示例#1
0
 private void When_CreateLoader32(bool big_endian)
 {
     this.eil  = new ElfImageLoader(sc, "foo", this.bytes);
     this.el32 = new ElfLoader32(eil, eih, this.bytes, big_endian ? ElfLoader.ELFDATA2MSB : ElfLoader.ELFDATA2LSB);
     el32.ProgramHeaders.AddRange(programHeaders);
     el32.Sections.AddRange(sections);
 }
示例#2
0
        private void ReadMod0(byte[] dcmpTextData, SegmentMap map)
        {
            var f    = new LeImageReader(dcmpTextData);
            var mod0 = f.ReadStruct <Mod0>();

            if (!map.TryFindSegment(mod0.DynamicOffset, out var dynseg))
            {
                return;
            }

            var offset = mod0.DynamicOffset - dynseg.MemoryArea.BaseAddress.ToLinear();

            offset += mod0.MagicOffset;
            var rdr    = dynseg.MemoryArea.CreateLeReader((int)offset);
            var elfHdr = new Elf32_EHdr {
                e_machine = (ushort)ElfMachine.EM_ARM
            };
            var elfLoader = new ElfLoader32(Services, elfHdr, 0, EndianServices.Little, RawImage);

            var(deps, entries) = elfLoader.LoadDynamicSegment(rdr);

            var dynEntries = entries.ToDictionary(e => e.Tag, e => e.UValue);
            var syms       = LoadSymbols(map, dynEntries);

            LoadRelocations(map, dynEntries, syms);
        }
示例#3
0
 private void When_CreateLoader32()
 {
     this.eil  = new ElfImageLoader(sc, "foo", this.bytes);
     this.el32 = new ElfLoader32(eil, eih, this.bytes);
     el32.ProgramHeaders.AddRange(programHeaders);
     el32.Sections.AddRange(sections);
 }
示例#4
0
        protected void DumpRela32(ElfLoader32 loader)
        {
            foreach (var section in loader.Sections.Where(s => s.Type == SectionHeaderType.SHT_RELA))
            {
                ElfImageLoader.trace.Inform(
                    "RELA: offset {0:X} symbol section {1}, relocating in section {2}",
                    section.FileOffset,
                    section.LinkedSection.Name,
                    section.RelocatedSection.Name);

                var symbols = loader.Symbols[section.LinkedSection.FileOffset];
                var rdr     = loader.CreateReader(section.FileOffset);
                for (uint i = 0; i < section.EntryCount(); ++i)
                {
                    var rela = Elf32_Rela.Read(rdr);
                    ElfImageLoader.trace.Verbose(
                        "  off:{0:X8} type:{1,-16} add:{3,-20} {4,3} {2}",
                        rela.r_offset,
                        RelocationTypeToString(rela.r_info & 0xFF),
                        symbols[(int)(rela.r_info >> 8)].Name,
                        rela.r_addend,
                        (int)(rela.r_info >> 8));
                }
            }
        }
示例#5
0
 private void When_CreateLoader32(bool big_endian)
 {
     this.eil  = new ElfImageLoader(sc, "foo", this.bytes);
     this.el32 = new ElfLoader32(sc, eih, 0, big_endian ? EndianServices.Big: EndianServices.Little, this.bytes);
     this.el32.LoadArchitectureFromHeader();
     el32.Segments.AddRange(programHeaders);
     el32.Sections.AddRange(sections);
 }
示例#6
0
 public void El32_SegmentSequence()
 {
     var mems = ElfLoader32.AllocateMemoryAreas(new[]
     {
         ElfSeg(1000, 10)
     });
     Assert.AreEqual(1, mems.Count);
 }
示例#7
0
 public void El32_SegmentSequence_Disjoint()
 {
     var mems = ElfLoader32.AllocateMemoryAreas(new[]
     {
         ElfSeg(1000, 10),
         ElfSeg(1020, 10),
     });
     Assert.AreEqual(2, mems.Count);
 }
示例#8
0
 public void El32_SegmentSequence_Adjacent()
 {
     var mems = ElfLoader32.AllocateMemoryAreas(new[]
     {
         ElfSeg(1000, 10),
         ElfSeg(1010, 20),
     });
     Assert.AreEqual(1, mems.Count);
     Assert.AreEqual(30, mems.Values[0].Length);
 }
