summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/SymbolTable.cpp1
-rw-r--r--lld/ELF/SymbolTable.h9
-rw-r--r--lld/ELF/Writer.cpp33
-rw-r--r--lld/test/elf2/basic.s14
-rw-r--r--lld/test/elf2/basic32.s12
-rw-r--r--lld/test/elf2/basic32be.s12
-rw-r--r--lld/test/elf2/basic64be.s12
-rw-r--r--lld/test/elf2/string-table.s8
-rw-r--r--lld/test/elf2/symbols.s34
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: ]
OpenPOWER on IntegriCloud