public void Setup()
		{
            mr = new MockRepository();
            form = new MainForm();
            sc = new ServiceContainer();
            loader = mr.StrictMock<ILoader>();
            dec = mr.StrictMock<IDecompiler>();
            sc = new ServiceContainer();
            uiSvc = new FakeShellUiService();
            host = mr.StrictMock<DecompilerHost>();
            memSvc = mr.StrictMock<ILowLevelViewService>();
            var image = new LoadedImage(Address.Ptr32(0x10000), new byte[1000]);
            var imageMap = image.CreateImageMap();
            var arch = mr.StrictMock<IProcessorArchitecture>();
            arch.Stub(a => a.CreateRegisterBitset()).Return(new BitSet(32));
            arch.Replay();
            var platform = mr.StrictMock<Platform>(null, arch);
            arch.BackToRecord();
            program = new Program(image, imageMap, arch, platform);
            project = new Project { Programs = { program } };

            browserSvc = mr.StrictMock<IProjectBrowserService>();

            sc.AddService<IDecompilerUIService>(uiSvc);
            sc.AddService(typeof(IDecompilerShellUiService), uiSvc);
            sc.AddService(typeof(IDecompilerService), new DecompilerService());
            sc.AddService(typeof(IWorkerDialogService), new FakeWorkerDialogService());
            sc.AddService(typeof(DecompilerEventListener), new FakeDecompilerEventListener());
            sc.AddService(typeof(IProjectBrowserService), browserSvc);
            sc.AddService(typeof(ILowLevelViewService), memSvc);
            sc.AddService<ILoader>(loader);

            i = new TestInitialPageInteractor(sc, dec);

		}
		public void Setup()
		{
            var image = new LoadedImage(Address.Ptr32(0x00100000), new byte[1024]);
            var arch = new FakeArchitecture();
            var program = new Program
            {
                Image = image,
                Architecture = arch,
                ImageMap = image.CreateImageMap(),
                Platform = new DefaultPlatform(null, arch),
            };
            store = program.TypeStore;
            factory = program.TypeFactory;
            globals = program.Globals;
			store.EnsureExpressionTypeVariable(factory, globals);

			StructureType s = new StructureType(null, 0);
			s.Fields.Add(0x00100000, PrimitiveType.Word32, null);

			TypeVariable tvGlobals = store.EnsureExpressionTypeVariable(factory, globals);
			EquivalenceClass eqGlobals = new EquivalenceClass(tvGlobals);
			eqGlobals.DataType = s;
			globals.TypeVariable.DataType = new Pointer(eqGlobals, 4);
			globals.DataType = globals.TypeVariable.DataType;

            tcr = new TypedConstantRewriter(program);
		}
示例#3
0
        public void HSC_x86_FindCallsToProcedure()
        {
#if OLD
            var image = new LoadedImage(Address.Ptr32(0x001000), new byte[] {
                0xE8, 0x0B, 0x00, 0x00,  0x00, 0xE8, 0x07, 0x00,
                0x00, 0x00, 0xC3, 0x00,  0x00, 0x00, 0x00, 0x00,
                0xC3, 0xC3                                      // 1010, 1011
            });
            prog = new Program
            {
                Image = image,
                ImageMap = image.CreateImageMap(),
                Architecture = new IntelArchitecture(ProcessorMode.Protected32),
            };
#else
            Given_Image32(0x001000, 
                "E8 0B 00 00 00 E8 07 00 " +
                "00 00 C3 00 00 00 00 00 " +
                "C3 C3 ");                                     // 1010, 1011
            Given_x86_32();
#endif
            Given_RewriterHost();
            mr.ReplayAll();

            Assert.AreEqual(18, prog.Image.Length);

            var hsc = new HeuristicScanner(prog, host);
            var linAddrs = hsc.FindCallOpcodes(new Address[]{
                Address.Ptr32(0x1010),
                Address.Ptr32(0x1011)}).ToList();

            Assert.AreEqual(2, linAddrs.Count);
            Assert.IsTrue(linAddrs.Contains(Address.Ptr32(0x1000)));
            Assert.IsTrue(linAddrs.Contains(Address.Ptr32(0x1005)));
        }
