#define DEBUG_TYPE "WinCOFFStreamer"
-#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCValue.h"
-#include "llvm/MC/MCAssembler.h"
-#include "llvm/MC/MCAsmLayout.h"
-#include "llvm/MC/MCCodeEmitter.h"
-#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCWin64EH.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetAsmBackend.h"
-#include "llvm/ADT/StringMap.h"
-
#include "llvm/Support/COFF.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
+
using namespace llvm;
namespace {
MCSymbol const *CurSymbol;
WinCOFFStreamer(MCContext &Context,
- TargetAsmBackend &TAB,
+ MCAsmBackend &MAB,
MCCodeEmitter &CE,
raw_ostream &OS);
virtual void InitSections();
virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
virtual void EmitThumbFunc(MCSymbol *Func);
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitCOFFSymbolStorageClass(int StorageClass);
virtual void EmitCOFFSymbolType(int Type);
virtual void EndCOFFSymbolDef();
+ virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size);
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment);
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
- unsigned Size,unsigned ByteAlignment);
+ uint64_t Size,unsigned ByteAlignment);
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment);
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
- virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
- unsigned ValueSize, unsigned MaxBytesToEmit);
- virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit);
virtual void EmitFileDirective(StringRef Filename);
- virtual void EmitInstruction(const MCInst &Instruction);
virtual void EmitWin64EHHandlerData();
- virtual void Finish();
+ virtual void FinishImpl();
private:
- virtual void EmitInstToFragment(const MCInst &Inst) {
- llvm_unreachable("Not used by WinCOFF.");
- }
virtual void EmitInstToData(const MCInst &Inst) {
- llvm_unreachable("Not used by WinCOFF.");
+ MCDataFragment *DF = getOrCreateDataFragment();
+
+ SmallVector<MCFixup, 4> Fixups;
+ SmallString<256> Code;
+ raw_svector_ostream VecOS(Code);
+ getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
+ VecOS.flush();
+
+ // 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]);
+ }
+ DF->getContents().append(Code.begin(), Code.end());
}
void SetSection(StringRef Section,
SectionKind::getBSS());
EmitCodeAlignment(4, 0);
}
-
};
} // end anonymous namespace.
WinCOFFStreamer::WinCOFFStreamer(MCContext &Context,
- TargetAsmBackend &TAB,
+ MCAsmBackend &MAB,
MCCodeEmitter &CE,
raw_ostream &OS)
- : MCObjectStreamer(Context, TAB, OS, &CE)
+ : MCObjectStreamer(Context, MAB, OS, &CE)
, CurSymbol(NULL) {
}
MCObjectStreamer::EmitLabel(Symbol);
}
+void WinCOFFStreamer::EmitDebugLabel(MCSymbol *Symbol) {
+ EmitLabel(Symbol);
+}
void WinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
llvm_unreachable("not implemented");
}
// don't really even do.
if (Value->getKind() != MCExpr::SymbolRef) {
- // TODO: This is exactly the same as MachOStreamer. Consider merging into
- // MCObjectStreamer.
- getAssembler().getOrCreateSymbolData(*Symbol);
- AddValueSymbols(Value);
- Symbol->setVariableValue(Value);
+ MCObjectStreamer::EmitAssignment(Symbol, Value);
} else {
// FIXME: This is a horrible way to do this :(. This should really be
// handled after we are done with the MC* objects and immediately before
default:
llvm_unreachable("unsupported attribute");
- break;
}
}
CurSymbol = NULL;
}
+void WinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol)
+{
+ MCDataFragment *DF = getOrCreateDataFragment();
+
+ DF->getFixups().push_back(
+ MCFixup::Create(DF->getContents().size(),
+ MCSymbolRefExpr::Create (Symbol, getContext ()),
+ FK_SecRel_4));
+ DF->getContents().resize(DF->getContents().size() + 4, 0);
+}
+
void WinCOFFStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
llvm_unreachable("not implemented");
}
AddCommonSymbol(Symbol, Size, ByteAlignment, true);
}
-void WinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
+void WinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) {
assert((Symbol->isInSection()
? Symbol->getSection().getVariant() == MCSection::SV_COFF
: true) && "Got non COFF section in the COFF backend!");
- AddCommonSymbol(Symbol, Size, 1, false);
+ AddCommonSymbol(Symbol, Size, ByteAlignment, false);
}
void WinCOFFStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
- unsigned Size,unsigned ByteAlignment) {
+ uint64_t Size,unsigned ByteAlignment) {
llvm_unreachable("not implemented");
}
llvm_unreachable("not implemented");
}
-void WinCOFFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
- // TODO: This is copied exactly from the MachOStreamer. Consider merging into
- // MCObjectStreamer?
- getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
-}
-
-void WinCOFFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
- int64_t Value,
- unsigned ValueSize,
- unsigned MaxBytesToEmit) {
- // TODO: This is copied exactly from the MachOStreamer. Consider merging into
- // MCObjectStreamer?
- if (MaxBytesToEmit == 0)
- MaxBytesToEmit = ByteAlignment;
- new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
- getCurrentSectionData());
-
- // Update the maximum alignment on the current section if necessary.
- if (ByteAlignment > getCurrentSectionData()->getAlignment())
- getCurrentSectionData()->setAlignment(ByteAlignment);
-}
-
-void WinCOFFStreamer::EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit) {
- // TODO: This is copied exactly from the MachOStreamer. Consider merging into
- // MCObjectStreamer?
- if (MaxBytesToEmit == 0)
- MaxBytesToEmit = ByteAlignment;
- MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
- getCurrentSectionData());
- F->setEmitNops(true);
-
- // Update the maximum alignment on the current section if necessary.
- if (ByteAlignment > getCurrentSectionData()->getAlignment())
- getCurrentSectionData()->setAlignment(ByteAlignment);
-}
-
void WinCOFFStreamer::EmitFileDirective(StringRef Filename) {
// Ignore for now, linkers don't care, and proper debug
// info will be a much large effort.
}
-void WinCOFFStreamer::EmitInstruction(const MCInst &Instruction) {
- for (unsigned i = 0, e = Instruction.getNumOperands(); i != e; ++i)
- if (Instruction.getOperand(i).isExpr())
- AddValueSymbols(Instruction.getOperand(i).getExpr());
-
- getCurrentSectionData()->setHasInstructions(true);
-
- MCInstFragment *Fragment =
- new MCInstFragment(Instruction, getCurrentSectionData());
-
- raw_svector_ostream VecOS(Fragment->getCode());
-
- getAssembler().getEmitter().EncodeInstruction(Instruction, VecOS,
- Fragment->getFixups());
-}
-
void WinCOFFStreamer::EmitWin64EHHandlerData() {
MCStreamer::EmitWin64EHHandlerData();
MCWin64EHUnwindEmitter::EmitUnwindInfo(*this, getCurrentW64UnwindInfo());
}
-void WinCOFFStreamer::Finish() {
+void WinCOFFStreamer::FinishImpl() {
EmitW64Tables();
- MCObjectStreamer::Finish();
+ MCObjectStreamer::FinishImpl();
}
namespace llvm
{
MCStreamer *createWinCOFFStreamer(MCContext &Context,
- TargetAsmBackend &TAB,
+ MCAsmBackend &MAB,
MCCodeEmitter &CE,
raw_ostream &OS,
bool RelaxAll) {
- WinCOFFStreamer *S = new WinCOFFStreamer(Context, TAB, CE, OS);
+ WinCOFFStreamer *S = new WinCOFFStreamer(Context, MAB, CE, OS);
S->getAssembler().setRelaxAll(RelaxAll);
return S;
}