[ELF] Refine isExported/isPreemptible condition · llvm/llvm-project@9bcc825 (original) (raw)
12 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -292,7 +292,6 @@ struct Config { | ||
292 | 292 | bool gdbIndex; |
293 | 293 | bool gnuHash = false; |
294 | 294 | bool gnuUnique; |
295 | -bool hasDynSymTab; | |
296 | 295 | bool ignoreDataAddressEquality; |
297 | 296 | bool ignoreFunctionAddressEquality; |
298 | 297 | bool ltoCSProfileGenerate; |
@@ -306,7 +305,6 @@ struct Config { | ||
306 | 305 | bool mipsN32Abi = false; |
307 | 306 | bool mmapOutputFile; |
308 | 307 | bool nmagic; |
309 | -bool noDynamicLinker = false; | |
310 | 308 | bool noinhibitExec; |
311 | 309 | bool nostdlib; |
312 | 310 | bool oFormatBinary; |
Original file line number | Diff line number | Diff line change | |
---|---|---|---|
@@ -781,11 +781,8 @@ static StringRef getDynamicLinker(Ctx &ctx, opt::InputArgList &args) { | |||
781 | 781 | auto *arg = args.getLastArg(OPT_dynamic_linker, OPT_no_dynamic_linker); | |
782 | 782 | if (!arg) | |
783 | 783 | return ""; | |
784 | -if (arg->getOption().getID() == OPT_no_dynamic_linker) { | ||
785 | -// --no-dynamic-linker suppresses undefined weak symbols in .dynsym | ||
786 | - ctx.arg.noDynamicLinker = true; | ||
784 | +if (arg->getOption().getID() == OPT_no_dynamic_linker) | ||
787 | 785 | return ""; | |
788 | - } | ||
789 | 786 | return arg->getValue(); | |
790 | 787 | } | |
791 | 788 | ||
@@ -2921,12 +2918,8 @@ template void LinkerDriver::link(opt::InputArgList &args) { | |||
2921 | 2918 | ||
2922 | 2919 | parseFiles(ctx, files); | |
2923 | 2920 | ||
2924 | -// Dynamic linking is used if there is an input DSO, | ||
2925 | -// or -shared or non-static pie is specified. | ||
2926 | - ctx.hasDynsym = !ctx.sharedFiles.empty() | | ctx.arg.shared | |
2927 | - (ctx.arg.pie && !ctx.arg.noDynamicLinker); | ||
2928 | 2921 | // Create dynamic sections for dynamic linking and static PIE. | |
2929 | - ctx.arg.hasDynSymTab = ctx.hasDynsym | | ctx.arg.isPic; | |
2922 | + ctx.hasDynsym = !ctx.sharedFiles.empty() | | ctx.arg.isPic; | |
2930 | 2923 | ||
2931 | 2924 | // If an entry symbol is in a static archive, pull out that file now. | |
2932 | 2925 | if (Symbol *sym = ctx.symtab->find(ctx.arg.entry)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -360,7 +360,9 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) { | ||
360 | 360 | // Symbol themselves might know their versions because symbols |
361 | 361 | // can contain versions in the form of @. |
362 | 362 | // Let them parse and update their names to exclude version suffix. |
363 | +// In addition, compute isExported and isPreemptible. | |
363 | 364 | bool hasDynsym = ctx.hasDynsym; |
365 | +bool maybePreemptible = ctx.sharedFiles.size() | | |
364 | 366 | for (Symbol *sym : ctx.symtab->getSymbols()) { |
365 | 367 | if (sym->hasVersionSuffix) |
366 | 368 | sym->parseSymbolVersion(ctx); |
@@ -371,7 +373,7 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) { | ||
371 | 373 | continue; |
372 | 374 | } |
373 | 375 | if (!sym->isDefined() && !sym->isCommon()) { |
374 | - sym->isPreemptible = computeIsPreemptible(ctx, *sym); | |
376 | + sym->isPreemptible = maybePreemptible && computeIsPreemptible(ctx, *sym); | |
375 | 377 | } else if (ctx.arg.exportDynamic && |
376 | 378 | (sym->isUsedInRegularObj | |
377 | 379 | sym->isExported = true; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -4740,7 +4740,7 @@ template void elf::createSyntheticSections(Ctx &ctx) { | ||
4740 | 4740 | |
4741 | 4741 | // Add MIPS-specific sections. |
4742 | 4742 | if (ctx.arg.emachine == EM_MIPS) { |
4743 | -if (!ctx.arg.shared && ctx.arg.hasDynSymTab) { | |
4743 | +if (!ctx.arg.shared && ctx.hasDynsym) { | |
4744 | 4744 | ctx.in.mipsRldMap = std::make_unique(ctx); |
4745 | 4745 | add(*ctx.in.mipsRldMap); |
4746 | 4746 | } |
@@ -4803,7 +4803,7 @@ template void elf::createSyntheticSections(Ctx &ctx) { | ||
4803 | 4803 | part.relaDyn = std::make_unique<RelocationSection>( |
4804 | 4804 | ctx, relaDynName, ctx.arg.zCombreloc, threadCount); |
4805 | 4805 | |
4806 | -if (ctx.arg.hasDynSymTab) { | |
4806 | +if (ctx.hasDynsym) { | |
4807 | 4807 | add(*part.dynSymTab); |
4808 | 4808 | |
4809 | 4809 | part.verSym = std::make_unique(ctx); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -284,6 +284,7 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) { | ||
284 | 284 | llvm::TimeTraceScope timeScope("Demote symbols"); |
285 | 285 | DenseMap<InputFile *, DenseMap<SectionBase *, size_t>> sectionIndexMap; |
286 | 286 | bool hasDynsym = ctx.hasDynsym; |
287 | +bool maybePreemptible = ctx.sharedFiles.size() | | |
287 | 288 | for (Symbol *sym : ctx.symtab->getSymbols()) { |
288 | 289 | if (auto *d = dyn_cast(sym)) { |
289 | 290 | if (d->section && !d->section->isLive()) |
@@ -300,7 +301,8 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) { | ||
300 | 301 | } |
301 | 302 | |
302 | 303 | if (hasDynsym) |
303 | - sym->isPreemptible = (sym->isUndefined() | | |
304 | + sym->isPreemptible = maybePreemptible && | |
305 | + (sym->isUndefined() | | |
304 | 306 | computeIsPreemptible(ctx, *sym); |
305 | 307 | } |
306 | 308 | } |
@@ -1929,10 +1931,9 @@ template void Writer::finalizeSections() { | ||
1929 | 1931 | if (ctx.in.symTab) |
1930 | 1932 | ctx.in.symTab->addSymbol(sym); |
1931 | 1933 | |
1932 | -// computeBinding might localize a linker-synthesized hidden symbol | |
1933 | -// (e.g. __global_pointer$) that was considered exported. | |
1934 | -if (ctx.hasDynsym && (sym->isUndefined() | | |
1935 | - !sym->isLocal()) { | |
1934 | +// computeBinding might localize a symbol that was considered exported | |
1935 | +// but then synthesized as hidden (e.g. _DYNAMIC). | |
1936 | +if ((sym->isExported | | |
1936 | 1937 | ctx.partitions[sym->partition - 1].dynSymTab->addSymbol(sym); |
1937 | 1938 | if (auto *file = dyn_cast(sym->file)) |
1938 | 1939 | if (file->isNeeded && !sym->isUndefined()) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,13 @@ | ||
1 | 1 | # REQUIRES: x86 |
2 | 2 | |
3 | -## --unresolved-symbols=ignore-all behaves similar to -shared: | |
3 | +## In dynamic linking, --unresolved-symbols=ignore-all behaves similar to -shared: | |
4 | 4 | ## for PLT relocations to undefined symbols, produce dynamic relocations if we |
5 | 5 | ## emit .dynsym. |
6 | 6 | |
7 | +# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/shared.s -o %ta.o | |
8 | +# RUN: ld.lld -shared -soname=ta %ta.o -o %ta.so | |
7 | 9 | # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o |
8 | -# RUN: ld.lld %t.o -o %t --unresolved-symbols=ignore-all -pie | |
10 | +# RUN: ld.lld %t.o %ta.so -o %t --unresolved-symbols=ignore-all -pie | |
9 | 11 | # RUN: llvm-readobj -r %t | FileCheck %s |
10 | 12 | |
11 | 13 | # CHECK: Relocations [ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,15 @@ | ||
1 | 1 | # REQUIRES: ppc |
2 | 2 | # RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o |
3 | 3 | # RUN: ld.lld %t.o -o %t |
4 | -# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=PDE %s | |
4 | +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=STATIC %s | |
5 | 5 | # RUN: ld.lld -pie %t.o -o %t |
6 | -# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=PIC %s | |
6 | +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=STATIC %s | |
7 | 7 | # RUN: ld.lld -shared %t.o -o %t |
8 | 8 | # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=PIC %s |
9 | 9 | |
10 | 10 | ## It does not really matter how we fixup it, but we cannot overflow and |
11 | 11 | ## should not generate a call stub (this would waste space). |
12 | -# PDE: bl 0x100100b4 | |
12 | +# STATIC: bl {{.*}} <.text> | |
13 | 13 | |
14 | 14 | ## With -pie or -shared, create a call stub. ld.bfd produces bl .+0 |
15 | 15 | # PIC: bl 0x[[PLT:[0-9a-f]+]] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -2,25 +2,25 @@ | ||
2 | 2 | |
3 | 3 | # RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o |
4 | 4 | # RUN: ld.lld %t.o -o %t |
5 | -# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=PDE | |
5 | +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=STATIC | |
6 | 6 | # RUN: ld.lld -pie %t.o -o %t |
7 | -# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=PIC | |
7 | +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=STATIC | |
8 | 8 | # RUN: ld.lld -shared %t.o -o %t.so |
9 | 9 | # RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s --check-prefix=PIC |
10 | 10 | |
11 | 11 | # RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t.o |
12 | 12 | # RUN: ld.lld %t.o -o %t |
13 | -# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=PDE | |
13 | +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=STATIC | |
14 | 14 | |
15 | 15 | ## Branches to an undefined weak symbol need a thunk iff a dynamic relocation is |
16 | 16 | ## produced. undefweak2 is hidden and does not need a dynamic relocation, so we |
17 | 17 | ## suppress the thunk. undefweak1 needs a thunk iff -pie or -shared. |
18 | 18 | |
19 | -# PDE-LABEL: <_start>: | |
20 | -# PDE-NEXT: bl {{.*}} <_start> | |
21 | -# PDE-NEXT: nop | |
22 | -# PDE-NEXT: bl {{.*}} <_start+0x8> | |
23 | -# PDE-NEXT: nop | |
19 | +# STATIC-LABEL: <_start>: | |
20 | +# STATIC-NEXT: bl {{.*}} <_start> | |
21 | +# STATIC-NEXT: nop | |
22 | +# STATIC-NEXT: bl {{.*}} <_start+0x8> | |
23 | +# STATIC-NEXT: nop | |
24 | 24 | |
25 | 25 | # PIC-LABEL: <_start>: |
26 | 26 | # PIC-NEXT: bl {{.*}} <__plt_undefweak1> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -14,17 +14,20 @@ | ||
14 | 14 | # SEC32: {{0*}}000039c0 0 NOTYPE GLOBAL DEFAULT [[#SDATA]] __global_pointer$ |
15 | 15 | |
16 | 16 | # SEC64: [ [[#SDATA:]]] .sdata PROGBITS {{0*}}000032e0 |
17 | +# SEC64: '.dynsym' | |
18 | +# SEC64-NOT: __global_pointer$ | |
19 | +# SEC64: '.symtab' | |
17 | 20 | # SEC64: {{0*}}00003ae0 0 NOTYPE GLOBAL DEFAULT [[#SDATA]] __global_pointer$ |
18 | 21 | |
19 | 22 | # ERR: error: relocation R_RISCV_PCREL_HI20 cannot be used against symbol '__global_pointer$'; recompile with -fPIC |
20 | 23 | |
21 | 24 | # RUN: ld.lld -pie --no-dynamic-linker --export-dynamic %t.64.o -o %t.64e |
22 | -# RUN: llvm-readelf -s %t.64e | FileCheck %s --check-prefix=STATICPIE | |
25 | +# RUN: llvm-readelf -s %t.64e | FileCheck %s --check-prefix=STATICE | |
23 | 26 | |
24 | -# STATICPIE: '.dynsym' | |
25 | -# STATICPIE-NOT: __global_pointer$ | |
26 | -# STATICPIE: '.symtab' | |
27 | -# STATICPIE: __global_pointer$ | |
27 | +# STATICE: '.dynsym' | |
28 | +# STATICE: __global_pointer$ | |
29 | +# STATICE: '.symtab' | |
30 | +# STATICE: __global_pointer$ | |
28 | 31 | |
29 | 32 | ## -r mode does not define __global_pointer$. |
30 | 33 | # RUN: ld.lld -r %t.64.o -o %t.64.ro |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -7,7 +7,7 @@ | ||
7 | 7 | # RUN: llvm-readobj --dyn-syms %t.so | FileCheck %s |
8 | 8 | |
9 | 9 | # RUN: ld.lld -pie -o %t %t1.o --start-lib %t2.o |
10 | -# RUN: llvm-readobj --dyn-syms %t | FileCheck %s | |
10 | +# RUN: llvm-readelf --dyn-syms %t | FileCheck %s --check-prefix=STATICPIE | |
11 | 11 | |
12 | 12 | # CHECK: Name: foo |
13 | 13 | # CHECK-NEXT: Value: 0x0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,12 @@ | ||
1 | 1 | # REQUIRES: x86 |
2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o |
3 | 3 | # RUN: ld.lld -pie %t.o -o %t |
4 | -# RUN: llvm-readobj --dyn-syms %t | FileCheck %s | |
4 | +# RUN: llvm-readobj --dyn-syms %t | FileCheck --check-prefix=NO %s | |
5 | 5 | # RUN: ld.lld -pie --no-dynamic-linker %t.o -o %t |
6 | 6 | # RUN: llvm-readobj --dyn-syms %t | FileCheck --check-prefix=NO %s |
7 | 7 | |
8 | -## With --no-dynamic-linker, don't emit undefined weak symbols to .dynsym . | |
9 | -## This will suppress a relocation. | |
10 | -# CHECK: Name: foo | |
8 | +## With static PIE (whether or not --no-dynamic-linker is specified), don't | |
9 | +## emit undefined weak symbols to .dynsym . This suppresses relocations. | |
11 | 10 | # NO-NOT: Name: foo |
12 | 11 | |
13 | 12 | .weak foo |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,23 @@ | ||
1 | 1 | # REQUIRES: x86 |
2 | 2 | # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o |
3 | 3 | # RUN: ld.lld %t.o -o %t --export-dynamic |
4 | -# RUN: llvm-readelf -r --hex-dump=.data %t | FileCheck %s --check-prefix=NOPIC | |
4 | +# RUN: llvm-readelf -r --hex-dump=.data %t | FileCheck %s --check-prefix=STATIC | |
5 | 5 | # RUN: ld.lld %t.o -o %t.pie -pie |
6 | -# RUN: llvm-readobj -r %t.pie | FileCheck %s --check-prefix=PIC | |
6 | +# RUN: llvm-readelf -r --hex-dump=.data %t.pie | FileCheck %s --check-prefix=STATIC | |
7 | 7 | # RUN: ld.lld %t.o -o %t.so -shared |
8 | 8 | # RUN: llvm-readobj -r %t.so | FileCheck %s --check-prefix=PIC |
9 | 9 | |
10 | 10 | ## gABI leaves the behavior of weak undefined references implementation defined. |
11 | -## We choose to resolve them statically for -no-pie and produce dynamic relocations | |
12 | -## for -pie and -shared. | |
11 | +## We choose to resolve them statically for static linking and produce dynamic relocations | |
12 | +## for dynamic linking (-shared or at least one input DSO). | |
13 | 13 | ## |
14 | 14 | ## Note: Some ports of GNU ld support -z nodynamic-undefined-weak that we don't |
15 | 15 | ## implement. |
16 | 16 | |
17 | -# NOPIC: no relocations | |
18 | -# NOPIC: Hex dump of section '.data': | |
19 | -# NOPIC-NEXT: {{.*}} 00000000 00000000 | |
20 | -# NOPIC-EMPTY: | |
17 | +# STATIC: no relocations | |
18 | +# STATIC: Hex dump of section '.data': | |
19 | +# STATIC-NEXT: {{.*}} 00000000 00000000 . | |
20 | +# STATIC-EMPTY: | |
21 | 21 | |
22 | 22 | # PIC: .rela.dyn { |
23 | 23 | # PIC-NEXT: R_X86_64_64 foobar 0x0 |