示例#4
0
        public override Program Load(Address addrLoad)
        {
            BinHexDecoder dec = new BinHexDecoder(new StringReader(Encoding.ASCII.GetString(RawImage)));
            IEnumerator<byte> stm = dec.GetBytes().GetEnumerator();
            BinHexHeader hdr = LoadBinHexHeader(stm);
            byte[] dataFork = LoadFork(hdr.DataForkLength, stm);
            byte[] rsrcFork = LoadFork(hdr.ResourceForkLength, stm);

            var arch = new M68kArchitecture();
            var platform = new MacOSClassic(Services, arch);
            if (hdr.FileType == "PACT")
            {
                Cpt.CompactProArchive archive = new Cpt.CompactProArchive();
                List<ArchiveDirectoryEntry> items = archive.Load(new MemoryStream(dataFork));
                IArchiveBrowserService abSvc = Services.GetService<IArchiveBrowserService>();
                if (abSvc != null)
                {
                    var selectedFile = abSvc.UserSelectFileFromArchive(items);
                    if (selectedFile != null)
                    {
                        var image = selectedFile.GetBytes();
                        this.rsrcFork = new ResourceFork(image, arch);
                        this.image = new LoadedImage(addrLoad, image);
                        this.imageMap = new ImageMap(addrLoad, image.Length);
                        return new Program(this.image, this.imageMap, arch, platform);
                    }
                }
            }

            var li = new LoadedImage(addrLoad, dataFork);
            return new Program(li, li.CreateImageMap(), arch, platform);
        }
示例#5
0
 public ProgramBuilder(LoadedImage loadedImage)
 {
     Program = new Program
     {
         Image = loadedImage,
         ImageMap = loadedImage.CreateImageMap(),
         Architecture = new FakeArchitecture()
     };
 }
 public void Setup()
 {
     mr = new MockRepository();
     sc = new ServiceContainer();
     var image = new LoadedImage(Address.SegPtr(0xC00, 0), Enumerable.Range(0x0, 0x100).Select(b => (byte)b).ToArray());
     var imageMap = image.CreateImageMap();
     var arch = new Mocks.FakeArchitecture();
     this.program = new Program(image, imageMap, arch, new DefaultPlatform(sc, arch));
 }
示例#7
0
 public Program GetImage()
 {
     var image = new LoadedImage(BaseAddress, emitter.GetBytes());
     return new Program(
         image,
         image.CreateImageMap(),
         arch,
         new DefaultPlatform(null, arch));
 }
示例#8
0
 private void btnLoad_Click(object sender, EventArgs e)
 {
     var image = new LoadedImage(Address.Ptr32(0x12312300),new byte[0x1000]);
     var imageMap = image.CreateImageMap();
     var arch = new Decompiler.Arch.X86.X86ArchitectureFlat32();
     var program = new Core.Program(image, imageMap, arch, new DefaultPlatform(null, arch));
     var project = new Project { Programs = { program } };
     pbs.Load(project);
 }
示例#9
0
 protected void Given_Image32(uint addr, string sBytes)
 {
     var bytes = HexStringToBytes(sBytes);
     var imag = new LoadedImage(Address.Ptr32(addr), bytes);
     prog = new Program
     {
         Image = imag,
         ImageMap = imag.CreateImageMap()
     };
 }
示例#10
0
 private void BuildTest32(Address addrBase, params byte[] bytes)
 {
     arch = new M68kArchitecture();
     var image = new LoadedImage(addrBase, bytes);
     program = new Program(
         image,
         image.CreateImageMap(),
         arch,
         new DefaultPlatform(null, arch));
     RunTest(addrBase);
 }
示例#11
0
 public override Program Load(Address addrLoad)
 {
     int iImageStart = (exe.e_cparHeader * 0x10);
     int cbImageSize = exe.e_cpImage * ExeImageLoader.CbPageSize - iImageStart;
     byte[] bytes = new byte[cbImageSize];
     int cbCopy = Math.Min(cbImageSize, RawImage.Length - iImageStart);
     Array.Copy(RawImage, iImageStart, bytes, 0, cbCopy);
     imgLoaded = new LoadedImage(addrLoad, bytes);
     imgLoadedMap = imgLoaded.CreateImageMap();
     return new Program(imgLoaded, imgLoadedMap, arch, platform);
 }
