summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Symbols.h6
-rw-r--r--lld/ELF/Writer.cpp6
-rw-r--r--lld/test/elf2/common.s15
-rw-r--r--lld/test/elf2/symbols.s2
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)
OpenPOWER on IntegriCloud