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/MCAsmInfo.h" 11 #include "llvm/MC/MCObjectStreamer.h" 12 13 #include "llvm/Support/ErrorHandling.h" 14 #include "llvm/MC/MCAssembler.h" 15 #include "llvm/MC/MCCodeEmitter.h" 16 #include "llvm/MC/MCContext.h" 17 #include "llvm/MC/MCDwarf.h" 18 #include "llvm/MC/MCExpr.h" 19 #include "llvm/MC/MCSymbol.h" 20 #include "llvm/Target/TargetAsmBackend.h" 21 using namespace llvm; 22 23 MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, 24 raw_ostream &OS, MCCodeEmitter *Emitter_) 25 : MCStreamer(Context), 26 Assembler(new MCAssembler(Context, TAB, 27 *Emitter_, *TAB.createObjectWriter(OS), 28 OS)), 29 CurSectionData(0) 30 { 31 } 32 33 MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, 34 raw_ostream &OS, MCCodeEmitter *Emitter_, 35 MCAssembler *_Assembler) 36 : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0) 37 { 38 } 39 40 MCObjectStreamer::~MCObjectStreamer() { 41 delete &Assembler->getBackend(); 42 delete &Assembler->getEmitter(); 43 delete &Assembler->getWriter(); 44 delete Assembler; 45 } 46 47 MCFragment *MCObjectStreamer::getCurrentFragment() const { 48 assert(getCurrentSectionData() && "No current section!"); 49 50 if (!getCurrentSectionData()->empty()) 51 return &getCurrentSectionData()->getFragmentList().back(); 52 53 return 0; 54 } 55 56 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { 57 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 58 if (!F) 59 F = new MCDataFragment(getCurrentSectionData()); 60 return F; 61 } 62 63 const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { 64 switch (Value->getKind()) { 65 case MCExpr::Target: 66 cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler); 67 break; 68 69 case MCExpr::Constant: 70 break; 71 72 case MCExpr::Binary: { 73 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 74 AddValueSymbols(BE->getLHS()); 75 AddValueSymbols(BE->getRHS()); 76 break; 77 } 78 79 case MCExpr::SymbolRef: 80 Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 81 break; 82 83 case MCExpr::Unary: 84 AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 85 break; 86 } 87 88 return Value; 89 } 90 91 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, 92 unsigned AddrSpace) { 93 assert(AddrSpace == 0 && "Address space must be 0!"); 94 MCDataFragment *DF = getOrCreateDataFragment(); 95 96 // Avoid fixups when possible. 97 int64_t AbsValue; 98 if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) { 99 EmitIntValue(AbsValue, Size, AddrSpace); 100 return; 101 } 102 DF->addFixup(MCFixup::Create(DF->getContents().size(), 103 Value, 104 MCFixup::getKindForSize(Size, false))); 105 DF->getContents().resize(DF->getContents().size() + Size, 0); 106 } 107 108 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { 109 MCStreamer::EmitLabel(Symbol); 110 111 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 112 113 // FIXME: This is wasteful, we don't necessarily need to create a data 114 // fragment. Instead, we should mark the symbol as pointing into the data 115 // fragment if it exists, otherwise we should just queue the label and set its 116 // fragment pointer when we emit the next fragment. 117 MCDataFragment *F = getOrCreateDataFragment(); 118 assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 119 SD.setFragment(F); 120 SD.setOffset(F->getContents().size()); 121 } 122 123 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { 124 int64_t IntValue; 125 if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 126 EmitULEB128IntValue(IntValue); 127 return; 128 } 129 Value = ForceExpAbs(Value); 130 new MCLEBFragment(*Value, false, getCurrentSectionData()); 131 } 132 133 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { 134 int64_t IntValue; 135 if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 136 EmitSLEB128IntValue(IntValue); 137 return; 138 } 139 Value = ForceExpAbs(Value); 140 new MCLEBFragment(*Value, true, getCurrentSectionData()); 141 } 142 143 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 144 const MCSymbol *Symbol) { 145 report_fatal_error("This file format doesn't support weak aliases."); 146 } 147 148 void MCObjectStreamer::ChangeSection(const MCSection *Section) { 149 assert(Section && "Cannot switch to a null section!"); 150 151 CurSectionData = &getAssembler().getOrCreateSectionData(*Section); 152 } 153 154 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) { 155 // Scan for values. 156 for (unsigned i = Inst.getNumOperands(); i--; ) 157 if (Inst.getOperand(i).isExpr()) 158 AddValueSymbols(Inst.getOperand(i).getExpr()); 159 160 getCurrentSectionData()->setHasInstructions(true); 161 162 // Now that a machine instruction has been assembled into this section, make 163 // a line entry for any .loc directive that has been seen. 164 MCLineEntry::Make(this, getCurrentSection()); 165 166 // If this instruction doesn't need relaxation, just emit it as data. 167 if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) { 168 EmitInstToData(Inst); 169 return; 170 } 171 172 // Otherwise, if we are relaxing everything, relax the instruction as much as 173 // possible and emit it as data. 174 if (getAssembler().getRelaxAll()) { 175 MCInst Relaxed; 176 getAssembler().getBackend().RelaxInstruction(Inst, Relaxed); 177 while (getAssembler().getBackend().MayNeedRelaxation(Relaxed)) 178 getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed); 179 EmitInstToData(Relaxed); 180 return; 181 } 182 183 // Otherwise emit to a separate fragment. 184 EmitInstToFragment(Inst); 185 } 186 187 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) { 188 MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData()); 189 190 SmallString<128> Code; 191 raw_svector_ostream VecOS(Code); 192 getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups()); 193 VecOS.flush(); 194 IF->getCode().append(Code.begin(), Code.end()); 195 } 196 197 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 198 const MCSymbol *LastLabel, 199 const MCSymbol *Label, 200 unsigned PointerSize) { 201 if (!LastLabel) { 202 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); 203 return; 204 } 205 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 206 int64_t Res; 207 if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 208 MCDwarfLineAddr::Emit(this, LineDelta, Res); 209 return; 210 } 211 AddrDelta = ForceExpAbs(AddrDelta); 212 new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData()); 213 } 214 215 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 216 const MCSymbol *Label) { 217 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 218 int64_t Res; 219 if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 220 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); 221 return; 222 } 223 AddrDelta = ForceExpAbs(AddrDelta); 224 new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData()); 225 } 226 227 void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, 228 unsigned char Value) { 229 int64_t Res; 230 if (Offset->EvaluateAsAbsolute(Res, getAssembler())) { 231 new MCOrgFragment(*Offset, Value, getCurrentSectionData()); 232 return; 233 } 234 235 MCSymbol *CurrentPos = getContext().CreateTempSymbol(); 236 EmitLabel(CurrentPos); 237 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 238 const MCExpr *Ref = 239 MCSymbolRefExpr::Create(CurrentPos, Variant, getContext()); 240 const MCExpr *Delta = 241 MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext()); 242 243 if (!Delta->EvaluateAsAbsolute(Res, getAssembler())) 244 report_fatal_error("expected assembly-time absolute expression"); 245 EmitFill(Res, Value, 0); 246 } 247 248 void MCObjectStreamer::Finish() { 249 // Dump out the dwarf file & directory tables and line tables. 250 if (getContext().hasDwarfFiles()) 251 MCDwarfFileTable::Emit(this); 252 253 getAssembler().Finish(); 254 } 255