示例#12
0
 public override Program Load(Address addrLoad)
 {
     if (addrLoad == null)
         addrLoad = PreferredBaseAddress;
     var image = new LoadedImage(addrLoad, imageBytes);
     return new Program(
         image,
         image.CreateImageMap(),
         Architecture,
         Platform ?? new DefaultPlatform(Services, Architecture));
 }
示例#13
0
 public override Program Load(Address addrLoad)
 {
     ldr = CreateParser();
     uint ncmds = ldr.ParseHeader(addrLoad);
     ldr.ParseLoadCommands(ncmds);
     var image = new LoadedImage(addrLoad, RawImage);
     return new Program {
         Architecture = ldr.arch,
         Image = image,
         ImageMap = image.CreateImageMap(),
         Platform = new DefaultPlatform(Services, ldr.arch)
     };
 }
示例#14
0
        public override Program Load(Address addrLoad)
        {
            arch = new M68kArchitecture();
            var imgReader = new BeImageReader(RawImage, 0);
            var parse = new HunkFileParser(imgReader, false);
            this.hunkFile = parse.Parse();
            BuildSegments();
            this.firstCodeHunk = parse.FindFirstCodeHunk();
            var image = new LoadedImage(addrLoad, RelocateBytes(addrLoad));

            return new Program(
                image,
                image.CreateImageMap(),
                arch,
                new AmigaOSPlatform(Services, arch));
        }
		public void Setup()
		{
            var image = new LoadedImage(Address.Ptr32(0x00400000), new byte[1024]);
            var arch = new FakeArchitecture();
            program = new Program
            {
                Architecture = arch,
                Image = image,
                ImageMap = image.CreateImageMap(),
                Platform = new DefaultPlatform(null, arch)
            };
            store = program.TypeStore;
            factory = program.TypeFactory;
			point = new StructureType(null, 0);
			point.Fields.Add(0, PrimitiveType.Word32, null);
			point.Fields.Add(4, PrimitiveType.Word32, null);
		}
示例#16
0
        private void LoadFromFile(TextReader rdr)
        {
            var arch = GetArchitecture(ReadLine(rdr).Trim());
            for (; ; )
            {
                var line = ReadLine(rdr);
                if (line == null)
                    break;
                ProcessLine(line);
            }
            var img = new LoadedImage(addrStart, memStm.ToArray());
            results = new Program(
                img,
                img.CreateImageMap(),
                arch,
                new DefaultPlatform(Services, arch));

        }
		public void Setup()
		{
			arch = new IntelArchitecture(ProcessorMode.Real);
            var image = new LoadedImage(Address.Ptr32(0x10000), new byte[4]);
			var prog = new Program(
                image,
                image.CreateImageMap(),
                arch,
                null);
			var procAddress = Address.Ptr32(0x10000000);
            instr = new IntelInstruction(Opcode.nop, PrimitiveType.Word16, PrimitiveType.Word16)
            {
                Address = procAddress,
            };

            proc = Procedure.Create(procAddress, arch.CreateFrame());
			orw = new OperandRewriter16(arch, proc.Frame, new FakeRewriterHost(prog));
            state = (X86State)arch.CreateProcessorState();
        }
 private void GenerateSimulatedProgram()
 {
     var row = Enumerable.Range(0, 0x100).Select(b => (byte)b).ToArray();
     var image = new LoadedImage(
             Address.Ptr32(0x0010000),
             Enumerable.Repeat(
                 row,
                 40).SelectMany(r => r).ToArray());
     var imageMap = image.CreateImageMap();
     var addrCode = Address.Ptr32(0x0010008);
     var addrData = Address.Ptr32(0x001001A);
     imageMap.AddItemWithSize(addrCode, new ImageMapBlock { Address = addrCode, Size = 0x0E });
     imageMap.AddItemWithSize(addrData, new ImageMapItem { Address = addrData, DataType = PrimitiveType.Byte, Size = 0x0E });
     var arch = dlg.Services.RequireService<IConfigurationService>().GetArchitecture("x86-protected-32");
     this.program = new Program
     {
         Image = image,
         ImageMap = imageMap,
         Architecture = arch,
     };
 }
示例#19
0
 private TestScanner CreateScanner(uint startAddress, int imageSize)
 {
     var image = new LoadedImage(Address.Ptr32(startAddress), new byte[imageSize]);
     program = new Program(
         image,
         image.CreateImageMap(),
         arch,
         new FakePlatform(null, arch));
     return new TestScanner(
         program,
         callSigs,
         importResolver);
 }
