mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-08 09:03:18 +00:00
[ELF] Add Symbol::hasVersionSuffix
"Process symbol versions" may take 2+% time. "Redirect symbols" may take 0.6% time. This change speeds up the two passes and makes `*sym.getVersionSuffix() == '@'` in the `undefined reference` diagnostic cleaner. Linking chrome (no debug info) and another large program is 1.5% faster. For empty-ver2.s: the behavior now matches GNU ld, though I'd consider the input invalid and the exact behavior does not matter.
This commit is contained in:
parent
469144ffa3
commit
7924b3814f
@ -2006,7 +2006,8 @@ template <class ELFT> void LinkerDriver::compileBitcodeFiles() {
|
||||
// Parse '@' in symbol names for non-relocatable output.
|
||||
if (!config->relocatable)
|
||||
for (Symbol *sym : obj->getGlobalSymbols())
|
||||
sym->parseSymbolVersion();
|
||||
if (sym->hasVersionSuffix)
|
||||
sym->parseSymbolVersion();
|
||||
objectFiles.push_back(obj);
|
||||
}
|
||||
}
|
||||
@ -2080,8 +2081,10 @@ static void redirectSymbols(ArrayRef<WrappedSymbol> wrapped) {
|
||||
map[w.real] = w.sym;
|
||||
}
|
||||
for (Symbol *sym : symtab->symbols()) {
|
||||
// Enumerate symbols with a non-default version (foo@v1).
|
||||
StringRef name = sym->getName();
|
||||
// Enumerate symbols with a non-default version (foo@v1). hasVersionSuffix
|
||||
// filters out most symbols but is not sufficient.
|
||||
if (!sym->hasVersionSuffix)
|
||||
continue;
|
||||
const char *suffix1 = sym->getVersionSuffix();
|
||||
if (suffix1[0] != '@' || suffix1[1] == '@')
|
||||
continue;
|
||||
@ -2090,7 +2093,7 @@ static void redirectSymbols(ArrayRef<WrappedSymbol> wrapped) {
|
||||
//
|
||||
// * There is a definition of foo@v1 and foo@@v1.
|
||||
// * There is a definition of foo@v1 and foo.
|
||||
Defined *sym2 = dyn_cast_or_null<Defined>(symtab->find(name));
|
||||
Defined *sym2 = dyn_cast_or_null<Defined>(symtab->find(sym->getName()));
|
||||
if (!sym2)
|
||||
continue;
|
||||
const char *suffix2 = sym2->getVersionSuffix();
|
||||
|
@ -741,7 +741,7 @@ static bool maybeReportUndefined(Symbol &sym, InputSectionBase &sec,
|
||||
uint64_t offset) {
|
||||
// If versioned, issue an error (even if the symbol is weak) because we don't
|
||||
// know the defining filename which is required to construct a Verneed entry.
|
||||
if (*sym.getVersionSuffix() == '@') {
|
||||
if (sym.hasVersionSuffix) {
|
||||
undefs.push_back({&sym, {{&sec, offset}}, false});
|
||||
return true;
|
||||
}
|
||||
|
@ -72,8 +72,10 @@ Symbol *SymbolTable::insert(StringRef name) {
|
||||
auto p = symMap.insert({CachedHashStringRef(stem), (int)symVector.size()});
|
||||
if (!p.second) {
|
||||
Symbol *sym = symVector[p.first->second];
|
||||
if (stem.size() != name.size())
|
||||
if (stem.size() != name.size()) {
|
||||
sym->setName(name);
|
||||
sym->hasVersionSuffix = true;
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
||||
@ -93,6 +95,8 @@ Symbol *SymbolTable::insert(StringRef name) {
|
||||
sym->referenced = false;
|
||||
sym->traced = false;
|
||||
sym->scriptDefined = false;
|
||||
if (pos != StringRef::npos)
|
||||
sym->hasVersionSuffix = true;
|
||||
sym->partition = 1;
|
||||
return sym;
|
||||
}
|
||||
@ -316,7 +320,8 @@ void SymbolTable::scanVersionScript() {
|
||||
// can contain versions in the form of <name>@<version>.
|
||||
// Let them parse and update their names to exclude version suffix.
|
||||
for (Symbol *sym : symVector)
|
||||
sym->parseSymbolVersion();
|
||||
if (sym->hasVersionSuffix)
|
||||
sym->parseSymbolVersion();
|
||||
|
||||
// isPreemptible is false at this point. To correctly compute the binding of a
|
||||
// Defined (which is used by includeInDynsym()), we need to know if it is
|
||||
|
@ -216,12 +216,13 @@ void Symbol::parseSymbolVersion() {
|
||||
if (pos == StringRef::npos)
|
||||
return;
|
||||
StringRef verstr = s.substr(pos + 1);
|
||||
if (verstr.empty())
|
||||
return;
|
||||
|
||||
// Truncate the symbol name so that it doesn't include the version string.
|
||||
nameSize = pos;
|
||||
|
||||
if (verstr.empty())
|
||||
return;
|
||||
|
||||
// If this is not in this DSO, it is not a definition.
|
||||
if (!isDefined())
|
||||
return;
|
||||
|
@ -144,6 +144,9 @@ public:
|
||||
// True if this symbol is specified by --trace-symbol option.
|
||||
uint8_t traced : 1;
|
||||
|
||||
// True if the name contains '@'.
|
||||
uint8_t hasVersionSuffix : 1;
|
||||
|
||||
inline void replace(const Symbol &newSym);
|
||||
|
||||
bool includeInDynsym() const;
|
||||
@ -246,10 +249,11 @@ protected:
|
||||
type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3),
|
||||
isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind),
|
||||
exportDynamic(isExportDynamic(k, visibility)), inDynamicList(false),
|
||||
canInline(false), referenced(false), traced(false), isInIplt(false),
|
||||
gotInIgot(false), isPreemptible(false), used(!config->gcSections),
|
||||
folded(false), needsTocRestore(false), scriptDefined(false),
|
||||
needsCopy(false), needsGot(false), needsPlt(false), needsTlsDesc(false),
|
||||
canInline(false), referenced(false), traced(false),
|
||||
hasVersionSuffix(false), isInIplt(false), gotInIgot(false),
|
||||
isPreemptible(false), used(!config->gcSections), folded(false),
|
||||
needsTocRestore(false), scriptDefined(false), needsCopy(false),
|
||||
needsGot(false), needsPlt(false), needsTlsDesc(false),
|
||||
needsTlsGd(false), needsTlsGdToIe(false), needsTlsLd(false),
|
||||
needsGotDtprel(false), needsTlsIe(false), hasDirectReloc(false) {}
|
||||
|
||||
@ -575,6 +579,7 @@ void Symbol::replace(const Symbol &newSym) {
|
||||
canInline = old.canInline;
|
||||
referenced = old.referenced;
|
||||
traced = old.traced;
|
||||
hasVersionSuffix = old.hasVersionSuffix;
|
||||
isPreemptible = old.isPreemptible;
|
||||
scriptDefined = old.scriptDefined;
|
||||
partition = old.partition;
|
||||
|
@ -12,7 +12,7 @@
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Version: 1
|
||||
# CHECK-NEXT: Name: bar@
|
||||
# CHECK-NEXT: Name: bar{{$}}
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user