MCObjectStreamer.cpp revision 64d9a3233476553fc950f0f2fc6a2cdd2a4c05cf
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 108dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCObjectStreamer.h" 11f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCAsmBackend.h" 12f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCAsmInfo.h" 138dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCAssembler.h" 141abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer#include "llvm/MC/MCCodeEmitter.h" 1589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola#include "llvm/MC/MCContext.h" 16f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola#include "llvm/MC/MCDwarf.h" 178067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer#include "llvm/MC/MCExpr.h" 18f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCObjectWriter.h" 19ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola#include "llvm/MC/MCSymbol.h" 20f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/Support/ErrorHandling.h" 218dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarusing namespace llvm; 228dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 2378c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan ChengMCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, 24feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar raw_ostream &OS, MCCodeEmitter *Emitter_) 25feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar : MCStreamer(Context), 26feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar Assembler(new MCAssembler(Context, TAB, 27feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar *Emitter_, *TAB.createObjectWriter(OS), 28feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar OS)), 2983b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar CurSectionData(0) 308dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar{ 318dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar} 328dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar 3378c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan ChengMCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, 3401dff9646173fea0c38df4471f41272557ca831aJan Sjödin raw_ostream &OS, MCCodeEmitter *Emitter_, 3501dff9646173fea0c38df4471f41272557ca831aJan Sjödin MCAssembler *_Assembler) 3601dff9646173fea0c38df4471f41272557ca831aJan Sjödin : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0) 3701dff9646173fea0c38df4471f41272557ca831aJan Sjödin{ 3801dff9646173fea0c38df4471f41272557ca831aJan Sjödin} 3901dff9646173fea0c38df4471f41272557ca831aJan Sjödin 408dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel DunbarMCObjectStreamer::~MCObjectStreamer() { 411abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer delete &Assembler->getBackend(); 421abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer delete &Assembler->getEmitter(); 43feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar delete &Assembler->getWriter(); 448dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar delete Assembler; 458dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar} 4683b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar 478067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. SpencerMCFragment *MCObjectStreamer::getCurrentFragment() const { 488067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer assert(getCurrentSectionData() && "No current section!"); 498067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 508067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer if (!getCurrentSectionData()->empty()) 518067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer return &getCurrentSectionData()->getFragmentList().back(); 528067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 538067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer return 0; 548067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer} 558067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 568067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. SpencerMCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { 578067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 588067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer if (!F) 598067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer F = new MCDataFragment(getCurrentSectionData()); 608067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer return F; 618067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer} 628067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 638067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencerconst MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { 648067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer switch (Value->getKind()) { 657597212abced110723f2fee985a7d60557c092ecEvan Cheng case MCExpr::Target: 667597212abced110723f2fee985a7d60557c092ecEvan Cheng cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler); 677597212abced110723f2fee985a7d60557c092ecEvan Cheng break; 687597212abced110723f2fee985a7d60557c092ecEvan Cheng 698067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::Constant: 708067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 718067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 728067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::Binary: { 738067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 748067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer AddValueSymbols(BE->getLHS()); 758067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer AddValueSymbols(BE->getRHS()); 768067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 778067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer } 788067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 798067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::SymbolRef: 808067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 818067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 828067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 838067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer case MCExpr::Unary: 848067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 858067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer break; 868067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer } 878067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 888067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer return Value; 898067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer} 908067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer 9189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindolavoid MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, 92debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola unsigned AddrSpace) { 936f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola assert(AddrSpace == 0 && "Address space must be 0!"); 946f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola MCDataFragment *DF = getOrCreateDataFragment(); 956f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola 966f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola // Avoid fixups when possible. 976f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola int64_t AbsValue; 98d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) { 992df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola EmitIntValue(AbsValue, Size, AddrSpace); 1002df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola return; 1016f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola } 10264d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky DF->getFixups().push_back( 10364d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky MCFixup::Create(DF->getContents().size(), Value, 10464d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky MCFixup::getKindForSize(Size, false))); 1052df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola DF->getContents().resize(DF->getContents().size() + Size, 0); 1066f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola} 1076f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola 108547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindolavoid MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 109547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindola RecordProcStart(Frame); 110547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindola} 111547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindola 1121fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindolavoid MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 1131fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindola RecordProcEnd(Frame); 1141fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindola} 1151fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindola 116ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindolavoid MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { 117ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola MCStreamer::EmitLabel(Symbol); 118ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola 119ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 120ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola 121ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // FIXME: This is wasteful, we don't necessarily need to create a data 122ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // fragment. Instead, we should mark the symbol as pointing into the data 123ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // fragment if it exists, otherwise we should just queue the label and set its 124ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola // fragment pointer when we emit the next fragment. 125ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola MCDataFragment *F = getOrCreateDataFragment(); 126ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 127ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola SD.setFragment(F); 128ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola SD.setOffset(F->getContents().size()); 129ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola} 130ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola 131e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindolavoid MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { 132660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola int64_t IntValue; 133d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 134e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola EmitULEB128IntValue(IntValue); 135660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola return; 136660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola } 137a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola Value = ForceExpAbs(Value); 1383ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola new MCLEBFragment(*Value, false, getCurrentSectionData()); 1393ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola} 1403ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola 141e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindolavoid MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { 142660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola int64_t IntValue; 143d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 144e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola EmitSLEB128IntValue(IntValue); 145660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola return; 146660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola } 147a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola Value = ForceExpAbs(Value); 1483ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola new MCLEBFragment(*Value, true, getCurrentSectionData()); 1493ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola} 1503ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola 151484291c27319668ad99cb87def000254357736fbRafael Espindolavoid MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 152484291c27319668ad99cb87def000254357736fbRafael Espindola const MCSymbol *Symbol) { 153484291c27319668ad99cb87def000254357736fbRafael Espindola report_fatal_error("This file format doesn't support weak aliases."); 154484291c27319668ad99cb87def000254357736fbRafael Espindola} 155484291c27319668ad99cb87def000254357736fbRafael Espindola 1567768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindolavoid MCObjectStreamer::ChangeSection(const MCSection *Section) { 15783b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar assert(Section && "Cannot switch to a null section!"); 15883b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar 15983b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar CurSectionData = &getAssembler().getOrCreateSectionData(*Section); 16083b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar} 16183b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar 162ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Benderskyvoid MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 163ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky getAssembler().getOrCreateSymbolData(*Symbol); 164ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky Symbol->setVariableValue(AddValueSymbols(Value)); 165ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky} 166ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky 167f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindolavoid MCObjectStreamer::EmitInstruction(const MCInst &Inst) { 168f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // Scan for values. 169f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola for (unsigned i = Inst.getNumOperands(); i--; ) 170f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola if (Inst.getOperand(i).isExpr()) 171f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola AddValueSymbols(Inst.getOperand(i).getExpr()); 172f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 173f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola getCurrentSectionData()->setHasInstructions(true); 174f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 175f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // Now that a machine instruction has been assembled into this section, make 176f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // a line entry for any .loc directive that has been seen. 177f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola MCLineEntry::Make(this, getCurrentSection()); 178f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 179f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // If this instruction doesn't need relaxation, just emit it as data. 180ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach if (!getAssembler().getBackend().mayNeedRelaxation(Inst)) { 181f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola EmitInstToData(Inst); 182f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola return; 183f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola } 184f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 185f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // Otherwise, if we are relaxing everything, relax the instruction as much as 186f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // possible and emit it as data. 187f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola if (getAssembler().getRelaxAll()) { 188f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola MCInst Relaxed; 189ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach getAssembler().getBackend().relaxInstruction(Inst, Relaxed); 190ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach while (getAssembler().getBackend().mayNeedRelaxation(Relaxed)) 191ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed); 192f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola EmitInstToData(Relaxed); 193f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola return; 194f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola } 195f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 196f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola // Otherwise emit to a separate fragment. 197f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola EmitInstToFragment(Inst); 198f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola} 199f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola 200dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindolavoid MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) { 201dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData()); 202dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola 20350ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman SmallString<128> Code; 20450ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman raw_svector_ostream VecOS(Code); 205dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups()); 20650ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman VecOS.flush(); 20764d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky IF->getContents().append(Code.begin(), Code.end()); 208dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola} 209dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola 21032a006e606742b1c5401e49607e33717bb5441f0Rafael Espindolavoid MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 21132a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola const MCSymbol *LastLabel, 212672b93a3324cc1da6d374eed4c75c050a9cad7beEvan Cheng const MCSymbol *Label, 213672b93a3324cc1da6d374eed4c75c050a9cad7beEvan Cheng unsigned PointerSize) { 21432a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola if (!LastLabel) { 21532a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); 21632a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola return; 21732a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola } 218245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 21932a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola int64_t Res; 220d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 22132a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola MCDwarfLineAddr::Emit(this, LineDelta, Res); 22232a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola return; 22332a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola } 224a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola AddrDelta = ForceExpAbs(AddrDelta); 22532a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData()); 22632a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola} 22732a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola 228245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindolavoid MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 229245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCSymbol *Label) { 230245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 231245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola int64_t Res; 232245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 233245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); 234245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola return; 235245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola } 236a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola AddrDelta = ForceExpAbs(AddrDelta); 237245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData()); 238245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola} 239245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola 240e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramervoid MCObjectStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 241e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer assert(AddrSpace == 0 && "Address space must be 0!"); 242e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 243e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer} 244e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer 245e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramervoid MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, 246e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer int64_t Value, 247e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer unsigned ValueSize, 248e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer unsigned MaxBytesToEmit) { 249e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer if (MaxBytesToEmit == 0) 250e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer MaxBytesToEmit = ByteAlignment; 251e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 252e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer getCurrentSectionData()); 253e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer 254e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer // Update the maximum alignment on the current section if necessary. 255e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer if (ByteAlignment > getCurrentSectionData()->getAlignment()) 256e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer getCurrentSectionData()->setAlignment(ByteAlignment); 257e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer} 258e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer 259e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramervoid MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment, 260e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer unsigned MaxBytesToEmit) { 261e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit); 262e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true); 263e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer} 264e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer 265ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbachbool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, 266660a4d9e0a15ad25db10d25a1a8caeafc0ebad5eJim Grosbach unsigned char Value) { 267f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola int64_t Res; 268f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola if (Offset->EvaluateAsAbsolute(Res, getAssembler())) { 269f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola new MCOrgFragment(*Offset, Value, getCurrentSectionData()); 270ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbach return false; 271f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola } 272f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola 273f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCSymbol *CurrentPos = getContext().CreateTempSymbol(); 274f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola EmitLabel(CurrentPos); 275f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 276f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola const MCExpr *Ref = 277f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCSymbolRefExpr::Create(CurrentPos, Variant, getContext()); 278f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola const MCExpr *Delta = 279f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext()); 280f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola 281f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola if (!Delta->EvaluateAsAbsolute(Res, getAssembler())) 282ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbach return true; 283f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola EmitFill(Res, Value, 0); 284ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbach return false; 285e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola} 286e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola 28784bfc2f090639f933df06cc675c4385511516befAkira Hatanaka// Associate GPRel32 fixup with data and resize data area 28884bfc2f090639f933df06cc675c4385511516befAkira Hatanakavoid MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { 28984bfc2f090639f933df06cc675c4385511516befAkira Hatanaka MCDataFragment *DF = getOrCreateDataFragment(); 29084bfc2f090639f933df06cc675c4385511516befAkira Hatanaka 29164d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 29264d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky Value, FK_GPRel_4)); 29384bfc2f090639f933df06cc675c4385511516befAkira Hatanaka DF->getContents().resize(DF->getContents().size() + 4, 0); 29484bfc2f090639f933df06cc675c4385511516befAkira Hatanaka} 29584bfc2f090639f933df06cc675c4385511516befAkira Hatanaka 296101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter// Associate GPRel32 fixup with data and resize data area 297101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Cartervoid MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { 298101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter MCDataFragment *DF = getOrCreateDataFragment(); 299101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter 30064d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 30164d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky Value, FK_GPRel_4)); 302101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter DF->getContents().resize(DF->getContents().size() + 8, 0); 303101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter} 304101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter 305f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramervoid MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, 306f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer unsigned AddrSpace) { 307f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer assert(AddrSpace == 0 && "Address space must be 0!"); 308f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer // FIXME: A MCFillFragment would be more memory efficient but MCExpr has 309f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer // problems evaluating expressions across multiple fragments. 310f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer getOrCreateDataFragment()->getContents().append(NumBytes, FillValue); 311f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer} 312f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer 31399b4237c1647156f0e1d3d7e03efdab23ed79778Rafael Espindolavoid MCObjectStreamer::FinishImpl() { 31489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Dump out the dwarf file & directory tables and line tables. 315e6ec02e8afe1bec8f9de5c907a50a6efdee261a0Rafael Espindola const MCSymbol *LineSectionSymbol = NULL; 31689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola if (getContext().hasDwarfFiles()) 317489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola LineSectionSymbol = MCDwarfFileTable::Emit(this); 31889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 31994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // If we are generating dwarf for assembly source files dump out the sections. 32094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby if (getContext().getGenDwarfForAssembly()) 321489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola MCGenDwarfInfo::Emit(this, LineSectionSymbol); 32294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 32383b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar getAssembler().Finish(); 32483b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar} 325