private void LoadImportReferencesFromRelaPlt() { var rela_plt = loader.GetSectionInfoByName(".rela.plt"); var plt = loader.GetSectionInfoByName(".plt"); if (rela_plt == null || plt == null) { return; } var relaRdr = loader.CreateReader(rela_plt.FileOffset); for (ulong i = 0; i < rela_plt.EntryCount(); ++i) { // Read the .rela.plt entry var rela = Elf64_Rela.Read(relaRdr); ulong sym = rela.r_info >> 32; var fileOff = rela_plt.LinkedSection !.FileOffset; if (fileOff == 0) { continue; } var symStr = loader.Symbols[fileOff][(int)sym]; var addr = plt.Address !+(uint)(i + 1) * plt.EntrySize; var st = ElfLoader.GetSymbolType(symStr); if (st.HasValue) { importReferences ![addr] = new NamedImportReference(addr, null, symStr.Name, st.Value);
/// <summary> /// Generate GOT entries for the global (imported) symbols of the MIPS ELF binary /// </summary> /// <remarks> /// The Elf MIPS ABI specifies that the GOT entries for import symbols are located after /// the GOT entries for the local functions. In addition they are orderd in the same order /// as the corresponding symbols in the symbol table. /// </remarks> private void LocateGlobalGotEntries(Program program, SortedList <Address, ImageSymbol> symbols) { var dynamic = loader.DynamicEntries; var uAddrSymtab = (uint)dynamic[ElfDynamicEntry.DT_SYMTAB].UValue; var allSymbols = loader.DynamicSymbols; var cLocalSymbols = (int)dynamic[ElfDynamicEntry.Mips.DT_MIPS_GOTSYM].SValue; var cTotalSymbols = (int)dynamic[ElfDynamicEntry.Mips.DT_MIPS_SYMTABNO].SValue; var cGlobalSymbols = cTotalSymbols - cLocalSymbols; var numberoflocalPointers = (int)dynamic[ElfDynamicEntry.Mips.DT_MIPS_LOCAL_GOTNO].SValue; var uAddrBeginningOfGot = (uint)dynamic[ElfDynamicEntry.DT_PLTGOT].UValue; var uAddrBeginningOfGlobalPointers = uAddrBeginningOfGot + (uint)numberoflocalPointers * PointerByteSize; for (int i = 0; i < cGlobalSymbols; ++i) { var addrGot = Address.Ptr32(uAddrBeginningOfGlobalPointers + PointerByteSize * (uint)i); var iSymbol = cLocalSymbols + i; if (allSymbols.TryGetValue(iSymbol, out var symbol) && symbol.Type == ElfSymbolType.STT_FUNC) { // This GOT entry is a known symbol! ImageSymbol symGotEntry = loader.CreateGotSymbol(addrGot, symbol.Name); symbols[addrGot] = symGotEntry; Debug.Print("Found GOT entry at {0}, changing symbol at {1}", symGotEntry, addrGot); var st = ElfLoader.GetSymbolType(symbol); if (st.HasValue) { program.ImportReferences[addrGot] = new NamedImportReference(addrGot, null, symbol.Name, st.Value); } } } }
public override ElfSymbol RelocateEntry(Program program, ElfSymbol symbol, ElfSection referringSection, ElfRelocation rela) { var rt = (SuperHrt)(byte)rela.Info; if (rt == SuperHrt.R_SH_GLOB_DAT || rt == SuperHrt.R_SH_JMP_SLOT) { var addrPfn = Address.Ptr32((uint)rela.Offset); Debug.Print("Import reference {0} - {1}", addrPfn, symbol.Name); var st = ElfLoader.GetSymbolType(symbol); if (st.HasValue) { program.ImportReferences[addrPfn] = new NamedImportReference(addrPfn, null, symbol.Name, st.Value); } return(symbol); } return(symbol); }
public override ElfSymbol RelocateEntry(Program program, ElfSymbol sym, ElfSection referringSection, ElfRelocation rela) { if (loader.Sections.Count <= sym.SectionIndex) { return(sym); } var rt = (SparcRt)(rela.Info & 0xFF); if (sym.SectionIndex == 0) { if (rt == SparcRt.R_SPARC_GLOB_DAT || rt == SparcRt.R_SPARC_JMP_SLOT) { var addrPfn = Address.Ptr32((uint)rela.Offset); Debug.Print("Import reference {0} - {1}", addrPfn, sym.Name); var st = ElfLoader.GetSymbolType(sym); if (st.HasValue) { importReferences[addrPfn] = new NamedImportReference(addrPfn, null, sym.Name, st.Value); } return(sym); } } var symSection = loader.Sections[(int)sym.SectionIndex]; uint S = (uint)sym.Value + symSection.Address.ToUInt32(); int A = 0; int sh = 0; uint mask = ~0u; Address addr; if (referringSection != null) { addr = referringSection.Address + rela.Offset; } else { addr = Address.Ptr32((uint)rela.Offset); } uint P = (uint)addr.ToLinear(); uint PP = P; uint B = 0; Debug.Print(" off:{0:X8} type:{1,-16} add:{3,-20} {4,3} {2} {5}", rela.Offset, (SparcRt)(rela.Info & 0xFF), sym.Name, rela.Addend, (int)(rela.Info >> 8), "section?"); switch (rt) { case 0: return(sym); case SparcRt.R_SPARC_HI22: A = (int)rela.Addend; sh = 10; P = 0; break; case SparcRt.R_SPARC_LO10: A = (int)rela.Addend; mask = 0x3FF; P = 0; break; case SparcRt.R_SPARC_32: A = (int)rela.Addend; mask = 0xFFFFFFFF; P = 0; break; case SparcRt.R_SPARC_WDISP30: A = (int)rela.Addend; P = ~P + 1; sh = 2; break; case SparcRt.R_SPARC_RELATIVE: A = (int)rela.Addend; B = program.SegmentMap.BaseAddress.ToUInt32(); break; case SparcRt.R_SPARC_COPY: Debug.Print("Relocation type {0} not handled yet.", rt); return(sym); default: throw new NotImplementedException(string.Format( "SPARC ELF relocation type {0} not implemented yet.", rt)); } var arch = program.Architecture; var relR = program.CreateImageReader(arch, addr); var relW = program.CreateImageWriter(arch, addr); var w = relR.ReadBeUInt32(); w += ((uint)(B + S + A + P) >> sh) & mask; relW.WriteBeUInt32(w); return(sym); }
public override ElfSymbol RelocateEntry(Program program, ElfSymbol sym, ElfSection referringSection, ElfRelocation rela) { var rt = (x86_64Rt)(rela.Info & 0xFF); if (loader.Sections.Count <= sym.SectionIndex) { return(sym); } if (rt == x86_64Rt.R_X86_64_GLOB_DAT || rt == x86_64Rt.R_X86_64_JUMP_SLOT) { var addrPfn = Address.Ptr64(rela.Offset); var st = ElfLoader.GetSymbolType(sym); if (!st.HasValue) { return(sym); } importReferences.Add(addrPfn, new NamedImportReference(addrPfn, null, sym.Name, st.Value)); var gotSym = loader.CreateGotSymbol(addrPfn, sym.Name); imageSymbols.Add(addrPfn, gotSym); return(sym); } if (sym.SectionIndex == 0) { return(sym); } var symSection = loader.Sections[(int)sym.SectionIndex]; ulong S = (ulong)sym.Value + symSection.Address.ToLinear(); long A = 0; int sh = 0; uint mask = ~0u; Address addr; ulong P; if (referringSection?.Address != null) { addr = referringSection.Address + rela.Offset; P = addr.ToLinear(); } else { addr = Address.Ptr64(rela.Offset); P = 0; } var arch = program.Architecture; var relR = program.CreateImageReader(arch, addr); var relW = program.CreateImageWriter(arch, addr); ulong PP = P; switch (rt) { case x86_64Rt.R_X86_64_NONE: // just ignore (common) break; case x86_64Rt.R_X86_64_COPY: break; default: Debug.Print("x86_64 ELF relocation type {0} not implemented yet.", rt); break; //throw new NotImplementedException(string.Format( // "x86_64 ELF relocation type {0} not implemented yet.", // rt)); } if (relR != null) { var w = relR.ReadUInt64(); w += ((ulong)(S + (ulong)A + P) >> sh) & mask; relW.WriteUInt64(w); } return(sym); }
public override (Address?, ElfSymbol?) RelocateEntry(Program program, ElfSymbol sym, ElfSection?referringSection, ElfRelocation rela) { if (loader.Sections.Count <= sym.SectionIndex) { return(null, null); } var rt = (SparcRt)(rela.Info & 0xFF); var addr = referringSection != null ? referringSection.Address !+rela.Offset : loader.CreateAddress(rela.Offset); if (sym.SectionIndex == 0) { if (rt == SparcRt.R_SPARC_GLOB_DAT || rt == SparcRt.R_SPARC_JMP_SLOT) { var addrPfn = Address.Ptr32((uint)rela.Offset); ElfImageLoader.trace.Verbose("Import reference {0} - {1}", addrPfn, sym.Name); var st = ElfLoader.GetSymbolType(sym); if (st.HasValue) { importReferences[addrPfn] = new NamedImportReference(addrPfn, null, sym.Name, st.Value); } return(addrPfn, null); } } var symSection = loader.Sections[(int)sym.SectionIndex]; ulong S = 0; int A = 0; int sh = 0; uint mask = ~0u; if (referringSection != null) { addr = referringSection.Address !+rela.Offset; } else { addr = Address.Ptr64(rela.Offset); } ulong P = addr.ToLinear(); ulong PP = P; ulong B = 0; ElfImageLoader.trace.Verbose(" off:{0:X8} type:{1,-16} add:{3,-20} {4,3} {2} {5}", rela.Offset, (SparcRt)(rela.Info & 0xFF), sym.Name, rela.Addend.HasValue ? rela.Addend.Value : 0, (int)(rela.Info >> 8), "section?"); switch (rt) { case 0: return(null, null); case SparcRt.R_SPARC_HI22: A = (int)rela.Addend !.Value; sh = 10; P = 0; mask = 0x3FFFFF; return(Relocate32(program, sym, addr, S, A, sh, mask, P, B)); case SparcRt.R_SPARC_LM22: A = (int)rela.Addend !.Value; S = sym.Value; sh = 10; P = 0; mask = 0x3FFFFF; return(Relocate32(program, sym, addr, S, A, sh, mask, P, B)); case SparcRt.R_SPARC_LO10: A = (int)rela.Addend !.Value; S = sym.Value; mask = 0x3FF; P = 0; return(Relocate32(program, sym, addr, S, A, sh, mask, P, B)); case SparcRt.R_SPARC_32: A = (int)rela.Addend !.Value; S = sym.Value; mask = 0xFFFFFFFF; P = 0; return(Relocate32(program, sym, addr, S, A, sh, mask, P, B)); case SparcRt.R_SPARC_WDISP30: A = (int)rela.Addend !.Value; P = ~P + 1; sh = 2; return(Relocate32(program, sym, addr, S, A, sh, mask, P, B)); case SparcRt.R_SPARC_RELATIVE: A = (int)rela.Addend !.Value; B = program.SegmentMap.BaseAddress.ToLinear(); P = 0; return(Relocate64(program, sym, addr, S, A, sh, mask, P, B)); case SparcRt.R_SPARC_COPY: ElfImageLoader.trace.Warn("Relocation type {0} not handled yet.", rt); return(addr, null); default: ElfImageLoader.trace.Error( "SPARC ELF relocation type {0} not implemented yet.", rt); return(addr, null); } }
public override (Address?, ElfSymbol?) RelocateEntry(Program program, ElfSymbol sym, ElfSection?referringSection, ElfRelocation rela) { if (loader.Sections.Count <= sym.SectionIndex) { return(null, null); } var rt = (SparcRt)(rela.Info & 0xFF); if (sym.SectionIndex == 0) { if (rt == SparcRt.R_SPARC_GLOB_DAT || rt == SparcRt.R_SPARC_JMP_SLOT) { var addrPfn = Address.Ptr32((uint)rela.Offset); Debug.Print("Import reference {0} - {1}", addrPfn, sym.Name); var st = ElfLoader.GetSymbolType(sym); if (st.HasValue) { importReferences[addrPfn] = new NamedImportReference(addrPfn, null, sym.Name, st.Value); } return(addrPfn, null); } } var symSection = loader.Sections[(int)sym.SectionIndex]; uint S = (uint)sym.Value + symSection.Address !.ToUInt32(); int A = 0; int sh = 0; uint mask = ~0u; Address addr; if (referringSection != null) { addr = referringSection.Address !+rela.Offset; } else { addr = Address.Ptr32((uint)rela.Offset); } uint P = (uint)addr.ToLinear(); uint PP = P; uint B = 0; Debug.Print(" off:{0:X8} type:{1,-16} add:{3,-20} {4,3} {2} {5}", rela.Offset, (SparcRt)(rela.Info & 0xFF), sym.Name, rela.Addend, (int)(rela.Info >> 8), "section?"); switch (rt) { case 0: return(addr, null); case SparcRt.R_SPARC_HI22: A = (int)rela.Addend; sh = 10; P = 0; break; case SparcRt.R_SPARC_LO10: A = (int)rela.Addend; mask = 0x3FF; P = 0; break; case SparcRt.R_SPARC_32: A = (int)rela.Addend; mask = 0xFFFFFFFF; P = 0; break; case SparcRt.R_SPARC_WDISP30: A = (int)re