summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp75
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp7
-rw-r--r--llvm/lib/MC/MCELFStreamer.cpp5
-rw-r--r--llvm/lib/MC/MCParser/ELFAsmParser.cpp3
-rw-r--r--llvm/lib/MC/MCStreamer.cpp2
-rw-r--r--llvm/lib/Object/RecordStreamer.cpp4
-rw-r--r--llvm/lib/Object/RecordStreamer.h2
7 files changed, 30 insertions, 68 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index e11eaaa3060..989d4bb4eb9 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -128,8 +128,6 @@ class ELFObjectWriter : public MCObjectWriter {
/// @name Symbol Table Data
/// @{
- BumpPtrAllocator Alloc;
- StringSaver VersionSymSaver{Alloc};
StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
/// @}
@@ -391,27 +389,29 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
// 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.
- if (!Alias.isVariable())
- continue;
- auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue());
- if (!Ref)
- continue;
- const auto &Symbol = cast<MCSymbolELF>(Ref->getSymbol());
-
- StringRef AliasName = Alias.getName();
+ for (const std::pair<StringRef, const MCSymbol *> &P : Asm.Symvers) {
+ StringRef AliasName = P.first;
+ const auto &Symbol = cast<MCSymbolELF>(*P.second);
size_t Pos = AliasName.find('@');
- if (Pos == StringRef::npos)
- continue;
+ assert(Pos != StringRef::npos);
+
+ StringRef Prefix = AliasName.substr(0, Pos);
+ StringRef Rest = AliasName.substr(Pos);
+ StringRef Tail = Rest;
+ if (Rest.startswith("@@@"))
+ Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
+
+ auto *Alias =
+ cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
+ Asm.registerSymbol(*Alias);
+ const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
+ Alias->setVariableValue(Value);
// Aliases defined with .symvar copy the binding from the symbol they alias.
// This is the first place we are able to copy this information.
- Alias.setExternal(Symbol.isExternal());
- Alias.setBinding(Symbol.getBinding());
+ Alias->setExternal(Symbol.isExternal());
+ Alias->setBinding(Symbol.getBinding());
- StringRef Rest = AliasName.substr(Pos);
if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
continue;
@@ -420,7 +420,7 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
!Rest.startswith("@@@"))
report_fatal_error("A @@ version cannot be undefined");
- Renames.insert(std::make_pair(&Symbol, &Alias));
+ Renames.insert(std::make_pair(&Symbol, Alias));
}
}
@@ -836,44 +836,7 @@ void ELFObjectWriter::computeSymbolTable(
HasLargeSectionIndex = true;
}
- // The @@@ in symbol version is replaced with @ in undefined symbols and @@
- // in defined ones.
- //
- // FIXME: All name handling should be done before we get to the writer,
- // including dealing with GNU-style version suffixes. Fixing this isn't
- // trivial.
- //
- // We thus have to be careful to not perform the symbol version replacement
- // blindly:
- //
- // The ELF format is used on Windows by the MCJIT engine. Thus, on
- // Windows, the ELFObjectWriter can encounter symbols mangled using the MS
- // Visual Studio C++ name mangling scheme. Symbols mangled using the MSVC
- // C++ name mangling can legally have "@@@" as a sub-string. In that case,
- // the EFLObjectWriter should not interpret the "@@@" sub-string as
- // specifying GNU-style symbol versioning. The ELFObjectWriter therefore
- // checks for the MSVC C++ name mangling prefix which is either "?", "@?",
- // "__imp_?" or "__imp_@?".
- //
- // It would have been interesting to perform the MS mangling prefix check
- // only when the target triple is of the form *-pc-windows-elf. But, it
- // seems that this information is not easily accessible from the
- // ELFObjectWriter.
StringRef Name = Symbol.getName();
- SmallString<32> Buf;
- if (!Name.startswith("?") && !Name.startswith("@?") &&
- !Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) {
- // This symbol isn't following the MSVC C++ name mangling convention. We
- // can thus safely interpret the @@@ in symbol names as specifying symbol
- // versioning.
- size_t Pos = Name.find("@@@");
- if (Pos != StringRef::npos) {
- Buf += Name.substr(0, Pos);
- unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
- Buf += Name.substr(Pos + Skip);
- Name = VersionSymSaver.save(Buf.c_str());
- }
- }
// Sections have their own string table
if (Symbol.getType() != ELF::STT_SECTION) {
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 1d7aa5a9067..d92a63adc69 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -130,7 +130,7 @@ public:
void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
- void emitELFSymverDirective(MCSymbol *Alias,
+ void emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) override;
void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
@@ -417,12 +417,11 @@ void MCAsmStreamer::ChangeSection(MCSection *Section,
}
}
-void MCAsmStreamer::emitELFSymverDirective(MCSymbol *Alias,
+void MCAsmStreamer::emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) {
OS << ".symver ";
Aliasee->print(OS, MAI);
- OS << ", ";
- Alias->print(OS, MAI);
+ OS << ", " << AliasName;
EmitEOL();
}
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 646d0dbded4..6b1c589f038 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -337,10 +337,9 @@ void MCELFStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
cast<MCSymbolELF>(Symbol)->setSize(Value);
}
-void MCELFStreamer::emitELFSymverDirective(MCSymbol *Alias,
+void MCELFStreamer::emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) {
- const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext());
- EmitAssignment(Alias, Value);
+ getAssembler().Symvers.push_back({AliasName, Aliasee});
}
void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index 510c456c775..b9fa49e131b 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -769,9 +769,8 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
if (AliasName.find('@') == StringRef::npos)
return TokError("expected a '@' in the name");
- MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
- getStreamer().emitELFSymverDirective(Alias, Sym);
+ getStreamer().emitELFSymverDirective(AliasName, Sym);
return false;
}
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index bf27a0abfda..7d847c67605 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -929,7 +929,7 @@ void MCStreamer::EmitCOFFSymbolType(int Type) {
llvm_unreachable("this directive only supported on COFF targets");
}
void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
-void MCStreamer::emitELFSymverDirective(MCSymbol *Alias,
+void MCStreamer::emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) {}
void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {}
diff --git a/llvm/lib/Object/RecordStreamer.cpp b/llvm/lib/Object/RecordStreamer.cpp
index a9e3a46b519..56e9ce73047 100644
--- a/llvm/lib/Object/RecordStreamer.cpp
+++ b/llvm/lib/Object/RecordStreamer.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "RecordStreamer.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
using namespace llvm;
@@ -112,8 +113,9 @@ void RecordStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
markDefined(*Symbol);
}
-void RecordStreamer::emitELFSymverDirective(MCSymbol *Alias,
+void RecordStreamer::emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) {
+ MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext());
EmitAssignment(Alias, Value);
SymverAliasMap[Aliasee].push_back(Alias);
diff --git a/llvm/lib/Object/RecordStreamer.h b/llvm/lib/Object/RecordStreamer.h
index 4d119091a3d..e1e23f260ac 100644
--- a/llvm/lib/Object/RecordStreamer.h
+++ b/llvm/lib/Object/RecordStreamer.h
@@ -54,7 +54,7 @@ public:
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
/// Record .symver aliases for later processing.
- void emitELFSymverDirective(MCSymbol *Alias,
+ void emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) override;
/// Return the map of .symver aliasee to associated aliases.
DenseMap<const MCSymbol *, std::vector<MCSymbol *>> &symverAliases() {
OpenPOWER on IntegriCloud