Fix bug in local symbol name disambiguation algorithm

Summary:
This bug would cause llvm-flo to fail to disambiguate two local symbols
with the same file name, causing two different addresses to compete in the
symbol table for the resolution of a given name, causing unpredicted behavior in
the linker.

(cherry picked from FBD2646626)
This commit is contained in:
Rafael Auler 2015-11-11 23:56:24 -08:00 committed by Maksim Panchenko
parent a30d04c3e2
commit e80d11f27a
1 changed files with 11 additions and 7 deletions

View File

@ -400,9 +400,20 @@ static void OptimizeFile(ELFObjectFileBase *File, const DataReader &DR) {
assert(BC->GlobalSymbols.find(*Name) == BC->GlobalSymbols.end() &&
"global name not unique");
UniqueName = *Name;
/// It's possible we are seeing a globalized local. LLVM might treat it as
/// local if it has a "private global" prefix, e.g. ".L". Thus we have to
/// change the prefix to enforce global scope of the symbol.
if (StringRef(UniqueName)
.startswith(BC->AsmInfo->getPrivateGlobalPrefix()))
UniqueName = "PG." + UniqueName;
} else {
unsigned LocalCount = 1;
std::string LocalName = (*Name).str() + "/" + FileSymbolName + "/";
if ((*Name).startswith(BC->AsmInfo->getPrivateGlobalPrefix())) {
LocalName = "PG." + LocalName;
}
while (BC->GlobalSymbols.find(LocalName + std::to_string(LocalCount)) !=
BC->GlobalSymbols.end()) {
++LocalCount;
@ -410,13 +421,6 @@ static void OptimizeFile(ELFObjectFileBase *File, const DataReader &DR) {
UniqueName = LocalName + std::to_string(LocalCount);
}
/// It's possible we are seeing a globalized local. Even though
/// we've made the name unique, LLVM might still treat it as local
/// if it has a "private global" prefix, e.g. ".L". Thus we have to
/// change the prefix to enforce global scope of the symbol.
if (StringRef(UniqueName).startswith(BC->AsmInfo->getPrivateGlobalPrefix()))
UniqueName = "PG." + UniqueName;
// Add the name to global symbols map.
BC->GlobalSymbols[UniqueName] = Address;