From 8c7e8cce991739077ae7cd2f888457ec7cba6aa4 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Sat, 4 Nov 2017 02:03:58 +0000 Subject: [PATCH] [ELF] Support expressions with -defsym option Fixes PR34948. Differential Revision: https://reviews.llvm.org/D39511 llvm-svn: 317396 --- lld/ELF/Driver.cpp | 27 ++++++++------------------- lld/ELF/ScriptParser.cpp | 13 +++++++++++++ lld/ELF/ScriptParser.h | 3 +++ 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 23e4116..c4d3bf2 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -946,21 +946,6 @@ static Optional getImageBase(opt::InputArgList &Args) { return V; } -// Parses --defsym=alias option. -static std::vector> -getDefsym(opt::InputArgList &Args) { - std::vector> 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 getExcludeLibs(opt::InputArgList &Args) { @@ -1054,6 +1039,14 @@ template void LinkerDriver::link(opt::InputArgList &Args) { for (InputFile *F : Files) Symtab->addFile(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 void LinkerDriver::link(opt::InputArgList &Args) { for (auto *Arg : Args.filtered(OPT_wrap)) Symtab->addSymbolWrap(Arg->getValue()); - // Create alias symbols for -defsym option. - for (std::pair &Def : getDefsym(Args)) - Symtab->addSymbolAlias(Def.first, Def.second); - Symtab->addCombinedLTOObject(); if (errorCount()) return; diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index af9bf19..8dd2366 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(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 f820044..d48d5aa 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 b821484..2abc08f 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 -- 2.7.4