Skip to content

Commit

Permalink
[ELF] Support expressions with -defsym option
Browse files Browse the repository at this point in the history
Fixes PR34948.

Differential Revision: https://reviews.llvm.org/D39511

llvm-svn: 317396
  • Loading branch information
petrhosek committed Nov 4, 2017
1 parent 39770ca commit 8c7e8cc
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 24 deletions.
27 changes: 8 additions & 19 deletions lld/ELF/Driver.cpp
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
13 changes: 13 additions & 0 deletions lld/ELF/ScriptParser.cpp
Expand Up @@ -53,6 +53,7 @@ class ScriptParser final : ScriptLexer {
void readLinkerScript();
void readVersionScript();
void readDynamicList();
void readDefsym(StringRef Name);

private:
void addFile(StringRef Path);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
3 changes: 3 additions & 0 deletions lld/ELF/ScriptParser.h
Expand Up @@ -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

Expand Down
42 changes: 37 additions & 5 deletions lld/test/ELF/defsym.s
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 8c7e8cc

Please sign in to comment.