public override void Relocate(Program program) { DumpRel32(loader); DumpRela32(loader); foreach (var relSection in loader.Sections) { if (relSection.Type == SectionHeaderType.SHT_REL) { var sectionSymbols = loader.Symbols[relSection.LinkedSection]; var referringSection = relSection.RelocatedSection; var rdr = loader.CreateReader(relSection.FileOffset); for (uint i = 0; i < relSection.EntryCount(); ++i) { var rel = Elf32_Rel.Read(rdr); var sym = sectionSymbols[(int)(rel.r_info >> 8)]; RelocateEntry(program, sym, referringSection, rel); } } else if (relSection.Type == SectionHeaderType.SHT_RELA) { var sectionSymbols = loader.Symbols[relSection.LinkedSection]; var referringSection = relSection.RelocatedSection; var rdr = loader.CreateReader(relSection.FileOffset); for (uint i = 0; i < relSection.EntryCount(); ++i) { var rela = Elf32_Rela.Read(rdr); var sym = sectionSymbols[(int)(rela.r_info >> 8)]; RelocateEntry(program, sym, referringSection, rela); } } } }
private void ApplyRelocation(Elf32_Rel rel) { // http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf // this is probably mostly wrong long val = 0; long A = rel.Addend; // since all symbols were moved by the same amount, just add _loadoffset here long S = _symlist[rel.SymbolIdx].Value + _loadoffset; long B = _loadoffset; switch (rel.Type) { case 0: val = 0; break; case 1: val = S + A; break; case 2: throw new NotImplementedException(); case 3: throw new NotImplementedException(); case 4: throw new NotImplementedException(); case 5: val = 0; break; case 6: val = S; break; case 7: val = S; break; case 8: val = B + A; break; case 9: throw new NotImplementedException(); case 10: throw new NotImplementedException(); default: throw new InvalidOperationException(); } byte[] tmp = new byte[4]; Marshal.Copy((IntPtr)(rel.Address + _loadoffset), tmp, 0, 4); long currentVal = BitConverter.ToUInt32(tmp, 0); tmp = BitConverter.GetBytes((uint)(currentVal + val)); Marshal.Copy(tmp, 0, (IntPtr)(rel.Address + _loadoffset), 4); }
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)); } } }
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)); } } }
public override void RelocateEntry(Program program, ElfSymbol symbol, ElfSection referringSection, Elf32_Rel rel) { if (loader.Sections.Count <= symbol.SectionIndex) { return; } if (symbol.SectionIndex == 0) { return; } var symSection = loader.Sections[(int)symbol.SectionIndex]; var addr = referringSection.Address + rel.r_offset; var S = symbol.Value; uint P = (uint)addr.ToLinear(); uint PP = P; var relR = program.CreateImageReader(addr); var relW = program.CreateImageWriter(addr); int sh = 0; uint mask = 0; uint A = 0; switch ((MIPSrt)(rel.r_info & 0xFF)) { case MIPSrt.R_MIPS_NONE: return; case MIPSrt.R_MIPS_REL32: break; /* * R_MIPS_NONE 0 none local none * R_MIPS_16 1 V–half16 external S + sign–extend(A) * 1 V–half16 local S + sign–extend(A) * R_MIPS_32 2 T–word32 external S + A * 2 T–word32 local S + A * R_MIPS_REL32 3 T–word32 external A – EA + S * R_MIPS_REL32 3 T–word32 local A – EA + S * R_MIPS_26 4 T–targ26 local (((A << 2) | \ * (P & 0xf0000000) + S) >> 2 * 4 T–targ26 external (sign–extend(A < 2) + S) >> 2 * R_MIPS_HI16 5 T–hi16 external ((AHL + S) – \ * (short)(AHL + S)) >> 16 * 5 T–hi16 local ((AHL + S) – \ * (short)(AHL + S)) >> 16 * 5 V–hi16 _gp_disp (AHL + GP – P) – (short) \ * (AHL + GP – P)) >> 16 * R_MIPS_LO16 6 T–lo16 external AHL + S * 6 T–lo16 local AHL + S * 6 V–lo16 _gp_disp AHL + GP – P + 4 * R_MIPS_GPREL16 7 V–rel16 external sign–extend(A) + S + GP * 7 V–rel16 local sign–extend(A) + S + GP0 – GP * R_MIPS_LITERAL 8 V–lit16 local sign–extend(A) + L * R_MIPS_GOT16 9 V–rel16 external G * 9 V–rel16 local see below * R_MIPS_PC16 10 V–pc16 external sign–extend(A) + S – P * R_MIPS_CALL16 11 V–rel16 external G * R_MIPS_GPREL32 12 T–word32 local A + S + GP0 – GP * R_MIPS_GOTHI16 21 T-hi16 external (G - (short)G) >> 16 + A * R_MIPS_GOTLO16 22 T-lo16 external G & 0xffff * R_MIPS_CALLHI16 30 T-hi16 external (G - (short)G) >> 16 + A * R_MIPS_CALLLO16 31 T-lo16 external G & 0xffff */ } var w = relR.ReadUInt32(); w += ((uint)(S + A + P) >> sh) & mask; relW.WriteUInt32(w); }
public virtual void RelocateEntry(Program program, ElfSymbol symbol, ElfSection referringSection, Elf32_Rel rel) { }