mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
Delay creating an alias for @@@.
With this we only create an alias for @@@ once we know if it should use @ or @@. This avoids last minutes renames and hacks to handle MS names. This only handles the ELF writer. LTO still has issues with @@@ aliases. llvm-svn: 327160
This commit is contained in:
parent
b899b52c84
commit
623d19e403
@ -206,6 +206,8 @@ private:
|
||||
handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup);
|
||||
|
||||
public:
|
||||
std::vector<std::pair<StringRef, const MCSymbol *>> Symvers;
|
||||
|
||||
/// Construct a new assembler instance.
|
||||
//
|
||||
// FIXME: How are we going to parameterize this? Two obvious options are stay
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
unsigned ByteAlignment) override;
|
||||
|
||||
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
|
||||
void emitELFSymverDirective(MCSymbol *Alias,
|
||||
void emitELFSymverDirective(StringRef AliasName,
|
||||
const MCSymbol *Aliasee) override;
|
||||
|
||||
void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
|
@ -525,9 +525,10 @@ public:
|
||||
///
|
||||
/// This corresponds to an assembler statement such as:
|
||||
/// .symver _start, foo@@SOME_VERSION
|
||||
/// \param Alias - The versioned alias (i.e. "foo@@SOME_VERSION")
|
||||
/// \param AliasName - The versioned alias (i.e. "foo@@SOME_VERSION")
|
||||
/// \param Aliasee - The aliased symbol (i.e. "_start")
|
||||
virtual void emitELFSymverDirective(MCSymbol *Alias, const MCSymbol *Aliasee);
|
||||
virtual void emitELFSymverDirective(StringRef AliasName,
|
||||
const MCSymbol *Aliasee);
|
||||
|
||||
/// \brief Emit a Linker Optimization Hint (LOH) directive.
|
||||
/// \param Args - Arguments of the LOH.
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {}
|
||||
|
@ -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);
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user