--- /dev/null
+## Show that llvm-objcopy can replace the symbol table with a new one.
+
+# RUN: yaml2obj %s -o %t
+
+# RUN: llvm-objcopy -R .symtab --add-symbol newsym=1234 %t %t2
+# RUN: llvm-readelf -S -s %t2 | FileCheck %s --match-full-lines
+
+# CHECK: There are 5 section headers, starting at offset {{.+}}:
+# CHECK: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
+# CHECK-NEXT: [ 0] NULL 0000000000000000 {{.+}} 000000 00 0 0 0
+# CHECK-NEXT: [ 1] .text PROGBITS 0000000000001000 {{.+}} 000040 00 AX 0 0 16
+# CHECK-NEXT: [ 2] .strtab STRTAB 0000000000000000 {{.+}} 000001 00 0 0 1
+# CHECK-NEXT: [ 3] .shstrtab STRTAB 0000000000000000 {{.+}} 000028 00 0 0 1
+# CHECK-NEXT: [ 4] .symtab SYMTAB 0000000000000000 {{.+}} 000030 18 3 1 8
+
+# CHECK: Symbol table '.symtab' contains 2 entries:
+# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name
+# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+# CHECK-NEXT: 1: 00000000000004d2 0 NOTYPE GLOBAL DEFAULT ABS newsym
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1000
+ AddressAlign: 0x0000000000000010
+ Size: 64
+Symbols:
+ - Name: foo
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1000
+ Size: 8
+ - Name: bar
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1008
+ Size: 8
+ - Name: baz
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1010
+ Size: 8
+
Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink,
Config.GnuDebugLinkCRC32);
+ // If the symbol table was previously removed, we need to create a new one
+ // before adding new symbols.
+ if (!Obj.SymbolTable && !Config.ELF->SymbolsToAdd.empty()) {
+ Obj.addNewSymbolTable();
+ }
+
for (const NewSymbolInfo &SI : Config.ELF->SymbolsToAdd) {
SectionBase *Sec = Obj.findSection(SI.SectionName);
uint64_t Value = Sec ? Sec->Addr + SI.Value : SI.Value;
Obj.SymbolTable->initialize(Obj.sections());
initSymbolTable(Obj.SymbolTable);
} else if (EnsureSymtab) {
- // Reuse an existing SHT_STRTAB section if it exists.
- StringTableSection *StrTab = nullptr;
- for (auto &Sec : Obj.sections()) {
- if (Sec.Type == ELF::SHT_STRTAB && !(Sec.Flags & SHF_ALLOC)) {
- StrTab = static_cast<StringTableSection *>(&Sec);
-
- // Prefer a string table that is not the section header string table, if
- // such a table exists.
- if (Obj.SectionNames != &Sec)
- break;
- }
- }
- if (!StrTab)
- StrTab = &Obj.addSection<StringTableSection>();
-
- SymbolTableSection &SymTab = Obj.addSection<SymbolTableSection>();
- SymTab.Name = ".symtab";
- SymTab.Link = StrTab->Index;
- SymTab.initialize(Obj.sections());
- SymTab.addSymbol("", 0, 0, nullptr, 0, 0, 0, 0);
- Obj.SymbolTable = &SymTab;
+ Obj.addNewSymbolTable();
}
// Now that all sections and symbols have been added we can add
return Error::success();
}
+void Object::addNewSymbolTable() {
+ assert(!SymbolTable && "Object must not has a SymbolTable.");
+
+ // Reuse an existing SHT_STRTAB section if it exists.
+ StringTableSection *StrTab = nullptr;
+ for (SectionBase &Sec : sections()) {
+ if (Sec.Type == ELF::SHT_STRTAB && !(Sec.Flags & SHF_ALLOC)) {
+ StrTab = static_cast<StringTableSection *>(&Sec);
+
+ // Prefer a string table that is not the section header string table, if
+ // such a table exists.
+ if (SectionNames != &Sec)
+ break;
+ }
+ }
+ if (!StrTab)
+ StrTab = &addSection<StringTableSection>();
+
+ SymbolTableSection &SymTab = addSection<SymbolTableSection>();
+ SymTab.Name = ".symtab";
+ SymTab.Link = StrTab->Index;
+ SymTab.initialize(sections());
+ SymTab.addSymbol("", 0, 0, nullptr, 0, 0, 0, 0);
+
+ SymbolTable = &SymTab;
+}
+
void Object::sortSections() {
// Use stable_sort to maintain the original ordering as closely as possible.
llvm::stable_sort(Sections, [](const SecPtr &A, const SecPtr &B) {