Skip to content

Commit

Permalink
Recommit r281318 "[ELF] - Versionscript: support mangled symbols with…
Browse files Browse the repository at this point in the history
… the same name."

Previouly bot was failing:
http://lab.llvm.org:8011/builders/clang-with-lto-ubuntu/builds/413/steps/test-stage1-compiler/logs/stdio
Fixed possible segfault, so commit should bix the buildbot.

Initial commit message:

This is PR30312. Info from bug page:

Both of these symbols demangle to abc::abc():
_ZN3abcC1Ev
_ZN3abcC2Ev
(These would be abc's complete object constructor and base object constructor, respectively.)
however with "abc::abc()" in the version script only one of the two receives the symbol version.

Patch fixes that.
It uses testcase created by Ed Maste (D24306).

Differential revision: https://reviews.llvm.org/D24336

llvm-svn: 281605
  • Loading branch information
George Rimar committed Sep 15, 2016
1 parent fe7fd87 commit 31c25ae
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 16 deletions.
34 changes: 21 additions & 13 deletions lld/ELF/SymbolTable.cpp
Expand Up @@ -594,11 +594,12 @@ static void setVersionId(SymbolBody *Body, StringRef VersionName,
// The relationship is 1:N instead of 1:1 because with the symbol
// versioning, more than one symbol may have the same name.
template <class ELFT>
std::map<std::string, SymbolBody *> SymbolTable<ELFT>::getDemangledSyms() {
std::map<std::string, SymbolBody *> Result;
std::map<std::string, std::vector<SymbolBody *>>
SymbolTable<ELFT>::getDemangledSyms() {
std::map<std::string, std::vector<SymbolBody *>> Result;
for (Symbol *Sym : SymVector) {
SymbolBody *B = Sym->body();
Result[demangle(B->getName())] = B;
Result[demangle(B->getName())].push_back(B);
}
return Result;
}
Expand All @@ -611,22 +612,24 @@ static bool hasExternCpp() {
return false;
}

static SymbolBody *findDemangled(const std::map<std::string, SymbolBody *> &D,
StringRef Name) {
static ArrayRef<SymbolBody *>
findDemangled(std::map<std::string, std::vector<SymbolBody *>> &D,
StringRef Name) {
auto I = D.find(Name);
if (I != D.end())
return I->second;
return nullptr;
return {};
}

static std::vector<SymbolBody *>
findAllDemangled(const std::map<std::string, SymbolBody *> &D,
findAllDemangled(const std::map<std::string, std::vector<SymbolBody *>> &D,
const Regex &Re) {
std::vector<SymbolBody *> Res;
for (auto &P : D) {
SymbolBody *Body = P.second;
if (!Body->isUndefined() && const_cast<Regex &>(Re).match(P.first))
Res.push_back(Body);
if (const_cast<Regex &>(Re).match(P.first))
for (SymbolBody *Body : P.second)
if (!Body->isUndefined())
Res.push_back(Body);
}
return Res;
}
Expand Down Expand Up @@ -675,7 +678,7 @@ template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() {
// "llvm::*::foo(int, ?)". Obviously, there's no way to handle this
// other than trying to match a regexp against all demangled symbols.
// So, if "extern C++" feature is used, we demangle all known symbols.
std::map<std::string, SymbolBody *> Demangled;
std::map<std::string, std::vector<SymbolBody *>> Demangled;
if (hasExternCpp())
Demangled = getDemangledSyms();

Expand All @@ -685,9 +688,14 @@ template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() {
for (SymbolVersion Sym : V.Globals) {
if (Sym.HasWildcards)
continue;

StringRef N = Sym.Name;
SymbolBody *B = Sym.IsExternCpp ? findDemangled(Demangled, N) : find(N);
setVersionId(B, V.Name, N, V.Id);
if (Sym.IsExternCpp) {
for (SymbolBody *B : findDemangled(Demangled, N))
setVersionId(B, V.Name, N, V.Id);
continue;
}
setVersionId(find(N), V.Name, N, V.Id);
}
}

Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/SymbolTable.h
Expand Up @@ -101,7 +101,7 @@ template <class ELFT> class SymbolTable {
std::string conflictMsg(SymbolBody *Existing, InputFile *NewFile);
void reportDuplicate(SymbolBody *Existing, InputFile *NewFile);

std::map<std::string, SymbolBody *> getDemangledSyms();
std::map<std::string, std::vector<SymbolBody *>> getDemangledSyms();
void handleAnonymousVersion();

struct SymIndex {
Expand Down
22 changes: 20 additions & 2 deletions lld/test/ELF/version-script-extern.s
Expand Up @@ -64,11 +64,20 @@
# DSO-NEXT: Other: 0
# DSO-NEXT: Section: .text (0x6)
# DSO-NEXT: }
# DSO-NEXT: Symbol {
# DSO-NEXT: Name: _ZN3abcC2Ev@@LIBSAMPLE_1.0
# DSO-NEXT: Value: 0x1004
# DSO-NEXT: Size: 0
# DSO-NEXT: Binding: Global (0x1)
# DSO-NEXT: Type: Function (0x2)
# DSO-NEXT: Other: 0
# DSO-NEXT: Section: .text (0x6)
# DSO-NEXT: }
# DSO-NEXT: ]
# DSO-NEXT: Version symbols {
# DSO-NEXT: Section Name: .gnu.version
# DSO-NEXT: Address: 0x240
# DSO-NEXT: Offset: 0x240
# DSO-NEXT: Address: 0x258
# DSO-NEXT: Offset: 0x258
# DSO-NEXT: Link: 1
# DSO-NEXT: Symbols [
# DSO-NEXT: Symbol {
Expand All @@ -91,6 +100,10 @@
# DSO-NEXT: Version: 2
# DSO-NEXT: Name: _ZN3abcC1Ev@@LIBSAMPLE_1.0
# DSO-NEXT: }
# DSO-NEXT: Symbol {
# DSO-NEXT: Version: 2
# DSO-NEXT: Name: _ZN3abcC2Ev@@LIBSAMPLE_1.0
# DSO-NEXT: }
# DSO-NEXT: ]
# DSO-NEXT: }

Expand All @@ -114,3 +127,8 @@ retq
.type _ZN3abcC1Ev,@function
_ZN3abcC1Ev:
retq

.globl _ZN3abcC2Ev
.type _ZN3abcC2Ev,@function
_ZN3abcC2Ev:
retq

0 comments on commit 31c25ae

Please sign in to comment.