示例#20
0
        private Program LoadImageBytes(Address addrPreferred, Address addrMax)
        {
            var bytes = new byte[addrMax - addrPreferred];
            var v_base = addrPreferred.ToLinear();
            this.image = new LoadedImage(addrPreferred, bytes);
            this.imageMap = image.CreateImageMap();

            if (fileClass == ELFCLASS64)
            {
                foreach (var ph in ProgramHeaders64)
                {
                    if (ph.p_vaddr > 0 && ph.p_filesz > 0)
                        Array.Copy(RawImage, (long)ph.p_offset, bytes, (long)(ph.p_vaddr - v_base), (long)ph.p_filesz);
                }
                foreach (var segment in SectionHeaders64)
                {
                    if (segment.sh_name == 0 || segment.sh_addr == 0)
                        continue;
                    AccessMode mode = AccessMode.Read;
                    if ((segment.sh_flags & SHF_WRITE) != 0)
                        mode |= AccessMode.Write;
                    if ((segment.sh_flags & SHF_EXECINSTR) != 0)
                        mode |= AccessMode.Execute;
                    var seg = imageMap.AddSegment(
                        platform.MakeAddressFromLinear(segment.sh_addr), 
                        GetSectionName(segment.sh_name),
                        mode);
                    seg.Designer = CreateRenderer64(segment);
                }
            }
            else
            {
                foreach (var ph in ProgramHeaders)
                {
                    if (ph.p_vaddr > 0 && ph.p_filesz > 0)
                        Array.Copy(RawImage, (long)ph.p_offset, bytes, (long)(ph.p_vaddr - v_base), (long)ph.p_filesz);
                }
                foreach (var segment in SectionHeaders)
                {
                    if (segment.sh_name == 0 || segment.sh_addr == 0)
                        continue;
                    AccessMode mode = AccessMode.Read;
                    if ((segment.sh_flags & SHF_WRITE) != 0)
                        mode |= AccessMode.Write;
                    if ((segment.sh_flags & SHF_EXECINSTR) != 0)
                        mode |= AccessMode.Execute;
                    var seg = imageMap.AddSegment(Address.Ptr32(segment.sh_addr), GetSectionName(segment.sh_name), mode);
                    seg.Designer = CreateRenderer(segment);
                }
                imageMap.DumpSections();
            }
            var program = new Program(
                this.image,
                this.imageMap,
                this.arch,
                this.platform);
            importReferences = program.ImportReferences;
            return program;
        }
 private void Given_Program(byte[] bytes)
 {
     var addr = Address.Ptr32(0x1000);
     var image = new LoadedImage(addr, bytes);
     this.imageMap = image.CreateImageMap();
     this.program = new Program(image, imageMap, arch, new DefaultPlatform(null, arch));
 }
 private void Given_Image(params byte[] bytes)
 {
     image = new LoadedImage(addrBase, bytes);
     imageMap = image.CreateImageMap();
     program = new Program(image, imageMap, arch, null);
     interactor.Program = program;
 }
示例#23
0
 /// <summary>
 /// Load a Basic PRG.
 /// </summary>
 /// <param name="imageBytes"></param>
 /// <returns></returns>
 private Program LoadPrg(byte[] imageBytes)
 {
     var stm = new MemoryStream();
     ushort preferredAddress = LoadedImage.ReadLeUInt16(imageBytes, 0);
     ushort alignedAddress = (ushort) (preferredAddress & ~0xF);
     int pad = preferredAddress - alignedAddress;
     while (pad-- > 0)
         stm.WriteByte(0);
     stm.Write(imageBytes, 2, imageBytes.Length - 2);
     var loadedBytes = stm.ToArray();
     var image = new LoadedImage(
         Address.Ptr16(alignedAddress),
         loadedBytes);
     var rdr = new C64BasicReader(image, 0x0801);
     var prog = rdr.ToSortedList(line => (ushort)line.Address.ToLinear(), line => line);
     var arch = new C64Basic(prog);
     image = new LoadedImage(
         Address.Ptr16(prog.Keys[0]),
         new byte[0xFFFF]);
     var program = new Program(
         image,
         image.CreateImageMap(),
         arch,
         new C64Platform(Services, null));
     program.EntryPoints.Add(new EntryPoint(image.BaseAddress, arch.CreateProcessorState()));
     return program;
 }
