mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-10 03:13:34 +00:00
If --dynamic-list is given, only those symbols are preemptible
Patch by Rafael Espíndola. This is PR34053. The implementation is a bit of a hack, given the precise location where IsPreemtible is set, it cannot be used from SymbolTable::handleAnonymousVersion. I could add another method to SymbolTable if you think that would be better. Differential Revision: https://reviews.llvm.org/D36499 llvm-svn: 311468
This commit is contained in:
parent
2724d45325
commit
9cbbacb910
@ -104,6 +104,7 @@ struct Configuration {
|
||||
std::vector<llvm::StringRef> SearchPaths;
|
||||
std::vector<llvm::StringRef> SymbolOrderingFile;
|
||||
std::vector<llvm::StringRef> Undefined;
|
||||
std::vector<SymbolVersion> DynamicList;
|
||||
std::vector<SymbolVersion> VersionScriptGlobals;
|
||||
std::vector<SymbolVersion> VersionScriptLocals;
|
||||
std::vector<uint8_t> BuildIdVector;
|
||||
|
@ -175,9 +175,22 @@ static ExprValue bitOr(ExprValue A, ExprValue B) {
|
||||
|
||||
void ScriptParser::readDynamicList() {
|
||||
expect("{");
|
||||
readAnonymousDeclaration();
|
||||
if (!atEOF())
|
||||
std::vector<SymbolVersion> Locals;
|
||||
std::vector<SymbolVersion> Globals;
|
||||
std::tie(Locals, Globals) = readSymbols();
|
||||
expect(";");
|
||||
|
||||
if (!atEOF()) {
|
||||
setError("EOF expected, but got " + next());
|
||||
return;
|
||||
}
|
||||
if (!Locals.empty()) {
|
||||
setError("\"local:\" scope not supported in --dynamic-list");
|
||||
return;
|
||||
}
|
||||
|
||||
for (SymbolVersion V : Globals)
|
||||
Config->DynamicList.push_back(V);
|
||||
}
|
||||
|
||||
void ScriptParser::readVersionScript() {
|
||||
|
@ -680,6 +680,24 @@ void SymbolTable::handleAnonymousVersion() {
|
||||
assignWildcardVersion(Ver, VER_NDX_LOCAL);
|
||||
}
|
||||
|
||||
// Handles -dynamic-list.
|
||||
void SymbolTable::handleDynamicList() {
|
||||
for (SymbolVersion &Ver : Config->DynamicList) {
|
||||
std::vector<SymbolBody *> Syms;
|
||||
if (Ver.HasWildcard)
|
||||
Syms = findByVersion(Ver);
|
||||
else
|
||||
Syms = findAllByVersion(Ver);
|
||||
|
||||
for (SymbolBody *B : Syms) {
|
||||
if (!Config->Shared)
|
||||
B->symbol()->VersionId = VER_NDX_GLOBAL;
|
||||
else if (B->symbol()->includeInDynsym())
|
||||
B->IsPreemptible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set symbol versions to symbols. This function handles patterns
|
||||
// containing no wildcard characters.
|
||||
void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
|
||||
@ -729,6 +747,7 @@ void SymbolTable::assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId) {
|
||||
void SymbolTable::scanVersionScript() {
|
||||
// Handle edge cases first.
|
||||
handleAnonymousVersion();
|
||||
handleDynamicList();
|
||||
|
||||
// Now we have version definitions, so we need to set version ids to symbols.
|
||||
// Each version definition has a glob pattern, and all symbols that match
|
||||
|
@ -90,6 +90,8 @@ public:
|
||||
|
||||
void trace(StringRef Name);
|
||||
|
||||
void handleDynamicList();
|
||||
|
||||
private:
|
||||
std::vector<SymbolBody *> findByVersion(SymbolVersion Ver);
|
||||
std::vector<SymbolBody *> findAllByVersion(SymbolVersion Ver);
|
||||
|
@ -1219,8 +1219,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||
applySynthetic({In<ELFT>::EhFrame},
|
||||
[](SyntheticSection *SS) { SS->finalizeContents(); });
|
||||
|
||||
for (Symbol *S : Symtab->getSymbols())
|
||||
S->body()->IsPreemptible = computeIsPreemptible(*S->body());
|
||||
if (Config->DynamicList.empty())
|
||||
for (Symbol *S : Symtab->getSymbols())
|
||||
S->body()->IsPreemptible = computeIsPreemptible(*S->body());
|
||||
|
||||
// Scan relocations. This must be done after every symbol is declared so that
|
||||
// we can correctly decide if a dynamic relocation is needed.
|
||||
|
65
lld/test/ELF/dynamic-list-preempt.s
Normal file
65
lld/test/ELF/dynamic-list-preempt.s
Normal file
@ -0,0 +1,65 @@
|
||||
# REQUIRES: x86
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||
# RUN: echo "{ foo; zed; };" > %t.list
|
||||
# RUN: echo "{ global: foo; bar; local: *; };" > %t.vers
|
||||
# RUN: ld.lld -fatal-warnings -dynamic-list %t.list -version-script %t.vers -shared %t.o -o %t.so
|
||||
# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOCS %s
|
||||
# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=DYNSYMS %s
|
||||
|
||||
# RELOCS: Relocations [
|
||||
# RELOCS-NEXT: Section ({{.*}}) .rela.plt {
|
||||
# RELOCS-NEXT: R_X86_64_JUMP_SLOT foo 0x0
|
||||
# RELOCS-NEXT: }
|
||||
# RELOCS-NEXT: ]
|
||||
|
||||
# DYNSYMS: DynamicSymbols [
|
||||
# DYNSYMS-NEXT: Symbol {
|
||||
# DYNSYMS-NEXT: Name: @ (0)
|
||||
# DYNSYMS-NEXT: Value: 0x0
|
||||
# DYNSYMS-NEXT: Size: 0
|
||||
# DYNSYMS-NEXT: Binding: Local
|
||||
# DYNSYMS-NEXT: Type: None
|
||||
# DYNSYMS-NEXT: Other: 0
|
||||
# DYNSYMS-NEXT: Section: Undefined
|
||||
# DYNSYMS-NEXT: }
|
||||
# DYNSYMS-NEXT: Symbol {
|
||||
# DYNSYMS-NEXT: Name: bar@
|
||||
# DYNSYMS-NEXT: Value:
|
||||
# DYNSYMS-NEXT: Size:
|
||||
# DYNSYMS-NEXT: Binding: Global
|
||||
# DYNSYMS-NEXT: Type:
|
||||
# DYNSYMS-NEXT: Other:
|
||||
# DYNSYMS-NEXT: Section:
|
||||
# DYNSYMS-NEXT: }
|
||||
# DYNSYMS-NEXT: Symbol {
|
||||
# DYNSYMS-NEXT: Name: foo@
|
||||
# DYNSYMS-NEXT: Value:
|
||||
# DYNSYMS-NEXT: Size:
|
||||
# DYNSYMS-NEXT: Binding: Global
|
||||
# DYNSYMS-NEXT: Type:
|
||||
# DYNSYMS-NEXT: Other:
|
||||
# DYNSYMS-NEXT: Section:
|
||||
# DYNSYMS-NEXT: }
|
||||
# DYNSYMS-NEXT: ]
|
||||
|
||||
.globl foo
|
||||
foo:
|
||||
ret
|
||||
|
||||
.globl bar
|
||||
bar:
|
||||
ret
|
||||
|
||||
.globl baz
|
||||
baz:
|
||||
ret
|
||||
|
||||
.globl zed
|
||||
zed:
|
||||
ret
|
||||
|
||||
call foo@PLT
|
||||
call bar@PLT
|
||||
call baz@PLT
|
||||
call zed@PLT
|
Loading…
x
Reference in New Issue
Block a user