示例#9
0
        public void Setup()
        {
            this.program              = new Program();
            this.program.SegmentMap   = new SegmentMap(Address.Ptr32(0x1000));
            this.program.Architecture = new Reko.Arch.X86.X86ArchitectureFlat32("x86-flat-32");
            this.symbols              = new Dictionary <int, ElfSymbol>();
            var services     = new ServiceContainer();
            var elfImgLoader = new ElfImageLoader(services, "foo.elf", new byte[0]);

            this.loader = new ElfLoader32();
            loader.Sections.Add(new ElfSection {
                Name = ""
            });                                                  // section 0
        }
示例#10
0
        private void Given_Linker(bool big_endian)
        {
            BuildObjectFile32();

            var eil = new ElfImageLoader(sc, "foo.o", rawBytes);

            eil.LoadElfIdentification();
            var eh = Elf32_EHdr.Load(new BeImageReader(rawBytes, ElfImageLoader.HEADER_OFFSET));
            var el = new ElfLoader32(eil, eh, rawBytes, big_endian ? ElfLoader.ELFDATA2MSB : ElfLoader.ELFDATA2LSB);

            el.LoadSectionHeaders();
            el.LoadSymbolsFromSections();
            this.linker = new ElfObjectLinker32(el, arch.Object, rawBytes);
        }
示例#11
0
        private void Given_Linker()
        {
            BuildObjectFile32();
            mr.ReplayAll();

            var eil = new ElfImageLoader(sc, "foo.o", rawBytes);

            eil.LoadElfIdentification();
            var eh = Elf32_EHdr.Load(new BeImageReader(rawBytes, ElfImageLoader.HEADER_OFFSET));
            var el = new ElfLoader32(eil, eh, rawBytes);

            el.LoadSectionHeaders();
            el.LoadSymbols();
            this.linker = new ElfObjectLinker32(el, arch, rawBytes);
        }
示例#12
0
        public void Eol32_CommonSymbol()
        {
            Given_SegName(".text");
            Given_SegName(".data");
            Given_Section(".text", SectionHeaderType.SHT_PROGBITS, ElfLoader.SHF_ALLOC | ElfLoader.SHF_EXECINSTR, new byte[] { 0xc3 });
            Given_Section(".data", SectionHeaderType.SHT_PROGBITS, ElfLoader.SHF_ALLOC | ElfLoader.SHF_WRITE, new byte[] { 0x01, 0x02, 0x03, 0x04 });
            Given_Symbol(
                "shared_global", 8, 0x4000,
                ElfLoader32.ELF32_ST_INFO(0, ElfSymbolType.STT_OBJECT),
                0xFFF2);

            Given_Linker(false);

            linker.ComputeSegmentSizes();
            Assert.AreEqual(0x4000, linker.Segments[3].p_pmemsz);
        }
示例#13
0
        private void Given_Linker(bool big_endian)
        {
            BuildObjectFile32(big_endian);
            var eil = new ElfImageLoader(sc, ImageLocation.FromUri("file:foo.o"), rawBytes);

            eil.LoadElfIdentification();
            var rdr = big_endian
                ? new BeImageReader(rawBytes, ElfImageLoader.HEADER_OFFSET)
                : (EndianImageReader) new LeImageReader(rawBytes, ElfImageLoader.HEADER_OFFSET);
            var eh = Elf32_EHdr.Load(rdr);
            var el = new ElfLoader32(sc, eh, 0, big_endian ? EndianServices.Big: EndianServices.Little, rawBytes);

            el.Sections.AddRange(el.LoadSectionHeaders());
            el.LoadSymbolsFromSections();
            this.linker = new ElfObjectLinker32(el, arch.Object, rawBytes);
        }
