diff options
| author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-03-28 20:36:28 +0000 |
|---|---|---|
| committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-03-28 20:36:28 +0000 |
| commit | a023f79db19dae6c42ce4240e85630510c20ac91 (patch) | |
| tree | 7f560eefe0cb296bd4d1313b0e77c054be60dca5 /llvm/lib | |
| parent | cc8ee8e3a226e160965dd586d22059bc3134337f (diff) | |
| download | bcm5719-llvm-a023f79db19dae6c42ce4240e85630510c20ac91.tar.gz bcm5719-llvm-a023f79db19dae6c42ce4240e85630510c20ac91.zip | |
Handle section vs global name conflict.
This is a fix for PR26941.
When there is both a section and a global definition with the same
name, the global wins.
Section symbols are not added to the symbol table; section references
are left undefined and fixed up in the object writer unless they've
been satisfied by some other definition.
llvm-svn: 264649
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 17 | ||||
| -rw-r--r-- | llvm/lib/MC/MCContext.cpp | 21 |
2 files changed, 23 insertions, 15 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 01b7148cea7..68c3cb13a1b 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -375,9 +375,24 @@ uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym, void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { + // Section symbols are used as definitions for undefined symbols with matching + // names. If there are multiple sections with the same name, the first one is + // used. + for (const MCSection &Sec : Asm) { + const MCSymbol *Begin = Sec.getBeginSymbol(); + if (!Begin) + continue; + + const MCSymbol *Alias = Asm.getContext().lookupSymbol(Begin->getName()); + if (!Alias || !Alias->isUndefined()) + continue; + + Renames.insert( + std::make_pair(cast<MCSymbolELF>(Alias), cast<MCSymbolELF>(Begin))); + } + // The presence of symbol versions causes undefined symbols and // versions declared with @@@ to be renamed. - for (const MCSymbol &A : Asm.symbols()) { const auto &Alias = cast<MCSymbolELF>(A); // Not an alias. diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 96e24de6b4d..e326738325a 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -124,19 +124,9 @@ MCSymbolELF *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) { return Sym; StringRef Name = Section.getSectionName(); - - MCSymbol *&OldSym = Symbols[Name]; - if (OldSym && OldSym->isUndefined()) { - Sym = cast<MCSymbolELF>(OldSym); - return Sym; - } - - auto NameIter = UsedNames.insert(std::make_pair(Name, true)).first; + auto NameIter = UsedNames.insert(std::make_pair(Name, false)).first; Sym = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false); - if (!OldSym) - OldSym = Sym; - return Sym; } @@ -192,9 +182,12 @@ MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix, raw_svector_ostream(NewName) << NextUniqueID++; } auto NameEntry = UsedNames.insert(std::make_pair(NewName, true)); - if (NameEntry.second) { - // Ok, we found a name. Have the MCSymbol object itself refer to the copy - // of the string that is embedded in the UsedNames entry. + if (NameEntry.second || !NameEntry.first->second) { + // Ok, we found a name. + // Mark it as used for a non-section symbol. + NameEntry.first->second = true; + // Have the MCSymbol object itself refer to the copy of the string that is + // embedded in the UsedNames entry. return createSymbolImpl(&*NameEntry.first, IsTemporary); } assert(IsTemporary && "Cannot rename non-temporary symbols"); |

