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