mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-24 10:07:48 +00:00
[ELF] - Implemented --defsym option.
gnu ld description of option is: --defsym=symbol=expression Create a global symbol in the output file, containing the absolute address given by expression. You may use this option as many times as necessary to define multiple symbols in the command line. A limited form of arithmetic is supported for the expression in this context: you may give a hexadecimal constant or the name of an existing symbol, or use "+" and "-" to add or subtract hexadecimal constants or symbols. If you need more elaborate expressions, consider using the linker command language from a script. Note: there should be no white space between symbol, the equals sign ("="), and expression. In compare with D32082, this patch does not support math expressions and absolute symbols. It implemented via code similar to --wrap. That covers 1 of 3 possible --defsym cases. Differential revision: https://reviews.llvm.org/D32171 llvm-svn: 301391
This commit is contained in:
parent
c3c6723ab5
commit
9703ad2221
@ -880,6 +880,21 @@ static 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;
|
||||
}
|
||||
|
||||
// Do actual linking. Note that when this function is called,
|
||||
// all linker scripts have already been parsed.
|
||||
template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
||||
@ -945,6 +960,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
||||
for (auto *Arg : Args.filtered(OPT_wrap))
|
||||
Symtab.wrap(Arg->getValue());
|
||||
|
||||
// Handle --defsym=sym=alias option.
|
||||
for (std::pair<StringRef, StringRef> &Def : getDefsym(Args))
|
||||
Symtab.alias(Def.first, Def.second);
|
||||
|
||||
// Now that we have a complete list of input files.
|
||||
// Beyond this point, no new files are added.
|
||||
// Aggregate all input sections into one place.
|
||||
|
@ -25,6 +25,8 @@ def build_id_eq: J<"build-id=">, HelpText<"Generate build ID note">;
|
||||
def compress_debug_sections : J<"compress-debug-sections=">,
|
||||
HelpText<"Compress DWARF debug sections">;
|
||||
|
||||
def defsym: J<"defsym=">, HelpText<"Define a symbol alias">;
|
||||
|
||||
def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
|
||||
HelpText<"Add a directory to the library search path">;
|
||||
|
||||
|
@ -168,6 +168,19 @@ template <class ELFT> void SymbolTable<ELFT>::wrap(StringRef Name) {
|
||||
memcpy(Sym->Body.buffer, Wrap->Body.buffer, sizeof(Wrap->Body));
|
||||
}
|
||||
|
||||
// Creates alias for symbol. Used to implement --defsym=ALIAS=SYM.
|
||||
template <class ELFT>
|
||||
void SymbolTable<ELFT>::alias(StringRef Alias, StringRef Name) {
|
||||
SymbolBody *B = find(Name);
|
||||
if (!B) {
|
||||
error("-defsym: undefined symbol: " + Name);
|
||||
return;
|
||||
}
|
||||
Symbol *Sym = B->symbol();
|
||||
Symbol *AliasSym = addUndefined(Alias);
|
||||
memcpy(AliasSym->Body.buffer, Sym->Body.buffer, sizeof(AliasSym->Body));
|
||||
}
|
||||
|
||||
static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
|
||||
if (VA == STV_DEFAULT)
|
||||
return VB;
|
||||
|
@ -86,6 +86,7 @@ public:
|
||||
|
||||
void trace(StringRef Name);
|
||||
void wrap(StringRef Name);
|
||||
void alias(StringRef Alias, StringRef Name);
|
||||
|
||||
private:
|
||||
std::vector<SymbolBody *> findByVersion(SymbolVersion Ver);
|
||||
|
44
lld/test/ELF/defsym.s
Normal file
44
lld/test/ELF/defsym.s
Normal file
@ -0,0 +1,44 @@
|
||||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||
# RUN: ld.lld -o %t %t.o --defsym=foo2=foo1
|
||||
# RUN: llvm-readobj -t -s %t | FileCheck %s
|
||||
# RUN: llvm-objdump -d -print-imm-hex %t | FileCheck %s --check-prefix=USE
|
||||
|
||||
## In compare with GNU linkers, symbol defined with --defsym does
|
||||
## not get aliased name in symbol table:
|
||||
# CHECK: Symbol {
|
||||
# CHECK: Name: foo1
|
||||
# CHECK-NEXT: Value: 0x123
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Binding: Global
|
||||
# CHECK-NEXT: Type:
|
||||
# CHECK-NEXT: Other:
|
||||
# CHECK-NEXT: Section: Absolute
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name: foo1
|
||||
# CHECK-NEXT: Value: 0x123
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Binding: Global
|
||||
# CHECK-NEXT: Type:
|
||||
# CHECK-NEXT: Other:
|
||||
# CHECK-NEXT: Section: Absolute
|
||||
# CHECK-NEXT: }
|
||||
|
||||
## Check we can use foo2 and it that it is an alias for foo1.
|
||||
# USE: Disassembly of section .text:
|
||||
# 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: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR2
|
||||
# ERR2: error: -defsym: undefined symbol: und
|
||||
|
||||
.globl foo1
|
||||
foo1 = 0x123
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
movl $foo2, %edx
|
Loading…
x
Reference in New Issue
Block a user