Skip to content

Commit f10441a

Browse files
committed
[ELF] Refine includeInDynsym condition
`includeInDynsym` has a special case for isUndefWeak and --no-dynamic-linker, which can be removed if we simplify disallow dynamic symbols for static-pie. The partition feature reports errors only when a symbol `isExported`. We need to link in a DSO to trigger the mips error.
1 parent 6a9d0e5 commit f10441a

File tree

5 files changed

+20
-13
lines changed

5 files changed

+20
-13
lines changed

lld/ELF/Config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,8 @@ struct Ctx : CommonLinkerContext {
654654
std::unique_ptr<llvm::TarWriter> tar;
655655
// InputFile for linker created symbols with no source location.
656656
InputFile *internalFile = nullptr;
657+
// True if symbols can be exported (isExported) or preemptible.
658+
bool hasDynsym = false;
657659
// True if SHT_LLVM_SYMPART is used.
658660
std::atomic<bool> hasSympart{false};
659661
// True if there are TLS IE relocations. Set DF_STATIC_TLS if -shared.

lld/ELF/Driver.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2554,7 +2554,7 @@ void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
25542554
for (Symbol *sym : obj->getGlobalSymbols()) {
25552555
if (!sym->isDefined())
25562556
continue;
2557-
if (sym->includeInDynsym(ctx))
2557+
if (ctx.hasDynsym && sym->includeInDynsym(ctx))
25582558
sym->isExported = true;
25592559
if (sym->hasVersionSuffix)
25602560
sym->parseSymbolVersion(ctx);
@@ -2899,8 +2899,12 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
28992899

29002900
parseFiles(ctx, files);
29012901

2902+
// Dynamic linking is used if there is an input DSO,
2903+
// or -shared or non-static pie is specified.
2904+
ctx.hasDynsym = !ctx.sharedFiles.empty() || ctx.arg.shared ||
2905+
(ctx.arg.pie && !ctx.arg.noDynamicLinker);
29022906
// Create dynamic sections for dynamic linking and static PIE.
2903-
ctx.arg.hasDynSymTab = !ctx.sharedFiles.empty() || ctx.arg.isPic;
2907+
ctx.arg.hasDynSymTab = ctx.hasDynsym || ctx.arg.isPic;
29042908

29052909
// If an entry symbol is in a static archive, pull out that file now.
29062910
if (Symbol *sym = ctx.symtab->find(ctx.arg.entry))

lld/ELF/Symbols.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,7 @@ bool Symbol::includeInDynsym(Ctx &ctx) const {
272272
if (computeBinding(ctx) == STB_LOCAL)
273273
return false;
274274
if (!isDefined() && !isCommon())
275-
// This should unconditionally return true, unfortunately glibc -static-pie
276-
// expects undefined weak symbols not to exist in .dynsym, e.g.
277-
// __pthread_mutex_lock reference in _dl_add_to_namespace_list,
278-
// __pthread_initialize_minimal reference in csu/libc-start.c.
279-
return !(isUndefWeak() && ctx.arg.noDynamicLinker);
275+
return true;
280276

281277
return exportDynamic ||
282278
(ctx.arg.exportDynamic && (isUsedInRegularObj || !ltoCanOmit));
@@ -374,13 +370,14 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
374370
// Symbol themselves might know their versions because symbols
375371
// can contain versions in the form of <name>@<version>.
376372
// Let them parse and update their names to exclude version suffix.
377-
bool hasDynSymTab = ctx.arg.hasDynSymTab;
373+
bool hasDynsym = ctx.hasDynsym;
378374
for (Symbol *sym : ctx.symtab->getSymbols()) {
379375
if (sym->hasVersionSuffix)
380376
sym->parseSymbolVersion(ctx);
381-
sym->isExported = sym->includeInDynsym(ctx);
382-
if (hasDynSymTab)
377+
if (hasDynsym) {
378+
sym->isExported = sym->includeInDynsym(ctx);
383379
sym->isPreemptible = sym->isExported && computeIsPreemptible(ctx, *sym);
380+
}
384381
}
385382
}
386383

lld/ELF/Writer.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ static void demoteDefined(Defined &sym, DenseMap<SectionBase *, size_t> &map) {
282282
static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
283283
llvm::TimeTraceScope timeScope("Demote symbols");
284284
DenseMap<InputFile *, DenseMap<SectionBase *, size_t>> sectionIndexMap;
285+
bool hasDynsym = ctx.hasDynsym;
285286
for (Symbol *sym : ctx.symtab->getSymbols()) {
286287
if (auto *d = dyn_cast<Defined>(sym)) {
287288
if (d->section && !d->section->isLive())
@@ -297,9 +298,10 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
297298
}
298299
}
299300

300-
sym->isExported = sym->includeInDynsym(ctx);
301-
if (ctx.arg.hasDynSymTab)
301+
if (hasDynsym) {
302+
sym->isExported = sym->includeInDynsym(ctx);
302303
sym->isPreemptible = sym->isExported && computeIsPreemptible(ctx, *sym);
304+
}
303305
}
304306
}
305307

lld/test/ELF/partition-errors.s

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
// RUN: not ld.lld --export-dynamic %ts.so %t.o -Tdata=0 2>&1 | FileCheck %s
1313
// RUN: not ld.lld --export-dynamic %ts.so %t.o -Tbss=0 2>&1 | FileCheck %s
1414

15+
// RUN: llvm-mc %S/Inputs/shared.s -o %ts.o -filetype=obj --triple=mipsel-unknown-linux
16+
// RUN: ld.lld -shared -soname=ts %ts.o -o %ts.so
1517
// RUN: llvm-mc -triple=mipsel-unknown-linux -filetype=obj -o %t2.o %s
16-
// RUN: not ld.lld --export-dynamic %t2.o 2>&1 | FileCheck %s
18+
// RUN: not ld.lld --export-dynamic %t2.o %ts.so 2>&1 | FileCheck %s
1719

1820
// CHECK: error: {{.*}}.o: partitions cannot be used
1921

0 commit comments

Comments
 (0)