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::EmitWeakReference(MCSymbol *Alias, 79 const MCSymbol *Symbol) { 80 report_fatal_error("This file format doesn't support weak aliases."); 81 } 82 83 void MCObjectStreamer::SwitchSection(const MCSection *Section) { 84 assert(Section && "Cannot switch to a null section!"); 85 86 // If already in this section, then this is a noop. 87 if (Section == CurSection) return; 88 89 PrevSection = CurSection; 90 CurSection = Section; 91 CurSectionData = &getAssembler().getOrCreateSectionData(*Section); 92 } 93 94 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) { 95 // Scan for values. 96 for (unsigned i = Inst.getNumOperands(); i--; ) 97 if (Inst.getOperand(i).isExpr()) 98 AddValueSymbols(Inst.getOperand(i).getExpr()); 99 100 getCurrentSectionData()->setHasInstructions(true); 101 102 // Now that a machine instruction has been assembled into this section, make 103 // a line entry for any .loc directive that has been seen. 104 MCLineEntry::Make(this, getCurrentSection()); 105 106 // If this instruction doesn't need relaxation, just emit it as data. 107 if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) { 108 EmitInstToData(Inst); 109 return; 110 } 111 112 // Otherwise, if we are relaxing everything, relax the instruction as much as 113 // possible and emit it as data. 114 if (getAssembler().getRelaxAll()) { 115 MCInst Relaxed; 116 getAssembler().getBackend().RelaxInstruction(Inst, Relaxed); 117 while (getAssembler().getBackend().MayNeedRelaxation(Relaxed)) 118 getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed); 119 EmitInstToData(Relaxed); 120 return; 121 } 122 123 // Otherwise emit to a separate fragment. 124 EmitInstToFragment(Inst); 125 } 126 127 void MCObjectStreamer::Finish() { 128 getAssembler().Finish(); 129 } 130