diff options
| -rw-r--r-- | lld/ELF/Symbols.h | 6 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 6 | ||||
| -rw-r--r-- | lld/test/elf2/common.s | 15 | ||||
| -rw-r--r-- | lld/test/elf2/symbols.s | 2 |
4 files changed, 24 insertions, 5 deletions
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 1b09e0113cf..ba6be5cae4f 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -138,12 +138,18 @@ template <class ELFT> class DefinedCommon : public Defined<ELFT> { typedef typename Base::Elf_Sym Elf_Sym; public: + typedef typename std::conditional<ELFT::Is64Bits, uint64_t, uint32_t>::type + uintX_t; explicit DefinedCommon(StringRef N, const Elf_Sym &Sym) : Defined<ELFT>(Base::DefinedCommonKind, N, Sym) {} static bool classof(const SymbolBody *S) { return S->kind() == Base::DefinedCommonKind; } + + // The output offset of this common symbol in the output bss. Computed by the + // writer. + uintX_t OffsetInBSS; }; // Regular defined symbols read from object file symbol tables. diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 2412cb86dba..1cee79cf051 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -344,7 +344,10 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) { uintX_t VA = Out->getVA(); if (Section) VA += Section->getOutputSectionOff(); - VA += InputSym->st_value; + if (auto *C = dyn_cast<DefinedCommon<ELFT>>(Body)) + VA += C->OffsetInBSS; + else + VA += InputSym->st_value; ESym->st_value = VA; } @@ -445,6 +448,7 @@ template <class ELFT> void Writer<ELFT>::createSections() { const Elf_Sym &Sym = C->Sym; uintX_t Align = Sym.st_value; Off = RoundUpToAlignment(Off, Align); + C->OffsetInBSS = Off; Off += Sym.st_size; } BSSSec->setSize(Off); diff --git a/lld/test/elf2/common.s b/lld/test/elf2/common.s index cceb8e4cce8..6a45cd6b93e 100644 --- a/lld/test/elf2/common.s +++ b/lld/test/elf2/common.s @@ -1,11 +1,20 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/common.s -o %t2 // RUN: lld -flavor gnu2 %t %t2 -o %t3 -// RUN: llvm-readobj -t %t3 | FileCheck %s +// RUN: llvm-readobj -t -s %t3 | FileCheck %s // REQUIRES: x86 +// CHECK: Name: .bss +// CHECK-NEXT: Type: SHT_NOBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x1000 + + // CHECK: Name: sym2 -// CHECK-NEXT: Value: 0x1004 +// CHECK-NEXT: Value: 0x1008 // CHECK-NEXT: Size: 8 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object @@ -13,7 +22,7 @@ // CHECK-NEXT: Section: .bss // CHECK: Name: sym1 -// CHECK-NEXT: Value: 0x1004 +// CHECK-NEXT: Value: 0x1000 // CHECK-NEXT: Size: 8 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object diff --git a/lld/test/elf2/symbols.s b/lld/test/elf2/symbols.s index 65dd4b0da64..603739b8721 100644 --- a/lld/test/elf2/symbols.s +++ b/lld/test/elf2/symbols.s @@ -106,7 +106,7 @@ abs = 0x123 // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: common (34) -// CHECK-NEXT: Value: 0x1008 +// CHECK-NEXT: Value: 0x1004 // CHECK-NEXT: Size: 4 // CHECK-NEXT: Binding: Global (0x1) // CHECK-NEXT: Type: Object (0x1) |

