mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
[ELF] Refine ctx.arg.exportDynamic condition
--export-dynamic should be a no-op when ctx.hasDynsym is false. * Drop unneeded ctx.hasDynsym checks. * Static linking with --export-dynamic does not prevent devirtualization.
This commit is contained in:
@@ -2617,8 +2617,7 @@ void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
|
||||
for (Symbol *sym : obj->getGlobalSymbols()) {
|
||||
if (!sym->isDefined())
|
||||
continue;
|
||||
if (ctx.hasDynsym && ctx.arg.exportDynamic &&
|
||||
sym->computeBinding(ctx) != STB_LOCAL)
|
||||
if (ctx.arg.exportDynamic && sym->computeBinding(ctx) != STB_LOCAL)
|
||||
sym->isExported = true;
|
||||
if (sym->hasVersionSuffix)
|
||||
sym->parseSymbolVersion(ctx);
|
||||
@@ -2965,6 +2964,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
|
||||
|
||||
// Create dynamic sections for dynamic linking and static PIE.
|
||||
ctx.hasDynsym = !ctx.sharedFiles.empty() || ctx.arg.isPic;
|
||||
ctx.arg.exportDynamic &= ctx.hasDynsym;
|
||||
|
||||
// If an entry symbol is in a static archive, pull out that file now.
|
||||
if (Symbol *sym = ctx.symtab->find(ctx.arg.entry))
|
||||
|
||||
@@ -361,13 +361,10 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
|
||||
// can contain versions in the form of <name>@<version>.
|
||||
// Let them parse and update their names to exclude version suffix.
|
||||
// In addition, compute isExported and isPreemptible.
|
||||
bool hasDynsym = ctx.hasDynsym;
|
||||
bool maybePreemptible = ctx.sharedFiles.size() || ctx.arg.shared;
|
||||
for (Symbol *sym : ctx.symtab->getSymbols()) {
|
||||
if (sym->hasVersionSuffix)
|
||||
sym->parseSymbolVersion(ctx);
|
||||
if (!hasDynsym)
|
||||
continue;
|
||||
if (sym->computeBinding(ctx) == STB_LOCAL) {
|
||||
sym->isExported = false;
|
||||
continue;
|
||||
@@ -377,7 +374,7 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
|
||||
} else if (ctx.arg.exportDynamic &&
|
||||
(sym->isUsedInRegularObj || !sym->ltoCanOmit)) {
|
||||
sym->isExported = true;
|
||||
sym->isPreemptible = computeIsPreemptible(ctx, *sym);
|
||||
sym->isPreemptible = maybePreemptible && computeIsPreemptible(ctx, *sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,7 +284,6 @@ static void demoteDefined(Defined &sym, DenseMap<SectionBase *, size_t> &map) {
|
||||
static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
|
||||
llvm::TimeTraceScope timeScope("Demote symbols");
|
||||
DenseMap<InputFile *, DenseMap<SectionBase *, size_t>> sectionIndexMap;
|
||||
bool hasDynsym = ctx.hasDynsym;
|
||||
bool maybePreemptible = ctx.sharedFiles.size() || ctx.arg.shared;
|
||||
for (Symbol *sym : ctx.symtab->getSymbols()) {
|
||||
if (auto *d = dyn_cast<Defined>(sym)) {
|
||||
@@ -301,9 +300,8 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDynsym)
|
||||
sym->isPreemptible = maybePreemptible &&
|
||||
(sym->isUndefined() || sym->isExported) &&
|
||||
if (maybePreemptible)
|
||||
sym->isPreemptible = (sym->isUndefined() || sym->isExported) &&
|
||||
computeIsPreemptible(ctx, *sym);
|
||||
}
|
||||
}
|
||||
@@ -1853,7 +1851,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||
|
||||
// If the previous code block defines any non-hidden symbols (e.g.
|
||||
// __global_pointer$), they may be exported.
|
||||
if (ctx.hasDynsym && ctx.arg.exportDynamic)
|
||||
if (ctx.arg.exportDynamic)
|
||||
for (Symbol *sym : ctx.synthesizedSymbols)
|
||||
if (sym->computeBinding(ctx) != STB_LOCAL)
|
||||
sym->isExported = true;
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
; RUN: ld.lld %t2.o -o %t3 -save-temps --lto-whole-program-visibility \
|
||||
; RUN: -mllvm -pass-remarks=. 2>&1 | FileCheck %s --check-prefix=REMARK
|
||||
; RUN: llvm-dis %t2.o.4.opt.bc -o - | FileCheck %s --check-prefix=CHECK-IR
|
||||
;; --export-dynamic without .dynsym does not prevent devirtualization.
|
||||
; RUN: ld.lld %t2.o -o %t3 -save-temps --lto-whole-program-visibility \
|
||||
; RUN: -mllvm -pass-remarks=. \
|
||||
; RUN: --export-dynamic 2>&1 | FileCheck %s --check-prefix=REMARK
|
||||
|
||||
;; Hybrid WPD
|
||||
;; Generate split module with summary for hybrid Thin/Regular LTO WPD.
|
||||
@@ -33,19 +37,20 @@
|
||||
; RUN: ld.lld -shared -soname=ta %ta.o -o %ta.so
|
||||
|
||||
;; Index based WPD
|
||||
; RUN: ld.lld %t2.o -o %t3 -save-temps --lto-whole-program-visibility \
|
||||
|
||||
; RUN: ld.lld %t2.o %ta.so -o %t3 -save-temps --lto-whole-program-visibility \
|
||||
; RUN: -mllvm -pass-remarks=. \
|
||||
; RUN: --export-dynamic 2>&1 | FileCheck /dev/null --implicit-check-not single-impl --allow-empty
|
||||
; RUN: llvm-dis %t2.o.4.opt.bc -o - | FileCheck %s --check-prefix=CHECK-NODEVIRT-IR
|
||||
|
||||
;; Hybrid WPD
|
||||
; RUN: ld.lld %t.o -o %t3 -save-temps --lto-whole-program-visibility \
|
||||
; RUN: ld.lld %t.o %ta.so -o %t3 -save-temps --lto-whole-program-visibility \
|
||||
; RUN: -mllvm -pass-remarks=. \
|
||||
; RUN: --export-dynamic 2>&1 | FileCheck /dev/null --implicit-check-not single-impl --allow-empty
|
||||
; RUN: llvm-dis %t.o.4.opt.bc -o - | FileCheck %s --check-prefix=CHECK-NODEVIRT-IR
|
||||
|
||||
;; Regular LTO WPD
|
||||
; RUN: ld.lld %t4.o -o %t3 -save-temps --lto-whole-program-visibility \
|
||||
; RUN: ld.lld %t4.o %ta.so -o %t3 -save-temps --lto-whole-program-visibility \
|
||||
; RUN: -mllvm -pass-remarks=. \
|
||||
; RUN: --export-dynamic 2>&1 | FileCheck /dev/null --implicit-check-not single-impl --allow-empty
|
||||
; RUN: llvm-dis %t3.0.4.opt.bc -o - | FileCheck %s --check-prefix=CHECK-NODEVIRT-IR
|
||||
|
||||
Reference in New Issue
Block a user