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/MC/MCSymbol.h" 18 #include "llvm/Target/TargetAsmBackend.h" 19 using namespace llvm; 20 21 MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, 22 raw_ostream &_OS, MCCodeEmitter *_Emitter, 23 bool _PadSectionToAlignment) 24 : MCStreamer(Context), Assembler(new MCAssembler(Context, TAB, 25 *_Emitter, 26 _PadSectionToAlignment, 27 _OS)), 28 CurSectionData(0) 29 { 30 } 31 32 MCObjectStreamer::~MCObjectStreamer() { 33 delete &Assembler->getBackend(); 34 delete &Assembler->getEmitter(); 35 delete Assembler; 36 } 37 38 MCFragment *MCObjectStreamer::getCurrentFragment() const { 39 assert(getCurrentSectionData() && "No current section!"); 40 41 if (!getCurrentSectionData()->empty()) 42 return &getCurrentSectionData()->getFragmentList().back(); 43 44 return 0; 45 } 46 47 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { 48 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 49 if (!F) 50 F = new MCDataFragment(getCurrentSectionData()); 51 return F; 52 } 53 54 const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { 55 switch (Value->getKind()) { 56 case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!"); 57 case MCExpr::Constant: 58 break; 59 60 case MCExpr::Binary: { 61 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 62 AddValueSymbols(BE->getLHS()); 63 AddValueSymbols(BE->getRHS()); 64 break; 65 } 66 67 case MCExpr::SymbolRef: 68 Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 69 break; 70 71 case MCExpr::Unary: 72 AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 73 break; 74 } 75 76 return Value; 77 } 78 79 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { 80 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 81 assert(CurSection && "Cannot emit before setting section!"); 82 83 Symbol->setSection(*CurSection); 84 85 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 86 87 // FIXME: This is wasteful, we don't necessarily need to create a data 88 // fragment. Instead, we should mark the symbol as pointing into the data 89 // fragment if it exists, otherwise we should just queue the label and set its 90 // fragment pointer when we emit the next fragment. 91 MCDataFragment *F = getOrCreateDataFragment(); 92 assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 93 SD.setFragment(F); 94 SD.setOffset(F->getContents().size()); 95 } 96 97 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value, 98 unsigned AddrSpace) { 99 new MCLEBFragment(*Value, false, getCurrentSectionData()); 100 } 101 102 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value, 103 unsigned AddrSpace) { 104 new MCLEBFragment(*Value, true, getCurrentSectionData()); 105 } 106 107 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 108 const MCSymbol *Symbol) { 109 report_fatal_error("This file format doesn't support weak aliases."); 110 } 111 112 void MCObjectStreamer::SwitchSection(const MCSection *Section) { 113 assert(Section && "Cannot switch to a null section!"); 114 115 // If already in this section, then this is a noop. 116 if (Section == CurSection) return; 117 118 PrevSection = CurSection; 119 CurSection = Section; 120 CurSectionData = &getAssembler().getOrCreateSectionData(*Section); 121 } 122 123 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) { 124 // Scan for values. 125 for (unsigned i = Inst.getNumOperands(); i--; ) 126 if (Inst.getOperand(i).isExpr()) 127 AddValueSymbols(Inst.getOperand(i).getExpr()); 128 129 getCurrentSectionData()->setHasInstructions(true); 130 131 // Now that a machine instruction has been assembled into this section, make 132 // a line entry for any .loc directive that has been seen. 133 MCLineEntry::Make(this, getCurrentSection()); 134 135 // If this instruction doesn't need relaxation, just emit it as data. 136 if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) { 137 EmitInstToData(Inst); 138 return; 139 } 140 141 // Otherwise, if we are relaxing everything, relax the instruction as much as 142 // possible and emit it as data. 143 if (getAssembler().getRelaxAll()) { 144 MCInst Relaxed; 145 getAssembler().getBackend().RelaxInstruction(Inst, Relaxed); 146 while (getAssembler().getBackend().MayNeedRelaxation(Relaxed)) 147 getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed); 148 EmitInstToData(Relaxed); 149 return; 150 } 151 152 // Otherwise emit to a separate fragment. 153 EmitInstToFragment(Inst); 154 } 155 156 void MCObjectStreamer::Finish() { 157 getAssembler().Finish(); 158 } 159