public override int GetHashCode() { var result = (Columns != null ? Columns.GetHashCode() : 0); result = 29 * result + KeyType.GetHashCode(); result = 29 * result + (RelTable != null ? RelTable.GetHashCode() : 0); result = 29 * result + (RelColumns != null ? RelColumns.GetHashCode() : 0); result = 29 * result + Clustered.GetHashCode(); result = 29 * result + (Source != null ? Source.GetHashCode() : 0); return(result); }
/// <summary> /// Relocates all relocations found in the DT_DYNAMIC segment. /// </summary> /// <param name="program"></param> /// <returns></returns> public List <ElfSymbol> RelocateDynamicSymbols(Program program) { var symbols = new List <ElfSymbol>(); foreach (var dynSeg in EnumerateDynamicSegments()) { DumpDynamicSegment(dynSeg); Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_STRTAB, out var strtab); Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_SYMTAB, out var symtab); Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_RELA, out var rela); Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_RELASZ, out var relasz); Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_RELAENT, out var relaent); Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_REL, out var rel); Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_RELSZ, out var relsz); Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_RELENT, out var relent); Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_SYMENT, out var syment); if (symtab == null || (rela == null && rel == null)) { continue; } if (strtab == null) { throw new BadImageFormatException("ELF dynamic segment lacks a string table."); } if (syment == null) { throw new BadImageFormatException("ELF dynamic segment lacks the size of symbol table entries."); } RelocationTable relTable; if (rela != null) { if (relasz == null) { throw new BadImageFormatException("ELF dynamic segment lacks the size of the relocation table."); } if (relaent == null) { throw new BadImageFormatException("ELF dynamic segment lacks the size of relocation table entries."); } relTable = new RelaTable(this, rela.UValue, relasz.UValue); } else { Debug.Assert(rel != null); if (relsz == null) { throw new BadImageFormatException("ELF dynamic segment lacks the size of the relocation table."); } if (relent == null) { throw new BadImageFormatException("ELF dynamic segment lacks the size of relocation table entries."); } relTable = new RelTable(this, rel.UValue, relsz.UValue); } var offStrtab = Loader.AddressToFileOffset(strtab.UValue); var offSymtab = Loader.AddressToFileOffset(symtab.UValue); LoadSymbolsFromDynamicSegment(dynSeg, symtab, syment, offStrtab, offSymtab); // Generate a symbol for each relocation. ElfImageLoader.trace.Inform("Relocating entries in .dynamic:"); foreach (var(_, elfSym, _) in relTable.RelocateEntries(program, offStrtab, offSymtab, syment.UValue)) { symbols.Add(elfSym); var imgSym = Loader.CreateImageSymbol(elfSym, true); // Symbols need to refer to the loaded image, if their value is 0, // they are imported symbols. if (imgSym == null || imgSym.Address.ToLinear() == 0) { continue; } imageSymbols[imgSym.Address] = imgSym; } // Relocate the DT_JMPREL table. Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_JMPREL, out var jmprel); Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_PLTRELSZ, out var pltrelsz); Loader.DynamicEntries.TryGetValue(ElfDynamicEntry.DT_PLTREL, out var pltrel); if (jmprel != null && pltrelsz != null && pltrel != null) { if (pltrel.SValue == ElfDynamicEntry.DT_RELA) // entries are in RELA format. { relTable = new RelaTable(this, jmprel.UValue, pltrelsz.UValue); } else if (pltrel.SValue == ElfDynamicEntry.DT_REL) // entries are in REL format { relTable = new RelTable(this, jmprel.UValue, pltrelsz.UValue); } else { //$REVIEW: bad elf format! continue; } ElfImageLoader.trace.Inform("Relocating entries in DT_JMPREL:"); foreach (var(addrImport, elfSym, extraSym) in relTable.RelocateEntries(program, offStrtab, offSymtab, syment.UValue)) { symbols.Add(elfSym); var imgSym = Loader.CreateImageSymbol(elfSym, true); if (imgSym != null && imgSym.Address.ToLinear() != 0) { imageSymbols[imgSym.Address] = imgSym; } if (extraSym != null) { symbols.Add(extraSym); var extraImgSym = Loader.CreateImageSymbol(extraSym, true); imageSymbols[extraImgSym.Address] = extraImgSym; } if (elfSym.SectionIndex == ElfSection.SHN_UNDEF) { program.ImportReferences[addrImport] = new NamedImportReference( addrImport, null, // ELF imports don't specify which module to take the import from imgSym.Name, imgSym.Type); } } } } return(symbols); }
/// <summary> /// Relocates all relocations found in the DT_DYNAMIC segment. /// </summary> /// <param name="program"></param> /// <returns></returns> public List <ElfSymbol> RelocateDynamicSymbols(Program program) { var symbols = new List <ElfSymbol>(); foreach (var dynSeg in EnumerateDynamicSegments()) { DumpDynamicSegment(dynSeg); Loader.DynamicEntries.TryGetValue(ElfLoader.DT_STRTAB, out var strtab); Loader.DynamicEntries.TryGetValue(ElfLoader.DT_SYMTAB, out var symtab); Loader.DynamicEntries.TryGetValue(ElfLoader.DT_RELA, out var rela); Loader.DynamicEntries.TryGetValue(ElfLoader.DT_RELASZ, out var relasz); Loader.DynamicEntries.TryGetValue(ElfLoader.DT_RELAENT, out var relaent); Loader.DynamicEntries.TryGetValue(ElfLoader.DT_REL, out var rel); Loader.DynamicEntries.TryGetValue(ElfLoader.DT_RELSZ, out var relsz); Loader.DynamicEntries.TryGetValue(ElfLoader.DT_RELENT, out var relent); Loader.DynamicEntries.TryGetValue(ElfLoader.DT_SYMENT, out var syment); if (symtab == null || (rela == null && rel == null)) { continue; } if (strtab == null) { throw new BadImageFormatException("ELF dynamic segment lacks a string table."); } if (syment == null) { throw new BadImageFormatException("ELF dynamic segment lacks the size of symbol table entries."); } RelocationTable relTable; if (rela != null) { if (relasz == null) { throw new BadImageFormatException("ELF dynamic segment lacks the size of the relocation table."); } if (relaent == null) { throw new BadImageFormatException("ELF dynamic segment lacks the size of relocation table entries."); } relTable = new RelaTable(this, rela.UValue, relasz.UValue); } else { Debug.Assert(rel != null); if (relsz == null) { throw new BadImageFormatException("ELF dynamic segment lacks the size of the relocation table."); } if (relent == null) { throw new BadImageFormatException("ELF dynamic segment lacks the size of relocation table entries."); } relTable = new RelTable(this, rel.UValue, relsz.UValue); } var offStrtab = Loader.AddressToFileOffset(strtab.UValue); var offSymtab = Loader.AddressToFileOffset(symtab.UValue); LoadSymbolsFromDynamicSegment(dynSeg, symtab, syment, offStrtab, offSymtab); // Generate a symbol for each relocation. foreach (var elfSym in relTable.RelocateEntries(program, offStrtab, offSymtab, syment.UValue)) { symbols.Add(elfSym); var imgSym = Loader.CreateImageSymbol(elfSym, true); if (imgSym == null || imgSym.Address.ToLinear() == 0) { continue; } imageSymbols[imgSym.Address] = imgSym; } // Relocate the DT_JMPREL table. Loader.DynamicEntries.TryGetValue(ElfLoader.DT_JMPREL, out var jmprel); Loader.DynamicEntries.TryGetValue(ElfLoader.DT_PLTRELSZ, out var pltrelsz); Loader.DynamicEntries.TryGetValue(ElfLoader.DT_PLTREL, out var pltrel); if (jmprel != null && pltrelsz != null && pltrel != null) { if (pltrel.SValue == 7) // entries are in RELA format. { relTable = new RelaTable(this, jmprel.UValue, pltrelsz.UValue); } else if (pltrel.SValue == 0x11) // entries are in REL format { relTable = new RelTable(this, jmprel.UValue, pltrelsz.UValue); } else { //$REVIEW: bad elf format! continue; } foreach (var elfSym in relTable.RelocateEntries(program, offStrtab, offSymtab, syment.UValue)) { symbols.Add(elfSym); var imgSym = Loader.CreateImageSymbol(elfSym, true); if (imgSym == null || imgSym.Address.ToLinear() == 0) { continue; } imageSymbols[imgSym.Address] = imgSym; program.ImportReferences[imgSym.Address] = new NamedImportReference( imgSym.Address, null, // ELF imports don't specify which modile to take the import from imgSym.Name); } } } return(symbols); }