summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp20
-rw-r--r--lld/ELF/SymbolTable.h10
-rw-r--r--lld/test/ELF/linkerscript/Inputs/lazy-symbols.s2
-rw-r--r--lld/test/ELF/linkerscript/lazy-symbols.s13
4 files changed, 30 insertions, 15 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index a5ecf48f18f..7c9328d845a 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -57,12 +57,12 @@ LinkerScriptBase *elf::ScriptBase;
ScriptConfiguration *elf::ScriptConfig;
template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
+ Symbol *Sym;
uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
- Symbol *Sym = Symtab<ELFT>::X->addUndefined(
- Cmd->Name, /*IsLocal=*/false, STB_GLOBAL, Visibility,
- /*Type*/ 0,
- /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
-
+ std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
+ Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
+ /*File*/ nullptr);
+ Sym->Binding = STB_GLOBAL;
replaceBody<DefinedRegular<ELFT>>(Sym, Cmd->Name, /*IsLocal=*/false,
Visibility, STT_NOTYPE, 0, 0, nullptr,
nullptr);
@@ -70,14 +70,14 @@ template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
}
template <class ELFT> static SymbolBody *addSynthetic(SymbolAssignment *Cmd) {
+ Symbol *Sym;
uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
const OutputSectionBase *Sec =
ScriptConfig->HasSections ? nullptr : Cmd->Expression.Section();
- Symbol *Sym = Symtab<ELFT>::X->addUndefined(
- Cmd->Name, /*IsLocal=*/false, STB_GLOBAL, Visibility,
- /*Type*/ 0,
- /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
-
+ std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
+ Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
+ /*File*/ nullptr);
+ Sym->Binding = STB_GLOBAL;
replaceBody<DefinedSynthetic>(Sym, Cmd->Name, 0, Sec);
return Sym->body();
}
diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h
index f39dbd1e2e1..371188179d2 100644
--- a/lld/ELF/SymbolTable.h
+++ b/lld/ELF/SymbolTable.h
@@ -77,6 +77,11 @@ public:
uint8_t Binding, uint8_t StOther, uint8_t Type,
InputFile *File);
+ std::pair<Symbol *, bool> insert(StringRef Name);
+ std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Type,
+ uint8_t Visibility, bool CanOmitFromDynSym,
+ InputFile *File);
+
void scanUndefinedFlags();
void scanShlibUndefined();
void scanVersionScript();
@@ -90,11 +95,6 @@ public:
std::vector<InputSectionBase<ELFT> *> Sections;
private:
- std::pair<Symbol *, bool> insert(StringRef Name);
- std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Type,
- uint8_t Visibility, bool CanOmitFromDynSym,
- InputFile *File);
-
std::vector<SymbolBody *> findByVersion(SymbolVersion Ver);
std::vector<SymbolBody *> findAllByVersion(SymbolVersion Ver);
diff --git a/lld/test/ELF/linkerscript/Inputs/lazy-symbols.s b/lld/test/ELF/linkerscript/Inputs/lazy-symbols.s
new file mode 100644
index 00000000000..dd28fcbd525
--- /dev/null
+++ b/lld/test/ELF/linkerscript/Inputs/lazy-symbols.s
@@ -0,0 +1,2 @@
+.globl foo
+foo:
diff --git a/lld/test/ELF/linkerscript/lazy-symbols.s b/lld/test/ELF/linkerscript/lazy-symbols.s
new file mode 100644
index 00000000000..22dffeef979
--- /dev/null
+++ b/lld/test/ELF/linkerscript/lazy-symbols.s
@@ -0,0 +1,13 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/lazy-symbols.s -o %t1
+# RUN: llvm-ar rcs %tar %t1
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
+# RUN: echo "foo = 1;" > %t.script
+# RUN: ld.lld %t2 %tar --script %t.script -o %tout
+# RUN: llvm-readobj -symbols %tout | FileCheck %s
+
+# This test is to ensure a linker script can define a symbol which have the same
+# name as a lazy symbol.
+
+# CHECK: Name: foo
+# CHECK-NEXT: Value: 0x1
OpenPOWER on IntegriCloud