示例#24
0
 private Program LoadImage(Address addrPreferred, D64FileEntry selectedFile)
 {
     byte[] imageBytes = selectedFile.GetBytes();
     switch (selectedFile.FileType & FileType.FileTypeMask)
     {
     case FileType.PRG:
         return LoadPrg(imageBytes);
     case FileType.SEQ:
         var image = new LoadedImage(addrPreferred, imageBytes);
         var arch = new Mos6502ProcessorArchitecture();
         return new Program(
             image,
             image.CreateImageMap(),
             arch,
             new DefaultPlatform(Services, arch));
     default:
         throw new NotImplementedException();
     }
 }
示例#25
0
 public override Program Load(Address addrLoad)
 {
     List<ArchiveDirectoryEntry> entries = LoadDiskDirectory();
     IArchiveBrowserService abSvc = Services.GetService<IArchiveBrowserService>();
     if (abSvc != null)
     {
         var selectedFile = abSvc.UserSelectFileFromArchive(entries) as D64FileEntry;
         if (selectedFile != null)
         {
             this.program = LoadImage(addrLoad, selectedFile);
             return program;
         }
     }
     var arch = new Mos6502ProcessorArchitecture();
     var image = new LoadedImage(Address.Ptr16(0), RawImage);
     return new Program {
         Image = image,
         ImageMap = image.CreateImageMap(),
         Architecture = arch,
         Platform = new DefaultPlatform(Services, arch)
     };
 }
示例#26
0
        public override Program Load(Address addrLoad)
		{
			uint dst = PspSize;

			for (;;)
			{
				if (bitStm.GetBit() == 0)
				{
					abU[dst++] = bitStm.GetByte();
					continue;
				}

				// Read span length

				int CX = 0;
				int BX = bitStm.AccumulateBit(0);				// bx= [0-1]
				BX = bitStm.AccumulateBit(BX);					// bx= [0-3]
				if (BX < 0x02)
				{
					BX = bitStm.AccumulateBit(BX);			// bx=[0-3]
					if (BX != 0)
					{
						BX = bitStm.AccumulateBit(BX);			// bx=[2-7]
						if (BX >= 0x05)
						{
							BX = bitStm.AccumulateBit(BX);		// bx=[0xA - 0xF]
							if (BX > 0x0C)
							{
								BX &= 0x03;
								BX = bitStm.AccumulateBit(BX);
								if (BX >= 0x05)
							    {
									BX = bitStm.AccumulateBit(BX);
									if (BX > 0x0C)
									{
										BX = BX & 0x03;
										BX = bitStm.AccumulateBit(BX);
										if (BX >= 0x05)
										{
											BX = bitStm.AccumulateBit(BX);
										}
										CX = ab0211[BX + 0x0B];
										goto l00C5;
									}
								}
								CX = ab0211[BX];
								if (CX != 0x19)
									goto l00C5;


								byte AL = bitStm.GetByte();
								CX += AL;
								if (AL < 0xFE)
									goto l00C5;

								/*
													ES = ES + ((DI - 0x2000) >> 4);
													DI = (DI & 0F) + 0x2000;

													DS = DS + (SI >> 4);
													SI = SI & 0x0F;
													DS = DS + BX;

								*/					
								if (AL == 0xFF)			// done!
									goto l01C8;

								continue;

							}
						}
					}
					BX = ab0206[BX];
				}
				CX = BX;

				// Read offset in dictionary.

			l00C5:
				BX = 0;
				if (CX == +02)
				{
					dst = CopyDictionaryWord(abU, BX, CX, bitStm, dst);
					continue;
				}
				if (bitStm.GetBit() != 0)
				{
					dst = CopyDictionaryWord(abU, BX, CX, bitStm, dst);
					continue;
				}

				BX = bitStm.AccumulateBit(BX);	// bx: [0-1]
				BX = bitStm.AccumulateBit(BX);	// bx: [0-3]
				BX = bitStm.AccumulateBit(BX);	// bx: [0-7]
				if (BX < 02)
				{
					dst = CopyDictionaryWord2(abU, BX, CX, bitStm, dst);
					continue;
				}

				BX = bitStm.AccumulateBit(BX);
				if (BX < 08)
				{
					dst = CopyDictionaryWord2(abU, BX, CX, bitStm, dst);
					continue;
				}

				BX = bitStm.AccumulateBit(BX);
				if (BX < 0x17)
				{
					dst = CopyDictionaryWord2(abU, BX, CX, bitStm, dst);
					continue;
				}

				BX = bitStm.AccumulateBit(BX);
				BX = (BX & 0x00DF) << 8;
				dst = CopyDictionaryWord(abU, BX, CX, bitStm, dst);
				continue;


			}
		

/*
l01C8:
		  5B            POP	BX
2DE9:01C9 8BEB          MOV	BP,BX				// unpackedBase
2DE9:01CB 83C310        ADD	BX,+10				// BX => unpackedBase + 0x100
*/
			l01C8:
			imgU = new LoadedImage(addrLoad, abU);
            imageMap = imgU.CreateImageMap();
			return new Program(imgU, imageMap, arch, platform);
		}
