forked from OSchip/llvm-project
				
			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,6 +1219,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
 | 
			
		|||
  applySynthetic({In<ELFT>::EhFrame},
 | 
			
		||||
                 [](SyntheticSection *SS) { SS->finalizeContents(); });
 | 
			
		||||
 | 
			
		||||
  if (Config->DynamicList.empty())
 | 
			
		||||
    for (Symbol *S : Symtab->getSymbols())
 | 
			
		||||
      S->body()->IsPreemptible = computeIsPreemptible(*S->body());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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…
	
		Reference in New Issue