summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LTO.cpp3
-rw-r--r--lld/ELF/OutputSections.cpp6
-rw-r--r--lld/ELF/SymbolTable.cpp6
-rw-r--r--lld/ELF/Symbols.cpp21
-rw-r--r--lld/ELF/Writer.cpp4
-rw-r--r--lld/test/ELF/mips-dynamic.s4
-rw-r--r--lld/test/ELF/protected-shared.s23
7 files changed, 45 insertions, 22 deletions
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index a9196567c4c..2fdf94a6c5f 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -116,7 +116,8 @@ void BitcodeCompiler::add(BitcodeFile &F) {
// Shared libraries need to be handled slightly differently.
// For now, let's be conservative and just never internalize
// symbols when creating a shared library.
- if (!Config->Shared && !Config->ExportDynamic && !B->isUsedInRegularObj())
+ if (!Config->Shared && !Config->ExportDynamic && !B->isUsedInRegularObj() &&
+ !B->MustBeInDynSym)
if (!Used.count(GV))
InternalizedSyms.insert(GV->getName());
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 24258fe40cc..753960447fa 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -138,9 +138,6 @@ template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody &Sym) {
++MipsLocalEntries;
return;
}
- // All preemptible symbols with MIPS GOT entries should be represented
- // in the dynamic symbols table.
- Sym.MustBeInDynSym = true;
}
Sym.GotIndex = Entries.size();
Entries.push_back(&Sym);
@@ -299,9 +296,6 @@ RelocationSection<ELFT>::RelocationSection(StringRef Name)
template <class ELFT>
void RelocationSection<ELFT>::addReloc(const DynamicReloc<ELFT> &Reloc) {
- SymbolBody *Sym = Reloc.Sym;
- if (!Reloc.UseSymVA && Sym)
- Sym->MustBeInDynSym = true;
Relocs.push_back(Reloc);
}
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 2348f9a6fb4..c1f01c10da8 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -119,10 +119,12 @@ template <class ELFT> void SymbolTable<ELFT>::addCombinedLtoObject() {
for (SymbolBody *Body : Obj->getNonLocalSymbols()) {
Symbol *Sym = insert(Body);
Sym->Body->setUsedInRegularObj();
- if (!Sym->Body->isUndefined() && Body->isUndefined())
- continue;
+ if (Sym->Body->isShared())
+ Sym->Body->MustBeInDynSym = true;
if (Sym->Body->MustBeInDynSym)
Body->MustBeInDynSym = true;
+ if (!Sym->Body->isUndefined() && Body->isUndefined())
+ continue;
Sym->Body = Body;
}
ObjectFiles.emplace_back(Obj);
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 9def17c6dbb..a0d07690da6 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -218,6 +218,18 @@ int SymbolBody::compare(SymbolBody *Other) {
if (L > R)
return -Other->compare(this);
+ if (isShared() != Other->isShared()) {
+ SymbolBody *Shared = isShared() ? this : Other;
+ Shared->MustBeInDynSym = true;
+ if (Shared->getVisibility() == STV_DEFAULT) {
+ // We want to export all symbols that exist in the executable and are
+ // preemptable in DSOs, so that the symbols in the executable can
+ // preempt symbols in the DSO at runtime.
+ SymbolBody *NonShared = isShared() ? Other : this;
+ NonShared->MustBeInDynSym = true;
+ }
+ }
+
if (!isShared() && !Other->isShared()) {
uint8_t V = getMinVisibility(getVisibility(), Other->getVisibility());
setVisibility(V);
@@ -227,15 +239,6 @@ int SymbolBody::compare(SymbolBody *Other) {
if (IsUsedInRegularObj || Other->IsUsedInRegularObj)
IsUsedInRegularObj = Other->IsUsedInRegularObj = true;
- // We want to export all symbols that exist both in the executable
- // and in DSOs, so that the symbols in the executable can interrupt
- // symbols in the DSO at runtime.
- if (isShared() != Other->isShared())
- if (isa<Defined>(isShared() ? Other : this)) {
- IsUsedInRegularObj = Other->IsUsedInRegularObj = true;
- MustBeInDynSym = Other->MustBeInDynSym = true;
- }
-
if (L != R)
return -1;
if (!isDefined() || isShared() || isWeak())
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index b19627e8c03..02627cc9d1f 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -826,12 +826,14 @@ template <class ELFT> static bool includeInSymtab(const SymbolBody &B) {
}
static bool includeInDynsym(const SymbolBody &B) {
+ if (B.MustBeInDynSym)
+ return true;
uint8_t V = B.getVisibility();
if (V != STV_DEFAULT && V != STV_PROTECTED)
return false;
if (Config->ExportDynamic || Config->Shared)
return true;
- return B.MustBeInDynSym;
+ return false;
}
// This class knows how to create an output section for a given
diff --git a/lld/test/ELF/mips-dynamic.s b/lld/test/ELF/mips-dynamic.s
index 7dcc247e536..cc5f233163c 100644
--- a/lld/test/ELF/mips-dynamic.s
+++ b/lld/test/ELF/mips-dynamic.s
@@ -47,8 +47,8 @@
# EXE-DAG: 0x70000005 MIPS_FLAGS NOTPOT
# EXE-DAG: 0x70000006 MIPS_BASE_ADDRESS
# EXE-DAG: 0x7000000A MIPS_LOCAL_GOTNO 2
-# EXE-DAG: 0x70000011 MIPS_SYMTABNO 2
-# EXE-DAG: 0x70000013 MIPS_GOTSYM 0x2
+# EXE-DAG: 0x70000011 MIPS_SYMTABNO 3
+# EXE-DAG: 0x70000013 MIPS_GOTSYM 0x3
# EXE-DAG: 0x70000016 MIPS_RLD_MAP [[RLDMAPADDR]]
# EXE: ]
diff --git a/lld/test/ELF/protected-shared.s b/lld/test/ELF/protected-shared.s
index ee931831b30..e1391a1320f 100644
--- a/lld/test/ELF/protected-shared.s
+++ b/lld/test/ELF/protected-shared.s
@@ -3,7 +3,7 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/protected-shared.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld %t.o %t2.so -o %t
-// RUN: llvm-readobj -t %t | FileCheck %s
+// RUN: llvm-readobj -t --dyn-symbols %t | FileCheck %s
.global _start
_start:
@@ -27,3 +27,24 @@ bar:
// CHECK-NEXT: Type: None
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: Undefined
+
+// CHECK: DynamicSymbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: @
+// 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: foo@
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
OpenPOWER on IntegriCloud