示例#14
0
        public void Eol32_UnresolvedExternals_OwnSegment()
        {
            Given_SegName(".text");
            Given_SegName(".data");
            Given_Section(".text", SectionHeaderType.SHT_PROGBITS, ElfLoader.SHF_ALLOC | ElfLoader.SHF_EXECINSTR, new byte[] { 0xc3 });
            Given_Section(".data", SectionHeaderType.SHT_PROGBITS, ElfLoader.SHF_ALLOC | ElfLoader.SHF_WRITE, new byte[] { 0x01, 0x02, 0x03, 0x04 });
            Given_Symbol(
                "unresolved_global1", 0, 0,
                ElfLoader32.ELF32_ST_INFO(0, ElfSymbolType.STT_NOTYPE),
                0);
            Given_Symbol(
                "unresolved_global2", 0, 0,
                ElfLoader32.ELF32_ST_INFO(0, ElfSymbolType.STT_NOTYPE),
                0);

            Given_Linker(false);

            linker.ComputeSegmentSizes();
            Assert.AreEqual(0x0030, linker.Segments[0].p_pmemsz, "Each external symbol is simulated with 16 bytes and added to executable section");
        }
示例#15
0
 protected void DumpRel32(ElfLoader32 loader)
 {
     foreach (var section in loader.Sections.Where(s => s.Type == SectionHeaderType.SHT_REL))
     {
         Debug.Print("REL: offset {0:X} symbol section {1}, relocating in section {2}",
                     section.FileOffset,
                     section.LinkedSection.Name,
                     section.RelocatedSection.Name);
         var symbols = loader.Symbols[section.LinkedSection.FileOffset];
         var rdr     = loader.CreateReader(section.FileOffset);
         for (uint i = 0; i < section.EntryCount(); ++i)
         {
             var rel = Elf32_Rel.Read(rdr);
             Debug.Print("  off:{0:X8} type:{1,-16} {3,3} {2}",
                         rel.r_offset,
                         RelocationTypeToString(rel.r_info & 0xFF),
                         symbols[(int)(rel.r_info >> 8)].Name,
                         (int)(rel.r_info >> 8));
         }
     }
 }
示例#16
0
 protected void DumpRel32(ElfLoader32 loader)
 {
     foreach (var section in loader.Sections.Where(s => s.Type == SectionHeaderType.SHT_REL))
     {
         ElfImageLoader.trace.Inform("REL: offset {0:X} symbol section {1}, relocating in section {2}",
                                     section.FileOffset,
                                     section.LinkedSection.Name,
                                     section.RelocatedSection.Name);
         loader.Symbols.TryGetValue(section.LinkedSection.FileOffset, out var symbols);
         var rdr = loader.CreateReader(section.FileOffset);
         for (uint i = 0; i < section.EntryCount(); ++i)
         {
             var rel = Elf32_Rel.Read(rdr);
             ElfImageLoader.trace.Verbose(
                 "  off:{0:X8} type:{1,-16} {3,3} {2}",
                 rel.r_offset,
                 RelocationTypeToString(rel.r_info & 0xFF),
                 symbols != null ? symbols[(int)(rel.r_info >> 8)].Name : "<nosym>",
                 (int)(rel.r_info >> 8));
         }
     }
 }
示例#17
0
        protected void DumpRela32(ElfLoader32 loader)
        {
            foreach (var section in loader.Sections.Where(s => s.Type == SectionHeaderType.SHT_RELA))
            {
                Debug.Print("RELA: offset {0:X} symbol section {1}, relocating in section {2}",
                    section.FileOffset,
                    section.LinkedSection.Name,
                    section.RelocatedSection.Name);

                var symbols = loader.Symbols[section.LinkedSection];
                var rdr = loader.CreateReader(section.FileOffset);
                for (uint i = 0; i < section.EntryCount(); ++i)
                {
                    var rela = Elf32_Rela.Read(rdr);
                    Debug.Print("  off:{0:X8} type:{1,-16} add:{3,-20} {4,3} {2}",
                        rela.r_offset,
                        RelocationTypeToString(rela.r_info & 0xFF),
                        symbols[(int)(rela.r_info >> 8)].Name,
                        rela.r_addend,
                        (int)(rela.r_info >> 8));
                }
            }
        }
示例#18
0
        public Avr32Relocator(ElfLoader32 elfLoader, SortedList <Address, ImageSymbol> imageSymbols)
            : base(elfLoader, imageSymbols)

        {
            this.elfLoader = elfLoader;
        }
