From aa4dc20f09795133f1054a665ff8f35c5fd6b531 Mon Sep 17 00:00:00 2001 From: George Rimar Date: Tue, 1 Mar 2016 16:23:13 +0000 Subject: [PATCH] [ELF] - Create _DYNAMIC symbol for dynamic output lld needs to provide _DYNAMIC symbol when creating a shared library both bfd and gold do that. This should fix the https://llvm.org/bugs/show_bug.cgi?id=26732 Differential revision: http://reviews.llvm.org/D17607 llvm-svn: 262348 --- lld/ELF/SymbolTable.cpp | 6 +++--- lld/ELF/SymbolTable.h | 2 +- lld/ELF/Symbols.cpp | 5 +++-- lld/ELF/Symbols.h | 4 ++-- lld/ELF/Writer.cpp | 10 +++++---- lld/test/ELF/basic-ppc.s | 11 +++++----- lld/test/ELF/comdat.s | 9 ++++++++ lld/test/ELF/discard-merge-locals.s | 9 ++++++++ lld/test/ELF/discard-merge-unnamed.s | 9 ++++++++ lld/test/ELF/discard-none.s | 2 +- lld/test/ELF/dynamic.s | 42 ++++++++++++++++++++++++++++++++++++ lld/test/ELF/gc-sections-local-sym.s | 11 +++++++++- lld/test/ELF/local-dynamic.s | 9 ++++++++ lld/test/ELF/section-symbol.s | 9 ++++++++ lld/test/ELF/shared.s | 9 ++++++++ lld/test/ELF/visibility.s | 9 ++++++++ 16 files changed, 137 insertions(+), 19 deletions(-) create mode 100644 lld/test/ELF/dynamic.s diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index c40377c..095ad86 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -186,9 +186,9 @@ SymbolBody *SymbolTable::addAbsolute(StringRef Name, Elf_Sym &ESym) { template SymbolBody *SymbolTable::addSynthetic(StringRef Name, - OutputSectionBase &Section, - uintX_t Value) { - auto *Sym = new (Alloc) DefinedSynthetic(Name, Value, Section); + OutputSectionBase &Sec, + uintX_t Val, uint8_t Visibility) { + auto *Sym = new (Alloc) DefinedSynthetic(Name, Val, Sec, Visibility); resolve(Sym); return Sym; } diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 1f602e7..a2a991a 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -58,7 +58,7 @@ public: SymbolBody *addUndefinedOpt(StringRef Name); SymbolBody *addAbsolute(StringRef Name, Elf_Sym &ESym); SymbolBody *addSynthetic(StringRef Name, OutputSectionBase &Section, - uintX_t Value); + uintX_t Value, uint8_t Visibility); SymbolBody *addIgnored(StringRef Name); void scanShlibUndefined(); diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 6e094a3..a1e936eb 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -192,8 +192,9 @@ UndefinedElf::UndefinedElf(StringRef N, const Elf_Sym &Sym) template DefinedSynthetic::DefinedSynthetic(StringRef N, uintX_t Value, - OutputSectionBase &Section) - : Defined(SymbolBody::DefinedSyntheticKind, N, false, STV_DEFAULT, + OutputSectionBase &Section, + uint8_t Visibility) + : Defined(SymbolBody::DefinedSyntheticKind, N, false, Visibility, /*IsTls*/ false, /*IsFunction*/ false), Value(Value), Section(Section) {} diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index ea2c2e1..ac67bf6 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -250,8 +250,8 @@ template class DefinedSynthetic : public Defined { public: typedef typename llvm::object::ELFFile::Elf_Sym Elf_Sym; typedef typename llvm::object::ELFFile::uintX_t uintX_t; - DefinedSynthetic(StringRef N, uintX_t Value, - OutputSectionBase &Section); + DefinedSynthetic(StringRef N, uintX_t Value, OutputSectionBase &Section, + uint8_t Visibility); static bool classof(const SymbolBody *S) { return S->kind() == SymbolBody::DefinedSyntheticKind; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index d7e13e8..1277994 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1004,6 +1004,8 @@ template bool Writer::createSections() { addStartEndSymbols(); for (OutputSectionBase *Sec : RegularSections) addStartStopSymbols(Sec); + if (isOutputDynamic()) + Symtab.addSynthetic("_DYNAMIC", *Out::Dynamic, 0, STV_HIDDEN); // Define __rel[a]_iplt_{start,end} symbols if needed. addRelIpltSymbols(); @@ -1146,8 +1148,8 @@ template void Writer::addStartEndSymbols() { auto Define = [&](StringRef Start, StringRef End, OutputSectionBase *OS) { if (OS) { - Symtab.addSynthetic(Start, *OS, 0); - Symtab.addSynthetic(End, *OS, OS->getSize()); + Symtab.addSynthetic(Start, *OS, 0, STV_DEFAULT); + Symtab.addSynthetic(End, *OS, OS->getSize(), STV_DEFAULT); } else { Symtab.addIgnored(Start); Symtab.addIgnored(End); @@ -1177,10 +1179,10 @@ void Writer::addStartStopSymbols(OutputSectionBase *Sec) { StringRef Stop = Saver.save("__stop_" + S); if (SymbolBody *B = Symtab.find(Start)) if (B->isUndefined()) - Symtab.addSynthetic(Start, *Sec, 0); + Symtab.addSynthetic(Start, *Sec, 0, STV_DEFAULT); if (SymbolBody *B = Symtab.find(Stop)) if (B->isUndefined()) - Symtab.addSynthetic(Stop, *Sec, Sec->getSize()); + Symtab.addSynthetic(Stop, *Sec, Sec->getSize(), STV_DEFAULT); } template static bool needsPtLoad(OutputSectionBase *Sec) { diff --git a/lld/test/ELF/basic-ppc.s b/lld/test/ELF/basic-ppc.s index 1dc5822..83ace9a 100644 --- a/lld/test/ELF/basic-ppc.s +++ b/lld/test/ELF/basic-ppc.s @@ -28,7 +28,7 @@ // CHECK-NEXT: Version: 1 // CHECK-NEXT: Entry: 0x0 // CHECK-NEXT: ProgramHeaderOffset: 0x34 -// CHECK-NEXT: SectionHeaderOffset: 0x2084 +// CHECK-NEXT: SectionHeaderOffset: 0x209C // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: HeaderSize: 52 @@ -157,13 +157,14 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 // CHECK-NEXT: Offset: 0x2030 -// CHECK-NEXT: Size: 16 +// CHECK-NEXT: Size: 32 // CHECK-NEXT: Link: 8 // CHECK-NEXT: Info: 1 // CHECK-NEXT: AddressAlignment: 4 // CHECK-NEXT: EntrySize: 16 // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................| +// CHECK-NEXT: 0010: 00000001 00002000 00000000 00020005 |...... .........| // CHECK-NEXT: ) // CHECK-NEXT: } // CHECK-NEXT: Section { @@ -173,7 +174,7 @@ // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x2040 +// CHECK-NEXT: Offset: 0x2050 // CHECK-NEXT: Size: 64 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -193,14 +194,14 @@ // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x2080 +// CHECK-NEXT: Offset: 0x2090 // CHECK-NEXT: Size: 1 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 // CHECK-NEXT: EntrySize: 0 // CHECK-NEXT: SectionData ( -// CHECK-NEXT: 0000: 00 |.| +// CHECK-NEXT: 0000: 005F4459 4E414D49 4300 |._DYNAMIC.| // CHECK-NEXT: ) // CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/lld/test/ELF/comdat.s b/lld/test/ELF/comdat.s index 4f8955e..d3c8c01 100644 --- a/lld/test/ELF/comdat.s +++ b/lld/test/ELF/comdat.s @@ -61,6 +61,15 @@ foo: // READ-NEXT: Section: .text // READ-NEXT: } // READ-NEXT: Symbol { +// READ-NEXT: Name: _DYNAMIC +// READ-NEXT: Value: 0x2000 +// READ-NEXT: Size: 0 +// READ-NEXT: Binding: Local +// READ-NEXT: Type: None +// READ-NEXT: Other: 2 +// READ-NEXT: Section: .dynamic +// READ-NEXT: } +// READ-NEXT: Symbol { // READ-NEXT: Name: abc // READ-NEXT: Value: 0x0 // READ-NEXT: Size: 0 diff --git a/lld/test/ELF/discard-merge-locals.s b/lld/test/ELF/discard-merge-locals.s index 51676da..bf3f9b9 100644 --- a/lld/test/ELF/discard-merge-locals.s +++ b/lld/test/ELF/discard-merge-locals.s @@ -21,4 +21,13 @@ // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: 0x2000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/lld/test/ELF/discard-merge-unnamed.s b/lld/test/ELF/discard-merge-unnamed.s index bd0058c..e61aec5 100644 --- a/lld/test/ELF/discard-merge-unnamed.s +++ b/lld/test/ELF/discard-merge-unnamed.s @@ -13,4 +13,13 @@ // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: 0x2000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/lld/test/ELF/discard-none.s b/lld/test/ELF/discard-none.s index c13b544..e3a7a20 100644 --- a/lld/test/ELF/discard-none.s +++ b/lld/test/ELF/discard-none.s @@ -21,7 +21,7 @@ // CHECK-NEXT: EntrySize: // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: 002E4C6D 796F7468 65727661 72002E4C |..Lmyothervar..L| -// CHECK-NEXT: 0010: 6D797661 7200 |myvar.| +// CHECK-NEXT: 0010: 6D797661 72005F44 594E414D 494300 |myvar._DYNAMIC.| // CHECK-NEXT: ) // CHECK-NEXT: } diff --git a/lld/test/ELF/dynamic.s b/lld/test/ELF/dynamic.s new file mode 100644 index 0000000..47c162a0 --- /dev/null +++ b/lld/test/ELF/dynamic.s @@ -0,0 +1,42 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t.o + +## Check that _DYNAMIC symbol is created when creating dynamic output, +## and has hidden visibility and address equal to .dynamic section. +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-readobj -sections -symbols %t.so | FileCheck %s +# CHECK: Section { +# CHECK: Index: 5 +# CHECK: Name: .dynamic +# CHECK-NEXT: Type: SHT_DYNAMIC +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x[[ADDR:.*]] +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK: Symbols [ +# CHECK: Symbol { +# CHECK: Name: _DYNAMIC +# CHECK-NEXT: Value: 0x[[ADDR]] +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 2 +# CHECK-NEXT: Section: .dynamic +# CHECK-NEXT: } + +# RUN: ld.lld %t.o -o %t.o +# RUN: llvm-readobj -sections -symbols %t.o | FileCheck -check-prefix=NODYN %s +# NODYN: Symbols [ +# NODYN-NOT: Name: _DYNAMIC +# NODYN: ] + +.globl _start +_start: diff --git a/lld/test/ELF/gc-sections-local-sym.s b/lld/test/ELF/gc-sections-local-sym.s index 5102e30..db9f4c37 100644 --- a/lld/test/ELF/gc-sections-local-sym.s +++ b/lld/test/ELF/gc-sections-local-sym.s @@ -21,7 +21,7 @@ zed: // CHECK-NEXT: AddressAlignment: // CHECK-NEXT: EntrySize: // CHECK-NEXT: SectionData ( -// CHECK-NEXT: 0000: 00666F6F 00 |.foo.| +// CHECK-NEXT: 0000: 00666F6F 005F4459 4E414D49 4300 |.foo._DYNAMIC.| // CHECK-NEXT: ) // CHECK: Symbols [ @@ -35,6 +35,15 @@ zed: // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: 0x1000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: foo // CHECK-NEXT: Value: // CHECK-NEXT: Size: diff --git a/lld/test/ELF/local-dynamic.s b/lld/test/ELF/local-dynamic.s index 162c58c..156f74e 100644 --- a/lld/test/ELF/local-dynamic.s +++ b/lld/test/ELF/local-dynamic.s @@ -42,6 +42,15 @@ // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: 0x1000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start // CHECK-NEXT: Value: 0x1000 // CHECK-NEXT: Size: 0 diff --git a/lld/test/ELF/section-symbol.s b/lld/test/ELF/section-symbol.s index 5f04606..072d9d4 100644 --- a/lld/test/ELF/section-symbol.s +++ b/lld/test/ELF/section-symbol.s @@ -23,6 +23,15 @@ // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .text // CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } // CHECK-NEXT: ] foo: diff --git a/lld/test/ELF/shared.s b/lld/test/ELF/shared.s index 1adda30..9cc235f 100644 --- a/lld/test/ELF/shared.s +++ b/lld/test/ELF/shared.s @@ -144,6 +144,15 @@ // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: 0x12000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start // CHECK-NEXT: Value: 0x11000 // CHECK-NEXT: Size: 0 diff --git a/lld/test/ELF/visibility.s b/lld/test/ELF/visibility.s index d76ed07..1aa01d0 100644 --- a/lld/test/ELF/visibility.s +++ b/lld/test/ELF/visibility.s @@ -42,6 +42,15 @@ // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: 0x2000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: default // CHECK-NEXT: Value: // CHECK-NEXT: Size: 0 -- 2.7.4