Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -89,6 +89,7 @@ bool ZNow; bool ZOrigin; bool ZRelro; + bool DynamicListData; ELFKind EKind = ELFNoneKind; uint16_t EMachine = llvm::ELF::EM_NONE; uint64_t EntryAddr = -1; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -318,6 +318,7 @@ StringRef DynamicListPath = getString(Args, OPT_dynamic_list); if (!DynamicListPath.empty()) readDynamicList(DynamicListPath); + Config->DynamicListData = Args.hasArg(OPT_dynamic_list_data); Config->Optimize = getInteger(Args, OPT_O, 0); Config->LtoO = getInteger(Args, OPT_lto_O, 2); Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -155,6 +155,9 @@ def dynamic_list : Separate<["--", "-"], "dynamic-list">, HelpText<"Dynamic list to use">; +def dynamic_list_data : Flag<["--", "-"], "dynamic-list-data">, + HelpText<"Add all global data to the dynamic symbol list">; + // Aliases def alias_Bdynamic_call_shared: Flag<["-"], "call_shared">, Alias; def alias_Bdynamic_dy: Flag<["-"], "dy">, Alias; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -845,6 +845,7 @@ return true; } +template static bool includeInDynsym(const SymbolBody &B) { uint8_t V = B.getVisibility(); if (V != STV_DEFAULT && V != STV_PROTECTED) @@ -853,6 +854,10 @@ return true; if (DynList->isInDynamicList(B.getName())) return true; + // Handle --dynamic-list-data. + if (Config->DynamicListData) + if (B.Type == STT_OBJECT) + return true; return B.MustBeInDynSym; } @@ -1126,7 +1131,7 @@ if (Out::SymTab) Out::SymTab->addSymbol(Body); - if (isOutputDynamic() && includeInDynsym(*Body)) + if (isOutputDynamic() && includeInDynsym(*Body)) Out::DynSymTab->addSymbol(Body); } Index: test/ELF/dynamic-list-data.s =================================================================== --- /dev/null +++ test/ELF/dynamic-list-data.s @@ -0,0 +1,54 @@ +# REQUIRES: x86 + +## This object is build in linked against to force dynamic loading without +## the use of full paths in linking command. +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o +# RUN: ld.lld -shared %t2.o -soname shared -o %t2.so + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld --dynamic-list-data %t %t2.so -o %t.exe +# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s + +# CHECK: DynamicSymbols [ +# 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: data1@ (1) +# CHECK-NEXT: Value: 0x13000 +# CHECK-NEXT: Size: 4 +# CHECK-NEXT: Binding: Global (0x1) +# CHECK-NEXT: Type: Object (0x1) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .bss (0x6) +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: data2@ (7) +# CHECK-NEXT: Value: 0x11000 +# CHECK-NEXT: Size: 4 +# CHECK-NEXT: Binding: Global (0x1) +# CHECK-NEXT: Type: Object (0x1) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text (0x4) +# CHECK-NEXT: } +# CHECK-NEXT: ] + +## int data1; +.comm data1,4,4 + +## int data2 = 5; +.globl data2 +.type data2, @object +.size data2, 4 +data2: +.long 5 + +.globl _start +_start: + retq