示例#19
0
 public ElfRelocator32(ElfLoader32 loader, SortedList <Address, ImageSymbol> imageSymbols) : base(imageSymbols)
 {
     this.loader       = loader;
     this.imageSymbols = imageSymbols;
 }
示例#20
0
 public M68kRelocator(ElfLoader32 loader) : base(loader)
 {
 }
示例#21
0
        public void RelocateOld(Program program)
        {
            uint nextFakeLibAddr = ~1u; // See R_386_PC32 below; -1 sometimes used for main

            for (int i = 1; i < loader.Sections.Count; ++i)
            {
                var ps = loader.Sections[i];
                if (ps.Type == SectionHeaderType.SHT_REL)
                {
                    // A section such as .rel.dyn or .rel.plt (without an addend field).
                    // Each entry has 2 words: r_offset and r_info. The r_offset is just the offset from the beginning
                    // of the section (section given by the section header's sh_info) to the word to be modified.
                    // r_info has the type in the bottom byte, and a symbol table index in the top 3 bytes.
                    // A symbol table offset of 0 (STN_UNDEF) means use value 0. The symbol table involved comes from
                    // the section header's sh_link field.
                    var   pReloc = loader.CreateReader(ps.FileOffset);
                    ulong size   = ps.Size;
                    // NOTE: the r_offset is different for .o files (ET_REL in the e_type header field) than for exe's
                    // and shared objects!
                    uint destNatOrigin  = 0;
                    uint destHostOrigin = 0;
                    if (loader.Header.e_type == ElfImageLoader.ET_REL)
                    {
                        var destSection = loader.Sections[i].RelocatedSection;
                        destNatOrigin  = destSection.Address.ToUInt32();
                        destHostOrigin = (uint)destSection.FileOffset;
                    }
                    var symSection  = loader.Sections[i].LinkedSection; // associated symbol table
                    var strSection  = symSection.LinkedSection;         // Section index for the string section assoc with this
                    var pStrSection = strSection.FileOffset;
                    var symOrigin   = symSection.FileOffset;
                    var relocR      = loader.CreateReader(0);
                    var relocW      = loader.CreateWriter(0);
                    for (uint u = 0; u < size; u += 2 * sizeof(uint))
                    {
                        uint r_offset = pReloc.ReadUInt32();
                        uint info     = pReloc.ReadUInt32();

                        byte relType     = (byte)info;
                        uint symTabIndex = info >> 8;
                        uint pRelWord; // Pointer to the word to be relocated
                        if (loader.Header.e_type == ElfImageLoader.ET_REL)
                        {
                            pRelWord = destHostOrigin + r_offset;
                        }
                        else
                        {
                            if (r_offset == 0)
                            {
                                continue;
                            }
                            var destSec = loader.GetSectionInfoByAddr(r_offset);
                            pRelWord      = ~0u; // destSec.uHostAddr - destSec.uNativeAddr + r_offset;
                            destNatOrigin = 0;
                        }
                        uint A, S = 0, P;
                        int  nsec;
                        var  sym = Elf32_Sym.Load(loader.CreateReader(symOrigin + symTabIndex * Elf32_Sym.Size));
                        switch (relType)
                        {
                        case 0: // R_386_NONE: just ignore (common)
                            break;

                        case 1: // R_386_32: S + A
                            // Read the symTabIndex'th symbol.
                            S = sym.st_value;
                            if (loader.Header.e_type == ElfImageLoader.ET_REL)
                            {
                                nsec = sym.st_shndx;
                                if (nsec >= 0 && nsec < loader.Sections.Count)
                                {
                                    S += loader.Sections[nsec].Address.ToUInt32();
                                }
                            }
                            A = relocR.ReadUInt32(pRelWord);
                            relocW.WriteUInt32(pRelWord, S + A);
                            break;

                        case 2: // R_386_PC32: S + A - P
                            if (ElfLoader32.ELF32_ST_TYPE(sym.st_info) == ElfLoader.STT_SECTION)
                            {
                                nsec = sym.st_shndx;
                                if (nsec >= 0 && nsec < loader.Sections.Count)
                                {
                                    S = loader.Sections[nsec].Address.ToUInt32();
                                }
                            }
                            else
                            {
                                S = sym.st_value;
                                if (S == 0)
                                {
                                    // This means that the symbol doesn't exist in this module, and is not accessed
                                    // through the PLT, i.e. it will be statically linked, e.g. strcmp. We have the
                                    // name of the symbol right here in the symbol table entry, but the only way
                                    // to communicate with the loader is through the target address of the call.
                                    // So we use some very improbable addresses (e.g. -1, -2, etc) and give them entries
                                    // in the symbol table
                                    uint   nameOffset = sym.st_name;
                                    string pName      = loader.ReadAsciiString(pStrSection + nameOffset);
                                    // this is too slow, I'm just going to assume it is 0
                                    //S = GetAddressByName(pName);
                                    //if (S == (e_type == E_REL ? 0x8000000 : 0)) {
                                    S = nextFakeLibAddr--; // Allocate a new fake address
                                    loader.AddSymbol(S, pName);
                                    //}
                                }
                                else if (loader.Header.e_type == ElfImageLoader.ET_REL)
                                {
                                    nsec = sym.st_shndx;
                                    if (nsec >= 0 && nsec < loader.Sections.Count)
                                    {
                                        S += loader.Sections[nsec].Address.ToUInt32();
                                    }
                                }
                            }
                            A = relocR.ReadUInt32(pRelWord);
                            P = destNatOrigin + r_offset;
                            relocW.WriteUInt32(pRelWord, S + A - P);
                            break;

                        case 6: // R_386_GLOB_DAT
                            // This relocation type is used to set a global offset table entry to the address of the
                            // specified symbol. The special relocation type allows one to determine the
                            // correspondence between symbols and global offset table entries.
                            S = sym.st_value;
                            relocW.WriteUInt32(pRelWord, S);
                            break;

                        case 7:
                        case 8:    // R_386_RELATIVE
                            break; // No need to do anything with these, if a shared object

                        default:
                            throw new NotSupportedException("Relocation type " + (int)relType + " not handled yet");
                        }
                    }
                }
            }
        }
