forked from OSchip/llvm-project
[ELF] Support expressions with -defsym option
Fixes PR34948. Differential Revision: https://reviews.llvm.org/D39511 llvm-svn: 317396
This commit is contained in:
parent
39770ca0a1
commit
8c7e8cce99
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue