Index: lld/trunk/ELF/SymbolTable.h =================================================================== --- lld/trunk/ELF/SymbolTable.h +++ lld/trunk/ELF/SymbolTable.h @@ -58,7 +58,7 @@ 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(); Index: lld/trunk/ELF/SymbolTable.cpp =================================================================== --- lld/trunk/ELF/SymbolTable.cpp +++ lld/trunk/ELF/SymbolTable.cpp @@ -186,9 +186,9 @@ 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; } Index: lld/trunk/ELF/Symbols.h =================================================================== --- lld/trunk/ELF/Symbols.h +++ lld/trunk/ELF/Symbols.h @@ -250,8 +250,8 @@ 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; Index: lld/trunk/ELF/Symbols.cpp =================================================================== --- lld/trunk/ELF/Symbols.cpp +++ lld/trunk/ELF/Symbols.cpp @@ -192,8 +192,9 @@ 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) {} Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -1004,6 +1004,8 @@ 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 @@ 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 @@ 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) { Index: lld/trunk/test/ELF/basic-ppc.s =================================================================== --- lld/trunk/test/ELF/basic-ppc.s +++ lld/trunk/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: ] Index: lld/trunk/test/ELF/comdat.s =================================================================== --- lld/trunk/test/ELF/comdat.s +++ lld/trunk/test/ELF/comdat.s @@ -61,6 +61,15 @@ // 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 Index: lld/trunk/test/ELF/discard-merge-locals.s =================================================================== --- lld/trunk/test/ELF/discard-merge-locals.s +++ lld/trunk/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: ] Index: lld/trunk/test/ELF/discard-merge-unnamed.s =================================================================== --- lld/trunk/test/ELF/discard-merge-unnamed.s +++ lld/trunk/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: ] Index: lld/trunk/test/ELF/discard-none.s =================================================================== --- lld/trunk/test/ELF/discard-none.s +++ lld/trunk/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: } Index: lld/trunk/test/ELF/dynamic.s =================================================================== --- lld/trunk/test/ELF/dynamic.s +++ lld/trunk/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: Index: lld/trunk/test/ELF/gc-sections-local-sym.s =================================================================== --- lld/trunk/test/ELF/gc-sections-local-sym.s +++ lld/trunk/test/ELF/gc-sections-local-sym.s @@ -21,7 +21,7 @@ // 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 @@ // 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: Index: lld/trunk/test/ELF/local-dynamic.s =================================================================== --- lld/trunk/test/ELF/local-dynamic.s +++ lld/trunk/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 Index: lld/trunk/test/ELF/section-symbol.s =================================================================== --- lld/trunk/test/ELF/section-symbol.s +++ lld/trunk/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: Index: lld/trunk/test/ELF/shared.s =================================================================== --- lld/trunk/test/ELF/shared.s +++ lld/trunk/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 Index: lld/trunk/test/ELF/visibility.s =================================================================== --- lld/trunk/test/ELF/visibility.s +++ lld/trunk/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