diff options
Diffstat (limited to 'contrib/llvm/lib/MC/MCELFStreamer.cpp')
-rw-r--r-- | contrib/llvm/lib/MC/MCELFStreamer.cpp | 122 |
1 files changed, 82 insertions, 40 deletions
diff --git a/contrib/llvm/lib/MC/MCELFStreamer.cpp b/contrib/llvm/lib/MC/MCELFStreamer.cpp index 116f86feb8a5..e806cb9f1c94 100644 --- a/contrib/llvm/lib/MC/MCELFStreamer.cpp +++ b/contrib/llvm/lib/MC/MCELFStreamer.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCELF.h" @@ -96,6 +97,9 @@ void MCELFStreamer::EmitDebugLabel(MCSymbol *Symbol) { } void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { + // Let the target do whatever target specific stuff it needs to do. + getAssembler().getBackend().handleAssemblerFlag(Flag); + // Do any generic stuff we need to do. switch (Flag) { case MCAF_SyntaxUnified: return; // no-op here. case MCAF_Code16: return; // Change parsing mode; no-op here. @@ -148,8 +152,8 @@ static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) { return T2; } -void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, - MCSymbolAttr Attribute) { +bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, + MCSymbolAttr Attribute) { // Indirect symbols are handled differently, to match how 'as' handles // them. This makes writing matching .o files easier. if (Attribute == MCSA_IndirectSymbol) { @@ -159,7 +163,7 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, ISD.Symbol = Symbol; ISD.SectionData = getCurrentSectionData(); getAssembler().getIndirectSymbols().push_back(ISD); - return; + return true; } // Adding a symbol attribute always introduces the symbol, note that an @@ -182,7 +186,7 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_WeakDefAutoPrivate: case MCSA_Invalid: case MCSA_IndirectSymbol: - llvm_unreachable("Invalid symbol attribute for ELF!"); + return false; case MCSA_NoDeadStrip: case MCSA_ELF_TypeGnuUniqueObject: @@ -251,6 +255,8 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, MCELF::SetVisibility(SD, ELF::STV_INTERNAL); break; } + + return true; } void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, @@ -270,7 +276,8 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, ELF::SHF_WRITE | ELF::SHF_ALLOC, SectionKind::getBSS()); - Symbol->setSection(*Section); + + AssignSection(Symbol, Section); struct LocalCommon L = {&SD, Size, ByteAlignment}; LocalCommons.push_back(L); @@ -296,12 +303,11 @@ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, EmitCommonSymbol(Symbol, Size, ByteAlignment); } -void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, - unsigned AddrSpace) { +void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { if (getCurrentSectionData()->isBundleLocked()) report_fatal_error("Emitting values inside a locked bundle is forbidden"); fixSymbolsInTLSFixups(Value); - MCObjectStreamer::EmitValueImpl(Value, Size, AddrSpace); + MCObjectStreamer::EmitValueImpl(Value, Size); } void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, @@ -314,20 +320,29 @@ void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, ValueSize, MaxBytesToEmit); } - -// Add a symbol for the file name of this module. This is the second -// entry in the module's symbol table (the first being the null symbol). +// Add a symbol for the file name of this module. They start after the +// null symbol and don't count as normal symbol, i.e. a non-STT_FILE symbol +// with the same name may appear. void MCELFStreamer::EmitFileDirective(StringRef Filename) { - MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename); - Symbol->setSection(*getCurrentSection().first); - Symbol->setAbsolute(); - - MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); - - SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default); + getAssembler().addFileName(Filename); +} + +void MCELFStreamer::EmitIdent(StringRef IdentString) { + const MCSection *Comment = getAssembler().getContext().getELFSection( + ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, + SectionKind::getReadOnly(), 1, ""); + PushSection(); + SwitchSection(Comment); + if (!SeenIdent) { + EmitIntValue(0, 1); + SeenIdent = true; + } + EmitBytes(IdentString); + EmitIntValue(0, 1); + PopSection(); } -void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { +void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { switch (expr->getKind()) { case MCExpr::Target: cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(getAssembler()); @@ -363,18 +378,41 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { case MCSymbolRefExpr::VK_Mips_GOTTPREL: case MCSymbolRefExpr::VK_Mips_TPREL_HI: case MCSymbolRefExpr::VK_Mips_TPREL_LO: - case MCSymbolRefExpr::VK_PPC_TPREL16_HA: - case MCSymbolRefExpr::VK_PPC_TPREL16_LO: - case MCSymbolRefExpr::VK_PPC_DTPREL16_HA: - case MCSymbolRefExpr::VK_PPC_DTPREL16_LO: - case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA: - case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO: + case MCSymbolRefExpr::VK_PPC_DTPMOD: + case MCSymbolRefExpr::VK_PPC_TPREL: + case MCSymbolRefExpr::VK_PPC_TPREL_LO: + case MCSymbolRefExpr::VK_PPC_TPREL_HI: + case MCSymbolRefExpr::VK_PPC_TPREL_HA: + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: + case MCSymbolRefExpr::VK_PPC_DTPREL: + case MCSymbolRefExpr::VK_PPC_DTPREL_LO: + case MCSymbolRefExpr::VK_PPC_DTPREL_HI: + case MCSymbolRefExpr::VK_PPC_DTPREL_HA: + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: + case MCSymbolRefExpr::VK_PPC_GOT_TPREL: + case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: + case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: + case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: case MCSymbolRefExpr::VK_PPC_TLS: - case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA: - case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO: + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: case MCSymbolRefExpr::VK_PPC_TLSGD: - case MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA: - case MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO: + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: case MCSymbolRefExpr::VK_PPC_TLSLD: break; } @@ -503,9 +541,7 @@ void MCELFStreamer::EmitBundleUnlock() { SD->setBundleLockState(MCSectionData::NotBundleLocked); } -void MCELFStreamer::FinishImpl() { - EmitFrames(true); - +void MCELFStreamer::Flush() { for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), e = LocalCommons.end(); i != e; ++i) { @@ -526,17 +562,23 @@ void MCELFStreamer::FinishImpl() { SectData.setAlignment(ByteAlignment); } - this->MCObjectStreamer::FinishImpl(); + LocalCommons.clear(); } -void MCELFStreamer::EmitTCEntry(const MCSymbol &S) { - // Creates a R_PPC64_TOC relocation - MCObjectStreamer::EmitSymbolValue(&S, 8); + +void MCELFStreamer::FinishImpl() { + EmitFrames(NULL, true); + + Flush(); + + this->MCObjectStreamer::FinishImpl(); } -MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB, - raw_ostream &OS, MCCodeEmitter *CE, - bool RelaxAll, bool NoExecStack) { - MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE); +MCStreamer *llvm::createELFStreamer(MCContext &Context, + MCTargetStreamer *Streamer, + MCAsmBackend &MAB, raw_ostream &OS, + MCCodeEmitter *CE, bool RelaxAll, + bool NoExecStack) { + MCELFStreamer *S = new MCELFStreamer(Context, Streamer, MAB, OS, CE); if (RelaxAll) S->getAssembler().setRelaxAll(true); if (NoExecStack) |