示例#22
0
 public MipsRelocator(ElfLoader32 loader, SortedList <Address, ImageSymbol> imageSymbols) : base(loader, imageSymbols)
 {
     archMips16e = null !;
 }
示例#23
0
 public SparcRelocator(ElfLoader32 loader) : base(loader)
 {
     this.loader = loader;
 }
示例#24
0
 public ArmRelocator(ElfLoader32 loader, SortedList <Address, ImageSymbol> imageSymbols) : base(loader, imageSymbols)
 {
     this.currentTlsSlotOffset = 0x0000000;
 }
示例#25
0
 public XtensaRelocator(ElfLoader32 loader) : base(loader)
 {
 }
示例#26
0
 public MipsRelocator(ElfLoader32 elfLoader) : base(elfLoader)
 {
     this.elfLoader = elfLoader;
 }
示例#27
0
 public Sparc32Relocator(ElfLoader32 loader, SortedList <Address, ImageSymbol> imageSymbols) : base(loader, imageSymbols)
 {
     importReferences = null !;
 }
示例#28
0
 public SuperHRelocator(ElfLoader32 loader) : base(loader)
 {
 }
示例#29
0
 public ElfRelocator32(ElfLoader32 loader)
 {
     this.loader = loader;
 }
示例#30
0
 public MipsRelocator(ElfLoader32 elfLoader) : base(elfLoader)
 {
     this.elfLoader = elfLoader;
 }
示例#31
0
 public XtensaRelocator(ElfLoader32 elfLoader32)
 {
     this.elfLoader32 = elfLoader32;
 }
示例#32
0
 public ArmRelocator(ElfLoader32 loader) : base(loader)
 {
     this.loader = loader;
 }
示例#33
0
 public M68kRelocator(ElfLoader32 loader, SortedList <Address, ImageSymbol> imageSymbols) : base(loader, imageSymbols)
 {
 }
示例#34
0
 public Nios2Relocator(ElfLoader32 elfLoader32, SortedList <Address, ImageSymbol> imageSymbols)
     : base(elfLoader32, imageSymbols)
 {
 }
示例#35
0
 public XtensaRelocator(ElfLoader32 elfLoader32)
 {
     this.elfLoader32 = elfLoader32;
 }