public override void Relocate(Program program) { // Get all relocations from PT_DYNAMIC segments first; these are the relocations actually // carried out by the operating system. var symbols = RelocateDynamicSymbols(program); if (symbols.Count > 0) { return; } DumpRel32(loader); DumpRela32(loader); foreach (var relSection in loader.Sections) { if (relSection.Type == SectionHeaderType.SHT_REL) { loader.Symbols.TryGetValue(relSection.LinkedSection.FileOffset, out var sectionSymbols); var referringSection = relSection.RelocatedSection; var rdr = loader.CreateReader(relSection.FileOffset); for (uint i = 0; i < relSection.EntryCount(); ++i) { var rel = loader.LoadRelEntry(rdr); var sym = sectionSymbols?[rel.SymbolIndex]; RelocateEntry(program, sym, referringSection, rel); } } else if (relSection.Type == SectionHeaderType.SHT_RELA) { loader.Symbols.TryGetValue(relSection.LinkedSection.FileOffset, out var sectionSymbols); var referringSection = relSection.RelocatedSection; var rdr = loader.CreateReader(relSection.FileOffset); for (uint i = 0; i < relSection.EntryCount(); ++i) { var rela = loader.LoadRelaEntry(rdr); var sym = sectionSymbols?[rela.SymbolIndex]; RelocateEntry(program, sym, referringSection, rela); } } } }