1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCAsmInfo.h" 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCObjectStreamer.h" 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h" 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCAssembler.h" 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCCodeEmitter.h" 1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCContext.h" 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCDwarf.h" 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCExpr.h" 1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCSymbol.h" 2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCAsmBackend.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, 2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman raw_ostream &OS, MCCodeEmitter *Emitter_) 2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman : MCStreamer(Context), 2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Assembler(new MCAssembler(Context, TAB, 2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman *Emitter_, *TAB.createObjectWriter(OS), 2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OS)), 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurSectionData(0) 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, 3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman raw_ostream &OS, MCCodeEmitter *Emitter_, 3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCAssembler *_Assembler) 3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0) 3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{ 3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanMCObjectStreamer::~MCObjectStreamer() { 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete &Assembler->getBackend(); 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete &Assembler->getEmitter(); 4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman delete &Assembler->getWriter(); 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman delete Assembler; 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanMCFragment *MCObjectStreamer::getCurrentFragment() const { 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(getCurrentSectionData() && "No current section!"); 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!getCurrentSectionData()->empty()) 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return &getCurrentSectionData()->getFragmentList().back(); 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanMCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!F) 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman F = new MCDataFragment(getCurrentSectionData()); 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return F; 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanconst MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Value->getKind()) { 6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MCExpr::Target: 6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler); 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MCExpr::Constant: 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MCExpr::Binary: { 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddValueSymbols(BE->getLHS()); 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddValueSymbols(BE->getRHS()); 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MCExpr::SymbolRef: 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MCExpr::Unary: 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Value; 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, 9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned AddrSpace) { 9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(AddrSpace == 0 && "Address space must be 0!"); 9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCDataFragment *DF = getOrCreateDataFragment(); 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Avoid fixups when possible. 9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t AbsValue; 9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) { 9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EmitIntValue(AbsValue, Size, AddrSpace); 10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DF->addFixup(MCFixup::Create(DF->getContents().size(), 10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Value, 10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCFixup::getKindForSize(Size, false))); 10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DF->getContents().resize(DF->getContents().size() + Size, 0); 10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { 10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCStreamer::EmitLabel(Symbol); 11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: This is wasteful, we don't necessarily need to create a data 11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // fragment. Instead, we should mark the symbol as pointing into the data 11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // fragment if it exists, otherwise we should just queue the label and set its 11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // fragment pointer when we emit the next fragment. 11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCDataFragment *F = getOrCreateDataFragment(); 11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SD.setFragment(F); 12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SD.setOffset(F->getContents().size()); 12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { 12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t IntValue; 12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EmitULEB128IntValue(IntValue); 12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Value = ForceExpAbs(Value); 13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman new MCLEBFragment(*Value, false, getCurrentSectionData()); 13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { 13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t IntValue; 13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EmitSLEB128IntValue(IntValue); 13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Value = ForceExpAbs(Value); 14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman new MCLEBFragment(*Value, true, getCurrentSectionData()); 14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCSymbol *Symbol) { 14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman report_fatal_error("This file format doesn't support weak aliases."); 14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCObjectStreamer::ChangeSection(const MCSection *Section) { 14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Section && "Cannot switch to a null section!"); 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurSectionData = &getAssembler().getOrCreateSectionData(*Section); 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCObjectStreamer::EmitInstruction(const MCInst &Inst) { 15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Scan for values. 15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = Inst.getNumOperands(); i--; ) 15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Inst.getOperand(i).isExpr()) 15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AddValueSymbols(Inst.getOperand(i).getExpr()); 15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getCurrentSectionData()->setHasInstructions(true); 16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Now that a machine instruction has been assembled into this section, make 16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // a line entry for any .loc directive that has been seen. 16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCLineEntry::Make(this, getCurrentSection()); 16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If this instruction doesn't need relaxation, just emit it as data. 16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) { 16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EmitInstToData(Inst); 16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Otherwise, if we are relaxing everything, relax the instruction as much as 17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // possible and emit it as data. 17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (getAssembler().getRelaxAll()) { 17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCInst Relaxed; 17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getAssembler().getBackend().RelaxInstruction(Inst, Relaxed); 17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman while (getAssembler().getBackend().MayNeedRelaxation(Relaxed)) 17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed); 17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EmitInstToData(Relaxed); 18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Otherwise emit to a separate fragment. 18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EmitInstToFragment(Inst); 18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) { 18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData()); 18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallString<128> Code; 19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman raw_svector_ostream VecOS(Code); 19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups()); 19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VecOS.flush(); 19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman IF->getCode().append(Code.begin(), Code.end()); 19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCSymbol *LastLabel, 19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCSymbol *Label, 20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned PointerSize) { 20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!LastLabel) { 20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); 20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t Res; 20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCDwarfLineAddr::Emit(this, LineDelta, Res); 20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AddrDelta = ForceExpAbs(AddrDelta); 21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData()); 21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCSymbol *Label) { 21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t Res; 21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); 22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AddrDelta = ForceExpAbs(AddrDelta); 22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData()); 22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, 22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned char Value) { 22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int64_t Res; 23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Offset->EvaluateAsAbsolute(Res, getAssembler())) { 23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman new MCOrgFragment(*Offset, Value, getCurrentSectionData()); 23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *CurrentPos = getContext().CreateTempSymbol(); 23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EmitLabel(CurrentPos); 23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCExpr *Ref = 23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbolRefExpr::Create(CurrentPos, Variant, getContext()); 24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCExpr *Delta = 24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext()); 24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!Delta->EvaluateAsAbsolute(Res, getAssembler())) 24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman report_fatal_error("expected assembly-time absolute expression"); 24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EmitFill(Res, Value, 0); 24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid MCObjectStreamer::Finish() { 24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Dump out the dwarf file & directory tables and line tables. 25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (getContext().hasDwarfFiles()) 25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCDwarfFileTable::Emit(this); 25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getAssembler().Finish(); 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 255