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/ADT/STLExtras.h" 12 #include "llvm/MC/MCAsmBackend.h" 13 #include "llvm/MC/MCAsmInfo.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/MCObjectWriter.h" 20 #include "llvm/MC/MCSection.h" 21 #include "llvm/MC/MCSymbol.h" 22 #include "llvm/Support/ErrorHandling.h" 23 using namespace llvm; 24 25 MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, 26 raw_ostream &OS, MCCodeEmitter *Emitter_) 27 : MCStreamer(Context), 28 Assembler(new MCAssembler(Context, TAB, *Emitter_, 29 *TAB.createObjectWriter(OS), OS)), 30 CurSectionData(nullptr) {} 31 32 MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, 33 raw_ostream &OS, MCCodeEmitter *Emitter_, 34 MCAssembler *_Assembler) 35 : MCStreamer(Context), Assembler(_Assembler), CurSectionData(nullptr) {} 36 37 MCObjectStreamer::~MCObjectStreamer() { 38 delete &Assembler->getBackend(); 39 delete &Assembler->getEmitter(); 40 delete &Assembler->getWriter(); 41 delete Assembler; 42 } 43 44 void MCObjectStreamer::reset() { 45 if (Assembler) 46 Assembler->reset(); 47 CurSectionData = nullptr; 48 CurInsertionPoint = MCSectionData::iterator(); 49 MCStreamer::reset(); 50 } 51 52 MCFragment *MCObjectStreamer::getCurrentFragment() const { 53 assert(getCurrentSectionData() && "No current section!"); 54 55 if (CurInsertionPoint != getCurrentSectionData()->getFragmentList().begin()) 56 return std::prev(CurInsertionPoint); 57 58 return nullptr; 59 } 60 61 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { 62 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 63 // When bundling is enabled, we don't want to add data to a fragment that 64 // already has instructions (see MCELFStreamer::EmitInstToData for details) 65 if (!F || (Assembler->isBundlingEnabled() && F->hasInstructions())) { 66 F = new MCDataFragment(); 67 insert(F); 68 } 69 return F; 70 } 71 72 const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { 73 switch (Value->getKind()) { 74 case MCExpr::Target: 75 cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler); 76 break; 77 78 case MCExpr::Constant: 79 break; 80 81 case MCExpr::Binary: { 82 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 83 AddValueSymbols(BE->getLHS()); 84 AddValueSymbols(BE->getRHS()); 85 break; 86 } 87 88 case MCExpr::SymbolRef: 89 Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 90 break; 91 92 case MCExpr::Unary: 93 AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 94 break; 95 } 96 97 return Value; 98 } 99 100 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { 101 MCDataFragment *DF = getOrCreateDataFragment(); 102 103 MCLineEntry::Make(this, getCurrentSection().first); 104 105 // Avoid fixups when possible. 106 int64_t AbsValue; 107 if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) { 108 EmitIntValue(AbsValue, Size); 109 return; 110 } 111 DF->getFixups().push_back( 112 MCFixup::Create(DF->getContents().size(), Value, 113 MCFixup::getKindForSize(Size, false))); 114 DF->getContents().resize(DF->getContents().size() + Size, 0); 115 } 116 117 void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 118 RecordProcStart(Frame); 119 } 120 121 void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 122 RecordProcEnd(Frame); 123 } 124 125 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { 126 MCStreamer::EmitLabel(Symbol); 127 128 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 129 130 // FIXME: This is wasteful, we don't necessarily need to create a data 131 // fragment. Instead, we should mark the symbol as pointing into the data 132 // fragment if it exists, otherwise we should just queue the label and set its 133 // fragment pointer when we emit the next fragment. 134 MCDataFragment *F = getOrCreateDataFragment(); 135 assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 136 SD.setFragment(F); 137 SD.setOffset(F->getContents().size()); 138 } 139 140 void MCObjectStreamer::EmitDebugLabel(MCSymbol *Symbol) { 141 EmitLabel(Symbol); 142 } 143 144 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { 145 int64_t IntValue; 146 if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 147 EmitULEB128IntValue(IntValue); 148 return; 149 } 150 Value = ForceExpAbs(Value); 151 insert(new MCLEBFragment(*Value, false)); 152 } 153 154 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { 155 int64_t IntValue; 156 if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 157 EmitSLEB128IntValue(IntValue); 158 return; 159 } 160 Value = ForceExpAbs(Value); 161 insert(new MCLEBFragment(*Value, true)); 162 } 163 164 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 165 const MCSymbol *Symbol) { 166 report_fatal_error("This file format doesn't support weak aliases."); 167 } 168 169 void MCObjectStreamer::ChangeSection(const MCSection *Section, 170 const MCExpr *Subsection) { 171 assert(Section && "Cannot switch to a null section!"); 172 173 CurSectionData = &getAssembler().getOrCreateSectionData(*Section); 174 175 int64_t IntSubsection = 0; 176 if (Subsection && 177 !Subsection->EvaluateAsAbsolute(IntSubsection, getAssembler())) 178 report_fatal_error("Cannot evaluate subsection number"); 179 if (IntSubsection < 0 || IntSubsection > 8192) 180 report_fatal_error("Subsection number out of range"); 181 CurInsertionPoint = 182 CurSectionData->getSubsectionInsertionPoint(unsigned(IntSubsection)); 183 } 184 185 void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 186 getAssembler().getOrCreateSymbolData(*Symbol); 187 AddValueSymbols(Value); 188 MCStreamer::EmitAssignment(Symbol, Value); 189 } 190 191 void MCObjectStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { 192 // Scan for values. 193 for (unsigned i = Inst.getNumOperands(); i--; ) 194 if (Inst.getOperand(i).isExpr()) 195 AddValueSymbols(Inst.getOperand(i).getExpr()); 196 197 MCSectionData *SD = getCurrentSectionData(); 198 SD->setHasInstructions(true); 199 200 // Now that a machine instruction has been assembled into this section, make 201 // a line entry for any .loc directive that has been seen. 202 MCLineEntry::Make(this, getCurrentSection().first); 203 204 // If this instruction doesn't need relaxation, just emit it as data. 205 MCAssembler &Assembler = getAssembler(); 206 if (!Assembler.getBackend().mayNeedRelaxation(Inst)) { 207 EmitInstToData(Inst, STI); 208 return; 209 } 210 211 // Otherwise, relax and emit it as data if either: 212 // - The RelaxAll flag was passed 213 // - Bundling is enabled and this instruction is inside a bundle-locked 214 // group. We want to emit all such instructions into the same data 215 // fragment. 216 if (Assembler.getRelaxAll() || 217 (Assembler.isBundlingEnabled() && SD->isBundleLocked())) { 218 MCInst Relaxed; 219 getAssembler().getBackend().relaxInstruction(Inst, Relaxed); 220 while (getAssembler().getBackend().mayNeedRelaxation(Relaxed)) 221 getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed); 222 EmitInstToData(Relaxed, STI); 223 return; 224 } 225 226 // Otherwise emit to a separate fragment. 227 EmitInstToFragment(Inst, STI); 228 } 229 230 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst, 231 const MCSubtargetInfo &STI) { 232 // Always create a new, separate fragment here, because its size can change 233 // during relaxation. 234 MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI); 235 insert(IF); 236 237 SmallString<128> Code; 238 raw_svector_ostream VecOS(Code); 239 getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups(), 240 STI); 241 VecOS.flush(); 242 IF->getContents().append(Code.begin(), Code.end()); 243 } 244 245 #ifndef NDEBUG 246 static const char *const BundlingNotImplementedMsg = 247 "Aligned bundling is not implemented for this object format"; 248 #endif 249 250 void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) { 251 llvm_unreachable(BundlingNotImplementedMsg); 252 } 253 254 void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) { 255 llvm_unreachable(BundlingNotImplementedMsg); 256 } 257 258 void MCObjectStreamer::EmitBundleUnlock() { 259 llvm_unreachable(BundlingNotImplementedMsg); 260 } 261 262 void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 263 unsigned Column, unsigned Flags, 264 unsigned Isa, 265 unsigned Discriminator, 266 StringRef FileName) { 267 // In case we see two .loc directives in a row, make sure the 268 // first one gets a line entry. 269 MCLineEntry::Make(this, getCurrentSection().first); 270 271 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, 272 Isa, Discriminator, FileName); 273 } 274 275 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 276 const MCSymbol *LastLabel, 277 const MCSymbol *Label, 278 unsigned PointerSize) { 279 if (!LastLabel) { 280 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); 281 return; 282 } 283 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 284 int64_t Res; 285 if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 286 MCDwarfLineAddr::Emit(this, LineDelta, Res); 287 return; 288 } 289 AddrDelta = ForceExpAbs(AddrDelta); 290 insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta)); 291 } 292 293 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 294 const MCSymbol *Label) { 295 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 296 int64_t Res; 297 if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 298 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); 299 return; 300 } 301 AddrDelta = ForceExpAbs(AddrDelta); 302 insert(new MCDwarfCallFrameFragment(*AddrDelta)); 303 } 304 305 void MCObjectStreamer::EmitBytes(StringRef Data) { 306 MCLineEntry::Make(this, getCurrentSection().first); 307 getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 308 } 309 310 void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, 311 int64_t Value, 312 unsigned ValueSize, 313 unsigned MaxBytesToEmit) { 314 if (MaxBytesToEmit == 0) 315 MaxBytesToEmit = ByteAlignment; 316 insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit)); 317 318 // Update the maximum alignment on the current section if necessary. 319 if (ByteAlignment > getCurrentSectionData()->getAlignment()) 320 getCurrentSectionData()->setAlignment(ByteAlignment); 321 } 322 323 void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment, 324 unsigned MaxBytesToEmit) { 325 EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit); 326 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true); 327 } 328 329 bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, 330 unsigned char Value) { 331 int64_t Res; 332 if (Offset->EvaluateAsAbsolute(Res, getAssembler())) { 333 insert(new MCOrgFragment(*Offset, Value)); 334 return false; 335 } 336 337 MCSymbol *CurrentPos = getContext().CreateTempSymbol(); 338 EmitLabel(CurrentPos); 339 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 340 const MCExpr *Ref = 341 MCSymbolRefExpr::Create(CurrentPos, Variant, getContext()); 342 const MCExpr *Delta = 343 MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext()); 344 345 if (!Delta->EvaluateAsAbsolute(Res, getAssembler())) 346 return true; 347 EmitFill(Res, Value); 348 return false; 349 } 350 351 // Associate GPRel32 fixup with data and resize data area 352 void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { 353 MCDataFragment *DF = getOrCreateDataFragment(); 354 355 DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 356 Value, FK_GPRel_4)); 357 DF->getContents().resize(DF->getContents().size() + 4, 0); 358 } 359 360 // Associate GPRel32 fixup with data and resize data area 361 void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { 362 MCDataFragment *DF = getOrCreateDataFragment(); 363 364 DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 365 Value, FK_GPRel_4)); 366 DF->getContents().resize(DF->getContents().size() + 8, 0); 367 } 368 369 void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) { 370 // FIXME: A MCFillFragment would be more memory efficient but MCExpr has 371 // problems evaluating expressions across multiple fragments. 372 getOrCreateDataFragment()->getContents().append(NumBytes, FillValue); 373 } 374 375 void MCObjectStreamer::EmitZeros(uint64_t NumBytes) { 376 unsigned ItemSize = getCurrentSection().first->isVirtualSection() ? 0 : 1; 377 insert(new MCFillFragment(0, ItemSize, NumBytes)); 378 } 379 380 void MCObjectStreamer::FinishImpl() { 381 // If we are generating dwarf for assembly source files dump out the sections. 382 if (getContext().getGenDwarfForAssembly()) 383 MCGenDwarfInfo::Emit(this); 384 385 // Dump out the dwarf file & directory tables and line tables. 386 MCDwarfLineTable::Emit(this); 387 388 getAssembler().Finish(); 389 } 390