diff options
Diffstat (limited to 'lib/MC/MCELFStreamer.cpp')
-rw-r--r-- | lib/MC/MCELFStreamer.cpp | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 8b9bdb14a0..b24deb9c51 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -12,11 +12,15 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCELFStreamer.h" + +#include "MCELF.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Twine.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" -#include "llvm/MC/MCELF.h" #include "llvm/MC/MCELFSymbolFlags.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" @@ -32,7 +36,6 @@ using namespace llvm; - inline void MCELFStreamer::SetSection(StringRef Section, unsigned Type, unsigned Flags, SectionKind Kind) { SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind)); @@ -100,6 +103,23 @@ void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { llvm_unreachable("invalid assembler flag!"); } +void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { + // FIXME: Anything needed here to flag the function as thumb? + + getAssembler().setIsThumbFunc(Func); + + MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func); + SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc); +} + +void MCELFStreamer::EmitAssignment(MCSymbol* Symbol, const MCExpr* Value) { + // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into + // MCObjectStreamer. + // FIXME: Lift context changes into super class. + getAssembler().getOrCreateSymbolData(*Symbol); + Symbol->setVariableValue(AddValueSymbols(Value)); +} + void MCELFStreamer::ChangeSection(const MCSection *Section) { const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup(); if (Grp) @@ -260,6 +280,7 @@ void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, unsigned AddrSpace) { fixSymbolsInTLSFixups(Value); MCObjectStreamer::EmitValueImpl(Value, Size, AddrSpace); + getCurrentSectionData()->MarkBundleOffsetUnknown(); // @LOCALMOD } @@ -328,10 +349,10 @@ void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) { for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i) fixSymbolsInTLSFixups(F.getFixups()[i].getValue()); + getCurrentSectionData()->MarkBundleOffsetUnknown(); // @LOCALMOD } void MCELFStreamer::EmitInstToData(const MCInst &Inst) { - MCDataFragment *DF = getOrCreateDataFragment(); SmallVector<MCFixup, 4> Fixups; SmallString<256> Code; @@ -342,12 +363,30 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) { for (unsigned i = 0, e = Fixups.size(); i != e; ++i) fixSymbolsInTLSFixups(Fixups[i].getValue()); - // Add the fixups and data. - for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { - Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); - DF->getFixups().push_back(Fixups[i]); + // @LOCALMOD-BEGIN + MCSectionData *SD = getCurrentSectionData(); + + if (Fixups.size() > 0 || !SD->isBundlingEnabled()) { + MCDataFragment *DF; + if (SD->isBundlingEnabled()) + DF = new MCDataFragment(SD); + else + DF = getOrCreateDataFragment(); + + // Add the fixups and data. + for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { + Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); + DF->addFixup(Fixups[i]); + } + DF->getContents().append(Code.begin(), Code.end()); + } else { + MCTinyFragment *TF = dyn_cast_or_null<MCTinyFragment>(getCurrentFragment()); + if (!TF || SD->ShouldCreateNewFragment(Code.size())) + TF = new MCTinyFragment(SD); + TF->getContents().append(Code.begin(), Code.end()); } - DF->getContents().append(Code.begin(), Code.end()); + SD->UpdateBundleOffset(Code.size()); + // @LOCALMOD-END } void MCELFStreamer::FinishImpl() { @@ -375,7 +414,9 @@ void MCELFStreamer::FinishImpl() { this->MCObjectStreamer::FinishImpl(); } -void MCELFStreamer::EmitTCEntry(const MCSymbol &S) { + +void MCELFStreamer::EmitTCEntry(const MCSymbol &S) +{ // Creates a R_PPC64_TOC relocation MCObjectStreamer::EmitSymbolValue(&S, 8, 0); } @@ -391,10 +432,6 @@ MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB, return S; } -void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { - llvm_unreachable("Generic ELF doesn't support this directive"); -} - void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { llvm_unreachable("ELF doesn't support this directive"); } |