MCObjectStreamer.cpp revision ed708f9c1facb9928ef2f79503e7030c8f25b00d
18dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===// 28dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// 38dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// The LLVM Compiler Infrastructure 48dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// 58dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// This file is distributed under the University of Illinois Open Source 68dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// License. See LICENSE.TXT for details. 78dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// 88dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//===----------------------------------------------------------------------===// 98dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 10835439a397407e421263bd476e5b18bf787ffb6aRafael Espindola#include "llvm/MC/MCAsmInfo.h" 118dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCObjectStreamer.h" 128dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 138067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer#include "llvm/Support/ErrorHandling.h" 148dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCAssembler.h" 151abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer#include "llvm/MC/MCCodeEmitter.h" 1689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola#include "llvm/MC/MCContext.h" 17f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola#include "llvm/MC/MCDwarf.h" 188067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer#include "llvm/MC/MCExpr.h" 19ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola#include "llvm/MC/MCSymbol.h" 201abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer#include "llvm/Target/TargetAsmBackend.h" 2189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola#include "llvm/Target/TargetAsmInfo.h" 228dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarusing namespace llvm; 238dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 248dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel DunbarMCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, 25feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar raw_ostream &OS, MCCodeEmitter *Emitter_) 26feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar : MCStreamer(Context), 27feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar Assembler(new MCAssembler(Context, TAB, 28feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar *Emitter_, *TAB.createObjectWriter(OS), 29feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar OS)), 3083b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar CurSectionData(0) 318dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar{ 328dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar} 338dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 3401dff9646173fea0c38df4471f41272557ca831aJan SjödinMCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, 3501dff9646173fea0c38df4471f41272557ca831aJan Sjödin raw_ostream &OS, MCCodeEmitter *Emitter_, 3601dff9646173fea0c38df4471f41272557ca831aJan Sjödin MCAssembler *_Assembler) 3701dff9646173fea0c38df4471f41272557ca831aJan Sjödin : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0) 3801dff9646173fea0c38df4471f41272557ca831aJan Sjödin{ 3901dff9646173fea0c38df4471f41272557ca831aJan Sjödin} 4001dff9646173fea0c38df4471f41272557ca831aJan Sjödin 418dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel DunbarMCObjectStreamer::~MCObjectStreamer() { 421abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer delete &Assembler->getBackend(); 431abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer delete &Assembler->getEmitter(); 44feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar delete &Assembler->getWriter(); 458dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar delete Assembler; 468dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar} 4783b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar 488067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. SpencerMCFragment *MCObjectStreamer::getCurrentFragment() const { 498067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer assert(getCurrentSectionData() && "No current section!"); 508067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 518067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer if (!getCurrentSectionData()->empty()) 528067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer return &getCurrentSectionData()->getFragmentList().back(); 538067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 548067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer return 0; 558067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer} 568067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 578067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. SpencerMCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { 588067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 598067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer if (!F) 608067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer F = new MCDataFragment(getCurrentSectionData()); 618067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer return F; 628067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer} 638067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 648067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencerconst MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { 658067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer switch (Value->getKind()) { 667597212abced110723f2fee985a7d60557c092ecEvan Cheng case MCExpr::Target: 677597212abced110723f2fee985a7d60557c092ecEvan Cheng cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler); 687597212abced110723f2fee985a7d60557c092ecEvan Cheng break; 697597212abced110723f2fee985a7d60557c092ecEvan Cheng 708067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::Constant: 718067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 728067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 738067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::Binary: { 748067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 758067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer AddValueSymbols(BE->getLHS()); 768067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer AddValueSymbols(BE->getRHS()); 778067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 788067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer } 798067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 808067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::SymbolRef: 818067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 828067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 838067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 848067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::Unary: 858067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 868067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 878067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer } 888067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 898067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer return Value; 908067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer} 918067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 9289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindolavoid MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, 9389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola bool isPCRel, unsigned AddrSpace) { 946f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola assert(AddrSpace == 0 && "Address space must be 0!"); 956f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola MCDataFragment *DF = getOrCreateDataFragment(); 966f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola 976f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola // Avoid fixups when possible. 986f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola int64_t AbsValue; 99d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) { 1002df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola EmitIntValue(AbsValue, Size, AddrSpace); 1012df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola return; 1026f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola } 1032df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola DF->addFixup(MCFixup::Create(DF->getContents().size(), 104835439a397407e421263bd476e5b18bf787ffb6aRafael Espindola Value, 10589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola MCFixup::getKindForSize(Size, isPCRel))); 1062df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola DF->getContents().resize(DF->getContents().size() + Size, 0); 1076f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola} 1086f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola 109ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindolavoid MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { 110ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola MCStreamer::EmitLabel(Symbol); 111ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola 112ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 113ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola 114ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // FIXME: This is wasteful, we don't necessarily need to create a data 115ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // fragment. Instead, we should mark the symbol as pointing into the data 116ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // fragment if it exists, otherwise we should just queue the label and set its 117ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // fragment pointer when we emit the next fragment. 118ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola MCDataFragment *F = getOrCreateDataFragment(); 119ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 120ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola SD.setFragment(F); 121ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola SD.setOffset(F->getContents().size()); 122ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola} 123ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola 124d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindolastatic const MCExpr *ForceExpAbs(MCObjectStreamer *Streamer, 125d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola MCContext &Context, const MCExpr* Expr) { 126d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola if (Context.getAsmInfo().hasAggressiveSymbolFolding()) 127d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola return Expr; 128d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola 129d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola MCSymbol *ABS = Context.CreateTempSymbol(); 130d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola Streamer->EmitAssignment(ABS, Expr); 131d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola return MCSymbolRefExpr::Create(ABS, Context); 132d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola} 133d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola 134e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindolavoid MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { 135660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola int64_t IntValue; 136d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 137e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola EmitULEB128IntValue(IntValue); 138660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola return; 139660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola } 140d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola Value = ForceExpAbs(this, getContext(), Value); 1413ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola new MCLEBFragment(*Value, false, getCurrentSectionData()); 1423ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola} 1433ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola 144e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindolavoid MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { 145660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola int64_t IntValue; 146d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 147e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola EmitSLEB128IntValue(IntValue); 148660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola return; 149660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola } 150d88cac0a6e908a366f403b37725e765604bc15d3Rafael Espindola Value = ForceExpAbs(this, getContext(), Value); 1513ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola new MCLEBFragment(*Value, true, getCurrentSectionData()); 1523ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola} 1533ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola 154484291c27319668ad99cb87def000254357736fbRafael Espindolavoid MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 155484291c27319668ad99cb87def000254357736fbRafael Espindola const MCSymbol *Symbol) { 156484291c27319668ad99cb87def000254357736fbRafael Espindola report_fatal_error("This file format doesn't support weak aliases."); 157484291c27319668ad99cb87def000254357736fbRafael Espindola} 158484291c27319668ad99cb87def000254357736fbRafael Espindola 1597768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindolavoid MCObjectStreamer::ChangeSection(const MCSection *Section) { 16083b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar assert(Section && "Cannot switch to a null section!"); 16183b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar 16283b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar CurSectionData = &getAssembler().getOrCreateSectionData(*Section); 16383b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar} 16483b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar 165f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindolavoid MCObjectStreamer::EmitInstruction(const MCInst &Inst) { 166f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // Scan for values. 167f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola for (unsigned i = Inst.getNumOperands(); i--; ) 168f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola if (Inst.getOperand(i).isExpr()) 169f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola AddValueSymbols(Inst.getOperand(i).getExpr()); 170f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 171f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola getCurrentSectionData()->setHasInstructions(true); 172f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 173f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // Now that a machine instruction has been assembled into this section, make 174f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // a line entry for any .loc directive that has been seen. 175f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola MCLineEntry::Make(this, getCurrentSection()); 176f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 177f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // If this instruction doesn't need relaxation, just emit it as data. 178f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) { 179f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola EmitInstToData(Inst); 180f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola return; 181f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola } 182f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 183f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // Otherwise, if we are relaxing everything, relax the instruction as much as 184f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // possible and emit it as data. 185f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola if (getAssembler().getRelaxAll()) { 186f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola MCInst Relaxed; 187f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola getAssembler().getBackend().RelaxInstruction(Inst, Relaxed); 188f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola while (getAssembler().getBackend().MayNeedRelaxation(Relaxed)) 189f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed); 190f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola EmitInstToData(Relaxed); 191f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola return; 192f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola } 193f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 194f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // Otherwise emit to a separate fragment. 195f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola EmitInstToFragment(Inst); 196f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola} 197f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 198dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindolavoid MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) { 199dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData()); 200dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola 20150ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman SmallString<128> Code; 20250ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman raw_svector_ostream VecOS(Code); 203dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups()); 20450ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman VecOS.flush(); 20550ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman IF->getCode().append(Code.begin(), Code.end()); 206dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola} 207dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola 208245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindolastatic const MCExpr *BuildSymbolDiff(MCContext &Context, 209245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCSymbol *A, const MCSymbol *B) { 210245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 211245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCExpr *ARef = 212245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola MCSymbolRefExpr::Create(A, Variant, Context); 213245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCExpr *BRef = 214245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola MCSymbolRefExpr::Create(B, Variant, Context); 215245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCExpr *AddrDelta = 216245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context); 217245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola return AddrDelta; 218245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola} 219245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola 22032a006e606742b1c5401e49607e33717bb5441f0Rafael Espindolavoid MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 22132a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola const MCSymbol *LastLabel, 22232a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola const MCSymbol *Label) { 22332a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola if (!LastLabel) { 22489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola int PointerSize = getContext().getTargetAsmInfo().getPointerSize(); 22532a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); 22632a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola return; 22732a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola } 228245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 22932a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola int64_t Res; 230d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 23132a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola MCDwarfLineAddr::Emit(this, LineDelta, Res); 23232a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola return; 23332a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola } 234245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola AddrDelta = ForceExpAbs(this, getContext(), AddrDelta); 23532a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData()); 23632a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola} 23732a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola 238245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindolavoid MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 239245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCSymbol *Label) { 240245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 241245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola int64_t Res; 242245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 243245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); 244245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola return; 245245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola } 246245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola AddrDelta = ForceExpAbs(this, getContext(), AddrDelta); 247245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData()); 248245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola} 249245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola 250e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindolavoid MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, 251e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola unsigned char Value) { 252f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola int64_t Res; 253f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola if (Offset->EvaluateAsAbsolute(Res, getAssembler())) { 254f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola new MCOrgFragment(*Offset, Value, getCurrentSectionData()); 255f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola return; 256f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola } 257f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola 258f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCSymbol *CurrentPos = getContext().CreateTempSymbol(); 259f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola EmitLabel(CurrentPos); 260f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 261f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola const MCExpr *Ref = 262f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCSymbolRefExpr::Create(CurrentPos, Variant, getContext()); 263f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola const MCExpr *Delta = 264f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext()); 265f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola 266f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola if (!Delta->EvaluateAsAbsolute(Res, getAssembler())) 267f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola report_fatal_error("expected assembly-time absolute expression"); 268f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola EmitFill(Res, Value, 0); 269e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola} 270e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola 27183b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbarvoid MCObjectStreamer::Finish() { 27289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Dump out the dwarf file & directory tables and line tables. 27389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola if (getContext().hasDwarfFiles()) 27489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola MCDwarfFileTable::Emit(this); 27589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 27683b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar getAssembler().Finish(); 27783b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar} 278