diff options
| -rw-r--r-- | lld/ELF/Driver.cpp | 27 | ||||
| -rw-r--r-- | lld/ELF/ScriptParser.cpp | 13 | ||||
| -rw-r--r-- | lld/ELF/ScriptParser.h | 3 | ||||
| -rw-r--r-- | lld/test/ELF/defsym.s | 42 |
4 files changed, 61 insertions, 24 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 23e4116151b..c4d3bf223fc 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -946,21 +946,6 @@ static Optional<uint64_t> getImageBase(opt::InputArgList &Args) { return V; } -// Parses --defsym=alias option. -static std::vector<std::pair<StringRef, StringRef>> -getDefsym(opt::InputArgList &Args) { - std::vector<std::pair<StringRef, StringRef>> Ret; - for (auto *Arg : Args.filtered(OPT_defsym)) { - StringRef From; - StringRef To; - std::tie(From, To) = StringRef(Arg->getValue()).split('='); - if (!isValidCIdentifier(To)) - error("--defsym: symbol name expected, but got " + To); - Ret.push_back({From, To}); - } - return Ret; -} - // Parses `--exclude-libs=lib,lib,...`. // The library names may be delimited by commas or colons. static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) { @@ -1054,6 +1039,14 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { for (InputFile *F : Files) Symtab->addFile<ELFT>(F); + // Process -defsym option. + for (auto *Arg : Args.filtered(OPT_defsym)) { + StringRef From; + StringRef To; + std::tie(From, To) = StringRef(Arg->getValue()).split('='); + readDefsym(From, MemoryBufferRef(To, "-defsym")); + } + // Now that we have every file, we can decide if we will need a // dynamic symbol table. // We need one if we were asked to export dynamic symbols or if we are @@ -1095,10 +1088,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { for (auto *Arg : Args.filtered(OPT_wrap)) Symtab->addSymbolWrap<ELFT>(Arg->getValue()); - // Create alias symbols for -defsym option. - for (std::pair<StringRef, StringRef> &Def : getDefsym(Args)) - Symtab->addSymbolAlias<ELFT>(Def.first, Def.second); - Symtab->addCombinedLTOObject<ELFT>(); if (errorCount()) return; diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index af9bf1994b4..8dd23668b7a 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -53,6 +53,7 @@ public: void readLinkerScript(); void readVersionScript(); void readDynamicList(); + void readDefsym(StringRef Name); private: void addFile(StringRef Path); @@ -269,6 +270,14 @@ void ScriptParser::readLinkerScript() { } } +void ScriptParser::readDefsym(StringRef Name) { + Expr E = readExpr(); + if (!atEOF()) + setError("EOF expected, but got " + next()); + SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation()); + Script->SectionCommands.push_back(Cmd); +} + void ScriptParser::addFile(StringRef S) { if (IsUnderSysroot && S.startswith("/")) { SmallString<128> PathData; @@ -1326,3 +1335,7 @@ void elf::readVersionScript(MemoryBufferRef MB) { void elf::readDynamicList(MemoryBufferRef MB) { ScriptParser(MB).readDynamicList(); } + +void elf::readDefsym(StringRef Name, MemoryBufferRef MB) { + ScriptParser(MB).readDefsym(Name); +} diff --git a/lld/ELF/ScriptParser.h b/lld/ELF/ScriptParser.h index f820044cc58..d48d5aa2115 100644 --- a/lld/ELF/ScriptParser.h +++ b/lld/ELF/ScriptParser.h @@ -25,6 +25,9 @@ void readVersionScript(MemoryBufferRef MB); void readDynamicList(MemoryBufferRef MB); +// Parses the defsym expression. +void readDefsym(StringRef Name, MemoryBufferRef MB); + } // namespace elf } // namespace lld diff --git a/lld/test/ELF/defsym.s b/lld/test/ELF/defsym.s index b821484261b..2abc08f99df 100644 --- a/lld/test/ELF/defsym.s +++ b/lld/test/ELF/defsym.s @@ -19,7 +19,7 @@ # CHECK-NEXT: Section: Absolute # CHECK-NEXT: } # CHECK-NEXT: Symbol { -# CHECK-NEXT: Name: foo1 +# CHECK-NEXT: Name: foo2 # CHECK-NEXT: Value: 0x123 # CHECK-NEXT: Size: # CHECK-NEXT: Binding: Global @@ -33,11 +33,43 @@ # USE-NEXT: _start: # USE-NEXT: movl $0x123, %edx -# RUN: not ld.lld -o %t %t.o --defsym=foo2=1 2>&1 | FileCheck %s -check-prefix=ERR1 -# ERR1: error: --defsym: symbol name expected, but got 1 +# RUN: ld.lld -o %t %t.o --defsym=foo2=1 +# RUN: llvm-readobj -t -s %t | FileCheck %s --check-prefix=ABS -# RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR2 -# ERR2: error: -defsym: undefined symbol: und +# ABS: Symbol { +# ABS: Name: foo2 +# ABS-NEXT: Value: 0x1 +# ABS-NEXT: Size: +# ABS-NEXT: Binding: Global +# ABS-NEXT: Type: +# ABS-NEXT: Other: +# ABS-NEXT: Section: Absolute +# ABS-NEXT: } + +# RUN: ld.lld -o %t %t.o --defsym=foo2=foo1+5 +# RUN: llvm-readobj -t -s %t | FileCheck %s --check-prefix=EXPR + +# EXPR: Symbol { +# EXPR: Name: foo1 +# EXPR-NEXT: Value: 0x123 +# EXPR-NEXT: Size: +# EXPR-NEXT: Binding: Global +# EXPR-NEXT: Type: +# EXPR-NEXT: Other: +# EXPR-NEXT: Section: Absolute +# EXPR-NEXT: } +# EXPR-NEXT: Symbol { +# EXPR-NEXT: Name: foo2 +# EXPR-NEXT: Value: 0x128 +# EXPR-NEXT: Size: +# EXPR-NEXT: Binding: Global +# EXPR-NEXT: Type: +# EXPR-NEXT: Other: +# EXPR-NEXT: Section: Absolute +# EXPR-NEXT: } + +# RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR +# ERR: error: -defsym:1: symbol not found: und .globl foo1 foo1 = 0x123 |

