1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/MC/MCObjectStreamer.h" 11 12 #include "llvm/Support/ErrorHandling.h" 13 #include "llvm/MC/MCAssembler.h" 14 #include "llvm/MC/MCCodeEmitter.h" 15 #include "llvm/MC/MCDwarf.h" 16 #include "llvm/MC/MCExpr.h" 17 #include "llvm/Target/TargetAsmBackend.h" 18 using namespace llvm; 19 20 MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, 21 raw_ostream &_OS, MCCodeEmitter *_Emitter, 22 bool _PadSectionToAlignment) 23 : MCStreamer(Context), Assembler(new MCAssembler(Context, TAB, 24 *_Emitter, 25 _PadSectionToAlignment, 26 _OS)), 27 CurSectionData(0) 28 { 29 } 30 31 MCObjectStreamer::~MCObjectStreamer() { 32 delete &Assembler->getBackend(); 33 delete &Assembler->getEmitter(); 34 delete Assembler; 35 } 36 37 MCFragment *MCObjectStreamer::getCurrentFragment() const { 38 assert(getCurrentSectionData() && "No current section!"); 39 40 if (!getCurrentSectionData()->empty()) 41 return &getCurrentSectionData()->getFragmentList().back(); 42 43 return 0; 44 } 45 46 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { 47 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 48 if (!F) 49 F = new MCDataFragment(getCurrentSectionData()); 50 return F; 51 } 52 53 const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { 54 switch (Value->getKind()) { 55 case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!"); 56 case MCExpr::Constant: 57 break; 58 59 case MCExpr::Binary: { 60 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 61 AddValueSymbols(BE->getLHS()); 62 AddValueSymbols(BE->getRHS()); 63 break; 64 } 65 66 case MCExpr::SymbolRef: 67 Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 68 break; 69 70 case MCExpr::Unary: 71 AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 72 break; 73 } 74 75 return Value; 76 } 77 78 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value, 79 unsigned AddrSpace) { 80 new MCLEBFragment(*Value, false, getCurrentSectionData()); 81 } 82 83 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value, 84 unsigned AddrSpace) { 85 new MCLEBFragment(*Value, true, getCurrentSectionData()); 86 } 87 88 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 89 const MCSymbol *Symbol) { 90 report_fatal_error("This file format doesn't support weak aliases."); 91 } 92 93 void MCObjectStreamer::SwitchSection(const MCSection *Section) { 94 assert(Section && "Cannot switch to a null section!"); 95 96 // If already in this section, then this is a noop. 97 if (Section == CurSection) return; 98 99 PrevSection = CurSection; 100 CurSection = Section; 101 CurSectionData = &getAssembler().getOrCreateSectionData(*Section); 102 } 103 104 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) { 105 // Scan for values. 106 for (unsigned i = Inst.getNumOperands(); i--; ) 107 if (Inst.getOperand(i).isExpr()) 108 AddValueSymbols(Inst.getOperand(i).getExpr()); 109 110 getCurrentSectionData()->setHasInstructions(true); 111 112 // Now that a machine instruction has been assembled into this section, make 113 // a line entry for any .loc directive that has been seen. 114 MCLineEntry::Make(this, getCurrentSection()); 115 116 // If this instruction doesn't need relaxation, just emit it as data. 117 if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) { 118 EmitInstToData(Inst); 119 return; 120 } 121 122 // Otherwise, if we are relaxing everything, relax the instruction as much as 123 // possible and emit it as data. 124 if (getAssembler().getRelaxAll()) { 125 MCInst Relaxed; 126 getAssembler().getBackend().RelaxInstruction(Inst, Relaxed); 127 while (getAssembler().getBackend().MayNeedRelaxation(Relaxed)) 128 getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed); 129 EmitInstToData(Relaxed); 130 return; 131 } 132 133 // Otherwise emit to a separate fragment. 134 EmitInstToFragment(Inst); 135 } 136 137 void MCObjectStreamer::Finish() { 138 getAssembler().Finish(); 139 } 140