示例#27
0
		public LoadedImage Unpack(byte [] abC, Address addrLoad)
		{
			// Extract the LZ stuff.

			ImageReader rdr = new LeImageReader(abC, (uint) lzHdrOffset);
			lzIp = rdr.ReadLeUInt16();
			lzCs = rdr.ReadLeUInt16();
			ushort lzSp = rdr.ReadLeUInt16();
			ushort lzSs = rdr.ReadLeUInt16();
			ushort lzcpCompressed = rdr.ReadLeUInt16();
			ushort lzcpDecompressed = rdr.ReadLeUInt16();

			// Find the start of the compressed stream.

			int ifile = lzHdrOffset - (lzcpCompressed << 4);

			// Allocate space for the decompressed goo.

			int cbUncompressed = ((int) lzcpDecompressed + lzcpDecompressed) << 4;
			byte [] abU = new byte[cbUncompressed];

			// Decompress this sorry mess.

			int len;
			int span;
			int p = 0;
			BitStream bits = new BitStream(abC, ifile);
			for (;;)
			{
				if (bits.GetBit() != 0)
				{
					// 1....
					abU[p++] = bits.GetByte();
					continue;
				}

				if (bits.GetBit() == 0) 
				{
					// 00.....
					len = bits.GetBit() << 1;
					len |= bits.GetBit();
					len += 2;
					span = bits.GetByte() | ~0xFF;
				} 
				else
				{
					// 01.....

					span = bits.GetByte();
					len = bits.GetByte();;
					span |= ((len & ~0x07)<<5) | ~0x1FFF;
					len = (len & 0x07) + 2;
					if (len == 2)
					{
						len = bits.GetByte();

						if (len == 0)
							break;    // end mark of compressed load module 

						if (len == 1)
							continue; // segment change 
						else
							++len;
					}
				}
				for( ;len > 0; --len, ++p)
				{
					abU[p] = abU[p+span];
				}
			}

			// Create a new image based on the uncompressed data.

			this.imgLoaded = new LoadedImage(addrLoad, abU);
            this.imageMap = imgLoaded.CreateImageMap();
			return imgLoaded;
		}
示例#28
0
 public override Program Load(Address addrLoad)
 {
     if (sections > 0)
     {
         sectionMap = LoadSections(addrLoad, rvaSectionTable, sections);
         imgLoaded = LoadSectionBytes(addrLoad, sectionMap);
         imageMap = imgLoaded.CreateImageMap();
     }
     imgLoaded.BaseAddress = addrLoad;
     var program = new Program(imgLoaded, imageMap, arch, platform);
     this.importReferences = program.ImportReferences;
     return program;
 }
示例#29
0
 internal void Given_ImageSeg(ushort seg, ushort offset, string sBytes)
 {
     var bytes = HexStringToBytes(sBytes);
     var imag = new LoadedImage(Address.SegPtr(seg, offset), bytes);
     prog = new Program
     {
         Image = imag,
         ImageMap = imag.CreateImageMap()
     };
 }
示例#30
0
 private void Given_Program(Address address)
 {
     var image = new LoadedImage(address, new byte[1]);
     var imageMap = image.CreateImageMap();
     this.program = new Program
     {
         Architecture = arch,
         Image = image,
         ImageMap = imageMap,
         Platform = new FakePlatform(null, arch)
     };
 }