summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp4
-rw-r--r--lld/ELF/SymbolTable.cpp8
-rw-r--r--lld/ELF/SymbolTable.h2
-rw-r--r--lld/ELF/Writer.cpp16
-rw-r--r--lld/test/ELF/startstop-shared.s16
-rw-r--r--lld/test/ELF/startstop.s24
6 files changed, 45 insertions, 25 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 6b037a021fb..9cfbb48a2ca 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -51,8 +51,8 @@ static void addRegular(SymbolAssignment *Cmd) {
}
template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) {
- Symbol *Sym = Symtab<ELFT>::X->addSynthetic(Cmd->Name, nullptr, 0);
- Sym->Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
+ Symbol *Sym = Symtab<ELFT>::X->addSynthetic(
+ Cmd->Name, nullptr, 0, Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT);
Cmd->Sym = Sym->body();
}
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index b4f9411ac49..c657a3a0608 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -418,12 +418,12 @@ Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t Binding,
template <typename ELFT>
Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N,
OutputSectionBase<ELFT> *Section,
- uintX_t Value) {
+ uintX_t Value, uint8_t StOther) {
Symbol *S;
bool WasInserted;
- std::tie(S, WasInserted) =
- insert(N, STT_NOTYPE, STV_HIDDEN, /*CanOmitFromDynSym*/ false,
- /*IsUsedInRegularObj*/ true, nullptr);
+ std::tie(S, WasInserted) = insert(N, STT_NOTYPE, /*Visibility*/ StOther & 0x3,
+ /*CanOmitFromDynSym*/ false,
+ /*IsUsedInRegularObj*/ true, nullptr);
int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, STB_GLOBAL);
if (Cmp > 0)
replaceBody<DefinedSynthetic<ELFT>>(S, N, Value, Section);
diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h
index 416e9434296..7a2121c870f 100644
--- a/lld/ELF/SymbolTable.h
+++ b/lld/ELF/SymbolTable.h
@@ -65,7 +65,7 @@ public:
InputSectionBase<ELFT> *Section);
Symbol *addRegular(StringRef Name, uint8_t Binding, uint8_t StOther);
Symbol *addSynthetic(StringRef N, OutputSectionBase<ELFT> *Section,
- uintX_t Value);
+ uintX_t Value, uint8_t StOther);
void addShared(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
const typename ELFT::Verdef *Verdef);
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index ecbbc0a3352..b39897f8200 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -519,7 +519,7 @@ static Symbol *addOptionalSynthetic(StringRef Name,
return nullptr;
if (!S->isUndefined() && !S->isShared())
return S->symbol();
- return Symtab<ELFT>::X->addSynthetic(Name, Sec, Val);
+ return Symtab<ELFT>::X->addSynthetic(Name, Sec, Val, STV_HIDDEN);
}
template <class ELFT>
@@ -527,7 +527,7 @@ static void addSynthetic(StringRef Name, OutputSectionBase<ELFT> *Sec,
typename ELFT::uint Val) {
SymbolBody *S = Symtab<ELFT>::X->find(Name);
if (!S || S->isUndefined() || S->isShared())
- Symtab<ELFT>::X->addSynthetic(Name, Sec, Val);
+ Symtab<ELFT>::X->addSynthetic(Name, Sec, Val, STV_HIDDEN);
}
// The beginning and the ending of .rel[a].plt section are marked
// with __rel[a]_iplt_{start,end} symbols if it is a statically linked
@@ -554,7 +554,8 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
// so that it points to an absolute address which is relative to GOT.
// See "Global Data Symbols" in Chapter 6 in the following document:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- Symtab<ELFT>::X->addSynthetic("_gp", Out<ELFT>::Got, MipsGPOffset);
+ Symtab<ELFT>::X->addSynthetic("_gp", Out<ELFT>::Got, MipsGPOffset,
+ STV_HIDDEN);
// On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
// start of function and 'gp' pointer into GOT.
@@ -701,7 +702,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// Even the author of gold doesn't remember why gold behaves that way.
// https://sourceware.org/ml/binutils/2002-03/msg00360.html
if (Out<ELFT>::DynSymTab)
- Symtab<ELFT>::X->addSynthetic("_DYNAMIC", Out<ELFT>::Dynamic, 0);
+ Symtab<ELFT>::X->addSynthetic("_DYNAMIC", Out<ELFT>::Dynamic, 0,
+ STV_HIDDEN);
// Define __rel[a]_iplt_{start,end} symbols if needed.
addRelIpltSymbols();
@@ -893,11 +895,11 @@ void Writer<ELFT>::addStartStopSymbols(OutputSectionBase<ELFT> *Sec) {
StringRef Stop = Saver.save("__stop_" + S);
if (SymbolBody *B = Symtab<ELFT>::X->find(Start))
if (B->isUndefined())
- Symtab<ELFT>::X->addSynthetic(Start, Sec, 0);
+ Symtab<ELFT>::X->addSynthetic(Start, Sec, 0, B->getVisibility());
if (SymbolBody *B = Symtab<ELFT>::X->find(Stop))
if (B->isUndefined())
- Symtab<ELFT>::X->addSynthetic(Stop, Sec,
- DefinedSynthetic<ELFT>::SectionEnd);
+ Symtab<ELFT>::X->addSynthetic(
+ Stop, Sec, DefinedSynthetic<ELFT>::SectionEnd, B->getVisibility());
}
template <class ELFT>
diff --git a/lld/test/ELF/startstop-shared.s b/lld/test/ELF/startstop-shared.s
index 77411f3f25c..80ccf3df0aa 100644
--- a/lld/test/ELF/startstop-shared.s
+++ b/lld/test/ELF/startstop-shared.s
@@ -6,21 +6,23 @@
.data
.quad __start_foo
.section foo,"aw"
-// By default the symbol is hidden.
-// CHECK: R_X86_64_RELATIVE - 0x[[ADDR1:.*]]
.hidden __start_bar
.quad __start_bar
.section bar,"a"
-// References do not affect the visibility.
-// CHECK: R_X86_64_RELATIVE - 0x[[ADDR2:.*]]
+
+// Test that we are able to hide the symbol.
+// CHECK: R_X86_64_RELATIVE - 0x[[ADDR:.*]]
+
+// By default the symbol is visible and we need a dynamic reloc.
+// CHECK: R_X86_64_64 __start_foo 0x0
// CHECK: Name: __start_bar
-// CHECK-NEXT: Value: 0x[[ADDR2]]
+// CHECK-NEXT: Value: 0x[[ADDR]]
// CHECK-NEXT: Size:
// CHECK-NEXT: Binding: Local
// CHECK: Name: __start_foo
-// CHECK-NEXT: Value: 0x[[ADDR1]]
+// CHECK-NEXT: Value:
// CHECK-NEXT: Size:
-// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Binding: Global
diff --git a/lld/test/ELF/startstop.s b/lld/test/ELF/startstop.s
index a7b2e43e6a5..326196dafa6 100644
--- a/lld/test/ELF/startstop.s
+++ b/lld/test/ELF/startstop.s
@@ -22,30 +22,46 @@
// SYMBOL: Relocations [
// SYMBOL-NEXT: Section ({{.*}}) .rela.dyn {
-// SYMBOL-NEXT: 0x3000 R_X86_64_RELATIVE - 0x3020
-// SYMBOL-NEXT: 0x3008 R_X86_64_RELATIVE - 0x3021
-// SYMBOL-NEXT: 0x3010 R_X86_64_RELATIVE - 0x3010
-// SYMBOL-NEXT: 0x3018 R_X86_64_RELATIVE - 0x3011
+// SYMBOL-NEXT: 0x3010 R_X86_64_64 __stop_zed1 0x0
+// SYMBOL-NEXT: 0x3018 R_X86_64_64 __stop_zed1 0x1
+// SYMBOL-NEXT: 0x3000 R_X86_64_64 __stop_zed2 0x0
+// SYMBOL-NEXT: 0x3008 R_X86_64_64 __stop_zed2 0x1
// SYMBOL-NEXT: }
// SYMBOL-NEXT: ]
// SYMBOL: Symbol {
// SYMBOL: Name: __start_bar
// SYMBOL: Value: 0x1012
+// SYMBOL: STV_HIDDEN
// SYMBOL: Section: bar
// SYMBOL: }
// SYMBOL-NOT: Section: __stop_bar
// SYMBOL: Symbol {
// SYMBOL: Name: __start_foo
// SYMBOL: Value: 0x100F
+// SYMBOL: STV_HIDDEN
// SYMBOL: Section: foo
// SYMBOL: }
// SYMBOL: Symbol {
// SYMBOL: Name: __stop_foo
// SYMBOL: Value: 0x1012
+// STMBOL: STV_HIDDEN
// SYMBOL: Section: foo
// SYMBOL: }
+// SYMBOL: Symbol {
+// SYMBOL: Name: __stop_zed1
+// SYMBOL: Value: 0x3010
+// STMBOL: Other: 0
+// SYMBOL: Section: zed1
+// SYMBOL: }
+// SYMBOL: Symbol {
+// SYMBOL: Name: __stop_zed2
+// SYMBOL: Value: 0x3020
+// STMBOL: Other: 0
+// SYMBOL: Section: zed2
+// SYMBOL: }
+
.hidden __start_foo
.hidden __stop_foo
.hidden __start_bar
OpenPOWER on IntegriCloud