diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -766,6 +766,15 @@ } }; std::unordered_map SymbolToFileName; + auto isSymbolGlobal = [](const ELFSymbolRef &Sym) { + if (cantFail(Sym.getFlags()) & SymbolRef::SF_Global) + return true; + // Hidden symbols are globals that were demoted to local at link-time. + // They should still be unique names at DSO-level. + if (cantFail(Sym.getFlags()) & SymbolRef::SF_Hidden) + return true; + return false; + }; for (const ELFSymbolRef &Symbol : InputFile->symbols()) { Expected NameOrError = Symbol.getName(); if (NameOrError && NameOrError->startswith("__asan_init")) { @@ -793,8 +802,7 @@ SeenFileName = true; continue; } - if (!FileSymbolName.empty() && - !(cantFail(Symbol.getFlags()) & SymbolRef::SF_Global)) + if (!FileSymbolName.empty() && !(isSymbolGlobal(Symbol))) SymbolToFileName[Symbol] = FileSymbolName; } @@ -951,7 +959,7 @@ std::string AlternativeName; if (Name.empty()) { UniqueName = "ANONYMOUS." + std::to_string(AnonymousId++); - } else if (cantFail(Symbol.getFlags()) & SymbolRef::SF_Global) { + } else if (isSymbolGlobal(Symbol)) { if (const BinaryData *BD = BC->getBinaryDataByName(Name)) { if (BD->getSize() == ELFSymbolRef(Symbol).getSize() && BD->getAddress() == Address) { diff --git a/bolt/test/AArch64/array_end.c b/bolt/test/AArch64/array_end.c --- a/bolt/test/AArch64/array_end.c +++ b/bolt/test/AArch64/array_end.c @@ -8,7 +8,7 @@ // RUN: llvm-bolt %t.exe -o %t.bolt --print-disasm \ // RUN: --print-only="callFini" | FileCheck %s -// CHECK: adr [[REG:x[0-28]+]], "__fini_array_end/1" +// CHECK: adr [[REG:x[0-28]+]], __fini_array_end __attribute__((destructor)) void destr() {}