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 #include "llvm/MC/MCAsmBackend.h" 12 #include "llvm/MC/MCAsmInfo.h" 13 #include "llvm/MC/MCAssembler.h" 14 #include "llvm/MC/MCCodeEmitter.h" 15 #include "llvm/MC/MCContext.h" 16 #include "llvm/MC/MCDwarf.h" 17 #include "llvm/MC/MCExpr.h" 18 #include "llvm/MC/MCObjectWriter.h" 19 #include "llvm/MC/MCSymbol.h" 20 #include "llvm/Support/ErrorHandling.h" 21 using namespace llvm; 22 23 MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &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, MCAsmBackend &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::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 109 RecordProcStart(Frame); 110 } 111 112 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 113 RecordProcEnd(Frame); 114 } 115 116 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { 117 MCStreamer::EmitLabel(Symbol); 118 119 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 120 121 // FIXME: This is wasteful, we don't necessarily need to create a data 122 // fragment. Instead, we should mark the symbol as pointing into the data 123 // fragment if it exists, otherwise we should just queue the label and set its 124 // fragment pointer when we emit the next fragment. 125 MCDataFragment *F = getOrCreateDataFragment(); 126 assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 127 SD.setFragment(F); 128 SD.setOffset(F->getContents().size()); 129 } 130 131 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { 132 int64_t IntValue; 133 if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 134 EmitULEB128IntValue(IntValue); 135 return; 136 } 137 Value = ForceExpAbs(Value); 138 new MCLEBFragment(*Value, false, getCurrentSectionData()); 139 } 140 141 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { 142 int64_t IntValue; 143 if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 144 EmitSLEB128IntValue(IntValue); 145 return; 146 } 147 Value = ForceExpAbs(Value); 148 new MCLEBFragment(*Value, true, getCurrentSectionData()); 149 } 150 151 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 152 const MCSymbol *Symbol) { 153 report_fatal_error("This file format doesn't support weak aliases."); 154 } 155 156 void MCObjectStreamer::ChangeSection(const MCSection *Section) { 157 assert(Section && "Cannot switch to a null section!"); 158 159 CurSectionData = &getAssembler().getOrCreateSectionData(*Section); 160 } 161 162 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) { 163 // Scan for values. 164 for (unsigned i = Inst.getNumOperands(); i--; ) 165 if (Inst.getOperand(i).isExpr()) 166 AddValueSymbols(Inst.getOperand(i).getExpr()); 167 168 getCurrentSectionData()->setHasInstructions(true); 169 170 // Now that a machine instruction has been assembled into this section, make 171 // a line entry for any .loc directive that has been seen. 172 MCLineEntry::Make(this, getCurrentSection()); 173 174 // If this instruction doesn't need relaxation, just emit it as data. 175 if (!getAssembler().getBackend().mayNeedRelaxation(Inst)) { 176 EmitInstToData(Inst); 177 return; 178 } 179 180 // Otherwise, if we are relaxing everything, relax the instruction as much as 181 // possible and emit it as data. 182 if (getAssembler().getRelaxAll()) { 183 MCInst Relaxed; 184 getAssembler().getBackend().relaxInstruction(Inst, Relaxed); 185 while (getAssembler().getBackend().mayNeedRelaxation(Relaxed)) 186 getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed); 187 EmitInstToData(Relaxed); 188 return; 189 } 190 191 // Otherwise emit to a separate fragment. 192 EmitInstToFragment(Inst); 193 } 194 195 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) { 196 MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData()); 197 198 SmallString<128> Code; 199 raw_svector_ostream VecOS(Code); 200 getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups()); 201 VecOS.flush(); 202 IF->getCode().append(Code.begin(), Code.end()); 203 } 204 205 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 206 const MCSymbol *LastLabel, 207 const MCSymbol *Label, 208 unsigned PointerSize) { 209 if (!LastLabel) { 210 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); 211 return; 212 } 213 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 214 int64_t Res; 215 if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 216 MCDwarfLineAddr::Emit(this, LineDelta, Res); 217 return; 218 } 219 AddrDelta = ForceExpAbs(AddrDelta); 220 new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData()); 221 } 222 223 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 224 const MCSymbol *Label) { 225 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 226 int64_t Res; 227 if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 228 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); 229 return; 230 } 231 AddrDelta = ForceExpAbs(AddrDelta); 232 new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData()); 233 } 234 235 bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, 236 unsigned char Value) { 237 int64_t Res; 238 if (Offset->EvaluateAsAbsolute(Res, getAssembler())) { 239 new MCOrgFragment(*Offset, Value, getCurrentSectionData()); 240 return false; 241 } 242 243 MCSymbol *CurrentPos = getContext().CreateTempSymbol(); 244 EmitLabel(CurrentPos); 245 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 246 const MCExpr *Ref = 247 MCSymbolRefExpr::Create(CurrentPos, Variant, getContext()); 248 const MCExpr *Delta = 249 MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext()); 250 251 if (!Delta->EvaluateAsAbsolute(Res, getAssembler())) 252 return true; 253 EmitFill(Res, Value, 0); 254 return false; 255 } 256 257 // Associate GPRel32 fixup with data and resize data area 258 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { 259 MCDataFragment *DF = getOrCreateDataFragment(); 260 261 DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4)); 262 DF->getContents().resize(DF->getContents().size() + 4, 0); 263 } 264 265 // Associate GPRel32 fixup with data and resize data area 266 void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { 267 MCDataFragment *DF = getOrCreateDataFragment(); 268 269 DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4)); 270 DF->getContents().resize(DF->getContents().size() + 8, 0); 271 } 272 273 void MCObjectStreamer::FinishImpl() { 274 // Dump out the dwarf file & directory tables and line tables. 275 const MCSymbol *LineSectionSymbol = NULL; 276 if (getContext().hasDwarfFiles()) 277 LineSectionSymbol = MCDwarfFileTable::Emit(this); 278 279 // If we are generating dwarf for assembly source files dump out the sections. 280 if (getContext().getGenDwarfForAssembly()) 281 MCGenDwarfInfo::Emit(this, LineSectionSymbol); 282 283 getAssembler().Finish(); 284 } 285