diff options
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 1 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.h | 9 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 33 | ||||
-rw-r--r-- | lld/test/elf2/basic.s | 14 | ||||
-rw-r--r-- | lld/test/elf2/basic32.s | 12 | ||||
-rw-r--r-- | lld/test/elf2/basic32be.s | 12 | ||||
-rw-r--r-- | lld/test/elf2/basic64be.s | 12 | ||||
-rw-r--r-- | lld/test/elf2/string-table.s | 8 | ||||
-rw-r--r-- | lld/test/elf2/symbols.s | 34 |
9 files changed, 96 insertions, 39 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 3c43a1d57b0..6884988d554 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -50,6 +50,7 @@ void SymbolTable::reportRemainingUndefines() { void SymbolTable::resolve(SymbolBody *New) { // Find an existing Symbol or create and insert a new one. StringRef Name = New->getName(); + Builder.add(Name); Symbol *&Sym = Symtab[Name]; if (!Sym) { Sym = new (Alloc) Symbol(New); diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 21396b2a663..4a90e3044c0 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -13,6 +13,7 @@ #include "InputFiles.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" +#include "llvm/MC/StringTableBuilder.h" namespace lld { namespace elf2 { @@ -41,6 +42,13 @@ public: // The writer needs to infer the machine type from the object files. std::vector<std::unique_ptr<ObjectFileBase>> ObjectFiles; + unsigned getNumSymbols() { return Symtab.size(); } + llvm::StringTableBuilder &getStringBuilder() { return Builder; }; + + const llvm::DenseMap<StringRef, Symbol *> &getSymbols() const { + return Symtab; + } + private: void addObject(ObjectFileBase *File); @@ -48,6 +56,7 @@ private: llvm::DenseMap<StringRef, Symbol *> Symtab; llvm::BumpPtrAllocator Alloc; + llvm::StringTableBuilder Builder; }; } // namespace elf2 diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 7075f4d3a48..e86c9a64d21 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -14,7 +14,6 @@ #include "Writer.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/MC/StringTableBuilder.h" #include "llvm/Support/FileOutputBuffer.h" using namespace llvm; @@ -82,11 +81,13 @@ private: template <bool Is64Bits> class StringTableSection final : public OutputSectionBase<Is64Bits> { - llvm::StringTableBuilder StrTabBuilder; + llvm::StringTableBuilder &StrTabBuilder; public: typedef typename OutputSectionBase<Is64Bits>::uintX_t uintX_t; - StringTableSection() : OutputSectionBase<Is64Bits>(".strtab", SHT_STRTAB, 0) { + StringTableSection(llvm::StringTableBuilder &StrTabBuilder) + : OutputSectionBase<Is64Bits>(".strtab", SHT_STRTAB, 0), + StrTabBuilder(StrTabBuilder) { this->Header.sh_addralign = 1; } @@ -103,20 +104,26 @@ public: template <class ELFT> class SymbolTableSection final : public OutputSectionBase<ELFT::Is64Bits> { public: - SymbolTableSection() - : OutputSectionBase<ELFT::Is64Bits>(".symtab", SHT_SYMTAB, 0) { + typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; + SymbolTableSection(SymbolTable &Table) + : OutputSectionBase<ELFT::Is64Bits>(".symtab", SHT_SYMTAB, 0), + Table(Table) { typedef OutputSectionBase<ELFT::Is64Bits> Base; typename Base::HeaderT &Header = this->Header; // For now the only local symbol is going to be the one at index 0 Header.sh_info = 1; - Header.sh_entsize = sizeof(typename ELFFile<ELFT>::Elf_Sym); + Header.sh_entsize = sizeof(Elf_Sym); Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; + this->Header.sh_size = (Table.getNumSymbols() + 1) * sizeof(Elf_Sym); } void setStringTableIndex(uint32_t Index) { this->Header.sh_link = Index; } void writeTo(uint8_t *Buf) override; + +private: + SymbolTable &Table; }; // The writer writes a SymbolTable result to a file. @@ -124,7 +131,8 @@ template <class ELFT> class Writer { public: typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t; typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; - Writer(SymbolTable *T) : Symtab(T) {} + Writer(SymbolTable *T) + : Symtab(T), SymbolTable(*T), StringTable(T->getStringBuilder()) {} void run(); private: @@ -201,7 +209,16 @@ void StringTableSection<Is64Bits>::writeTo(uint8_t *Buf) { memcpy(Buf, Data.data(), Data.size()); } -template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {} +template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { + Buf += sizeof(Elf_Sym); + llvm::StringTableBuilder &Builder = Table.getStringBuilder(); + for (auto &P : Table.getSymbols()) { + StringRef Name = P.first; + auto *S = reinterpret_cast<Elf_Sym *>(Buf); + S->st_name = Builder.getOffset(Name); + Buf += sizeof(Elf_Sym); + } +} template <bool Is64Bits> template <endianness E> diff --git a/lld/test/elf2/basic.s b/lld/test/elf2/basic.s index 9f931dc61e8..f696f8ec6a4 100644 --- a/lld/test/elf2/basic.s +++ b/lld/test/elf2/basic.s @@ -25,7 +25,7 @@ _start: # CHECK-NEXT: Version: 1 # CHECK-NEXT: Entry: 0x401000 # CHECK-NEXT: ProgramHeaderOffset: 0x40 -# CHECK-NEXT: SectionHeaderOffset: 0x1038 +# CHECK-NEXT: SectionHeaderOffset: 0x1070 # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 64 @@ -106,7 +106,7 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 # CHECK-NEXT: Offset: 0x1010 -# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Size: 48 # CHECK-NEXT: Link: 5 # CHECK-NEXT: Info: 1 # CHECK-NEXT: AddressAlignment: 8 @@ -114,13 +114,13 @@ _start: # CHECK-NEXT: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 5 -# CHECK-NEXT: Name: .strtab (12) +# CHECK-NEXT: Name: .strtab # CHECK-NEXT: Type: SHT_STRTAB (0x3) # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x1010 -# CHECK-NEXT: Size: 34 +# CHECK-NEXT: Offset: 0x1040 +# CHECK-NEXT: Size: 41 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 @@ -133,8 +133,8 @@ _start: # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x400000 # CHECK-NEXT: PhysicalAddress: 0x400000 -# CHECK-NEXT: FileSize: 4536 -# CHECK-NEXT: MemSize: 4536 +# CHECK-NEXT: FileSize: 4592 +# CHECK-NEXT: MemSize: 4592 # CHECK-NEXT: Flags [ (0x5) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: PF_X (0x1) diff --git a/lld/test/elf2/basic32.s b/lld/test/elf2/basic32.s index 9b0edb3b26f..151b83ba840 100644 --- a/lld/test/elf2/basic32.s +++ b/lld/test/elf2/basic32.s @@ -25,7 +25,7 @@ _start: # CHECK-NEXT: Version: 1 # CHECK-NEXT: Entry: 0x401000 # CHECK-NEXT: ProgramHeaderOffset: 0x34 -# CHECK-NEXT: SectionHeaderOffset: 0x1030 +# CHECK-NEXT: SectionHeaderOffset: 0x1058 # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 52 @@ -106,7 +106,7 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 # CHECK-NEXT: Offset: 0x100C -# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Size: 32 # CHECK-NEXT: Link: 5 # CHECK-NEXT: Info: 1 # CHECK-NEXT: AddressAlignment: 4 @@ -119,8 +119,8 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x100C -# CHECK-NEXT: Size: 34 +# CHECK-NEXT: Offset: 0x102C +# CHECK-NEXT: Size: 41 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 @@ -133,8 +133,8 @@ _start: # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x400000 # CHECK-NEXT: PhysicalAddress: 0x400000 -# CHECK-NEXT: FileSize: 4384 -# CHECK-NEXT: MemSize: 4384 +# CHECK-NEXT: FileSize: 4424 +# CHECK-NEXT: MemSize: 4424 # CHECK-NEXT: Flags [ (0x5) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: PF_X (0x1) diff --git a/lld/test/elf2/basic32be.s b/lld/test/elf2/basic32be.s index 63f8f1c6601..8fecb968458 100644 --- a/lld/test/elf2/basic32be.s +++ b/lld/test/elf2/basic32be.s @@ -25,7 +25,7 @@ _start: # CHECK-NEXT: Version: 1 # CHECK-NEXT: Entry: 0x401000 # CHECK-NEXT: ProgramHeaderOffset: 0x34 -# CHECK-NEXT: SectionHeaderOffset: 0x1030 +# CHECK-NEXT: SectionHeaderOffset: 0x1058 # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 52 @@ -106,7 +106,7 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 # CHECK-NEXT: Offset: 0x100C -# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Size: 32 # CHECK-NEXT: Link: 5 # CHECK-NEXT: Info: 1 # CHECK-NEXT: AddressAlignment: 4 @@ -119,8 +119,8 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x100C -# CHECK-NEXT: Size: 34 +# CHECK-NEXT: Offset: 0x102C +# CHECK-NEXT: Size: 41 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 @@ -133,8 +133,8 @@ _start: # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x400000 # CHECK-NEXT: PhysicalAddress: 0x400000 -# CHECK-NEXT: FileSize: 4384 -# CHECK-NEXT: MemSize: 4384 +# CHECK-NEXT: FileSize: 4424 +# CHECK-NEXT: MemSize: 4424 # CHECK-NEXT: Flags [ (0x5) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: PF_X (0x1) diff --git a/lld/test/elf2/basic64be.s b/lld/test/elf2/basic64be.s index 38f2c85f055..6a0a442fe17 100644 --- a/lld/test/elf2/basic64be.s +++ b/lld/test/elf2/basic64be.s @@ -30,7 +30,7 @@ _start: # CHECK-NEXT: Version: 1 # CHECK-NEXT: Entry: 0x401000 # CHECK-NEXT: ProgramHeaderOffset: 0x40 -# CHECK-NEXT: SectionHeaderOffset: 0x1050 +# CHECK-NEXT: SectionHeaderOffset: 0x1088 # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 64 @@ -127,7 +127,7 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 # CHECK-NEXT: Offset: 0x1024 -# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Size: 48 # CHECK-NEXT: Link: 6 # CHECK-NEXT: Info: 1 # CHECK-NEXT: AddressAlignment: 8 @@ -140,8 +140,8 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x1024 -# CHECK-NEXT: Size: 39 +# CHECK-NEXT: Offset: 0x1054 +# CHECK-NEXT: Size: 46 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 @@ -154,8 +154,8 @@ _start: # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x400000 # CHECK-NEXT: PhysicalAddress: 0x400000 -# CHECK-NEXT: FileSize: 4624 -# CHECK-NEXT: MemSize: 4624 +# CHECK-NEXT: FileSize: 4680 +# CHECK-NEXT: MemSize: 4680 # CHECK-NEXT: Flags [ (0x5) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: PF_X (0x1) diff --git a/lld/test/elf2/string-table.s b/lld/test/elf2/string-table.s index 03b1feab4d8..7045ee9a6bd 100644 --- a/lld/test/elf2/string-table.s +++ b/lld/test/elf2/string-table.s @@ -52,14 +52,14 @@ _start: // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 41 +// CHECK-NEXT: Size: 48 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 // CHECK-NEXT: EntrySize: 0 // CHECK-NEXT: SectionData ( -// CHECK-NEXT: 0000: 002E7465 7874002E 62737300 666F6F62 |..text..bss.foob| -// CHECK-NEXT: 0010: 6172002E 73747274 6162002E 73796D74 |ar..strtab..symt| -// CHECK-NEXT: 0020: 6162002E 64617461 00 |ab..data.| +// CHECK-NEXT: 0000: 002E7465 7874005F 73746172 74002E62 |..text._start..b| +// CHECK-NEXT: 0010: 73730066 6F6F6261 72002E73 74727461 |ss.foobar..strta| +// CHECK-NEXT: 0020: 62002E73 796D7461 62002E64 61746100 |b..symtab..data.| // CHECK-NEXT: ) // CHECK-NEXT: } diff --git a/lld/test/elf2/symbols.s b/lld/test/elf2/symbols.s index fcef67723ab..e701f6fbae3 100644 --- a/lld/test/elf2/symbols.s +++ b/lld/test/elf2/symbols.s @@ -3,8 +3,38 @@ // RUN: llvm-readobj -symbols %t2 | FileCheck %s // REQUIRES: x86 -.globl _start; +.globl _start _start: -// CHECK: Symbols [ +.weak foo +foo: + +// CHECK: Symbols [ +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: (0) +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local (0x0) +// CHECK-NEXT: Type: None (0x0) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined (0x0) +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _start +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local (0x0) +// CHECK-NEXT: Type: None (0x0) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined (0x0) +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: foo +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local (0x0) +// CHECK-NEXT: Type: None (0x0) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined (0x0) +// CHECK-NEXT: } // CHECK-NEXT: ] |