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#include "llvm/Support/SourceMgr.h" 24#include "llvm/Support/TargetRegistry.h" 25using namespace llvm; 26 27MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, 28 raw_pwrite_stream &OS, 29 MCCodeEmitter *Emitter_) 30 : MCStreamer(Context), 31 Assembler(new MCAssembler(Context, TAB, *Emitter_, 32 *TAB.createObjectWriter(OS))), 33 EmitEHFrame(true), EmitDebugFrame(false) {} 34 35MCObjectStreamer::~MCObjectStreamer() { 36 delete &Assembler->getBackend(); 37 delete &Assembler->getEmitter(); 38 delete &Assembler->getWriter(); 39 delete Assembler; 40} 41 42void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) { 43 if (PendingLabels.empty()) 44 return; 45 if (!F) { 46 F = new MCDataFragment(); 47 MCSection *CurSection = getCurrentSectionOnly(); 48 CurSection->getFragmentList().insert(CurInsertionPoint, F); 49 F->setParent(CurSection); 50 } 51 for (MCSymbol *Sym : PendingLabels) { 52 Sym->setFragment(F); 53 Sym->setOffset(FOffset); 54 } 55 PendingLabels.clear(); 56} 57 58void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, 59 const MCSymbol *Lo, 60 unsigned Size) { 61 // If not assigned to the same (valid) fragment, fallback. 62 if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() || 63 Hi->isVariable() || Lo->isVariable()) { 64 MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size); 65 return; 66 } 67 68 EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size); 69} 70 71void MCObjectStreamer::reset() { 72 if (Assembler) 73 Assembler->reset(); 74 CurInsertionPoint = MCSection::iterator(); 75 EmitEHFrame = true; 76 EmitDebugFrame = false; 77 PendingLabels.clear(); 78 MCStreamer::reset(); 79} 80 81void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) { 82 if (!getNumFrameInfos()) 83 return; 84 85 if (EmitEHFrame) 86 MCDwarfFrameEmitter::Emit(*this, MAB, true); 87 88 if (EmitDebugFrame) 89 MCDwarfFrameEmitter::Emit(*this, MAB, false); 90} 91 92MCFragment *MCObjectStreamer::getCurrentFragment() const { 93 assert(getCurrentSectionOnly() && "No current section!"); 94 95 if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin()) 96 return &*std::prev(CurInsertionPoint); 97 98 return nullptr; 99} 100 101MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() { 102 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 103 // When bundling is enabled, we don't want to add data to a fragment that 104 // already has instructions (see MCELFStreamer::EmitInstToData for details) 105 if (!F || (Assembler->isBundlingEnabled() && !Assembler->getRelaxAll() && 106 F->hasInstructions())) { 107 F = new MCDataFragment(); 108 insert(F); 109 } 110 return F; 111} 112 113void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) { 114 Assembler->registerSymbol(Sym); 115} 116 117void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) { 118 MCStreamer::EmitCFISections(EH, Debug); 119 EmitEHFrame = EH; 120 EmitDebugFrame = Debug; 121} 122 123void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, 124 SMLoc Loc) { 125 MCStreamer::EmitValueImpl(Value, Size, Loc); 126 MCDataFragment *DF = getOrCreateDataFragment(); 127 flushPendingLabels(DF, DF->getContents().size()); 128 129 MCCVLineEntry::Make(this); 130 MCDwarfLineEntry::Make(this, getCurrentSection().first); 131 132 // Avoid fixups when possible. 133 int64_t AbsValue; 134 if (Value->evaluateAsAbsolute(AbsValue, getAssembler())) { 135 EmitIntValue(AbsValue, Size); 136 return; 137 } 138 DF->getFixups().push_back( 139 MCFixup::create(DF->getContents().size(), Value, 140 MCFixup::getKindForSize(Size, false), Loc)); 141 DF->getContents().resize(DF->getContents().size() + Size, 0); 142} 143 144void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 145 // We need to create a local symbol to avoid relocations. 146 Frame.Begin = getContext().createTempSymbol(); 147 EmitLabel(Frame.Begin); 148} 149 150void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 151 Frame.End = getContext().createTempSymbol(); 152 EmitLabel(Frame.End); 153} 154 155void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { 156 MCStreamer::EmitLabel(Symbol); 157 158 getAssembler().registerSymbol(*Symbol); 159 160 // If there is a current fragment, mark the symbol as pointing into it. 161 // Otherwise queue the label and set its fragment pointer when we emit the 162 // next fragment. 163 auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 164 if (F && !(getAssembler().isBundlingEnabled() && 165 getAssembler().getRelaxAll())) { 166 Symbol->setFragment(F); 167 Symbol->setOffset(F->getContents().size()); 168 } else { 169 PendingLabels.push_back(Symbol); 170 } 171} 172 173void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { 174 int64_t IntValue; 175 if (Value->evaluateAsAbsolute(IntValue, getAssembler())) { 176 EmitULEB128IntValue(IntValue); 177 return; 178 } 179 insert(new MCLEBFragment(*Value, false)); 180} 181 182void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { 183 int64_t IntValue; 184 if (Value->evaluateAsAbsolute(IntValue, getAssembler())) { 185 EmitSLEB128IntValue(IntValue); 186 return; 187 } 188 insert(new MCLEBFragment(*Value, true)); 189} 190 191void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 192 const MCSymbol *Symbol) { 193 report_fatal_error("This file format doesn't support weak aliases."); 194} 195 196void MCObjectStreamer::ChangeSection(MCSection *Section, 197 const MCExpr *Subsection) { 198 changeSectionImpl(Section, Subsection); 199} 200 201bool MCObjectStreamer::changeSectionImpl(MCSection *Section, 202 const MCExpr *Subsection) { 203 assert(Section && "Cannot switch to a null section!"); 204 flushPendingLabels(nullptr); 205 206 bool Created = getAssembler().registerSection(*Section); 207 208 int64_t IntSubsection = 0; 209 if (Subsection && 210 !Subsection->evaluateAsAbsolute(IntSubsection, getAssembler())) 211 report_fatal_error("Cannot evaluate subsection number"); 212 if (IntSubsection < 0 || IntSubsection > 8192) 213 report_fatal_error("Subsection number out of range"); 214 CurInsertionPoint = 215 Section->getSubsectionInsertionPoint(unsigned(IntSubsection)); 216 return Created; 217} 218 219void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 220 getAssembler().registerSymbol(*Symbol); 221 MCStreamer::EmitAssignment(Symbol, Value); 222} 223 224bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { 225 return Sec.hasInstructions(); 226} 227 228void MCObjectStreamer::EmitInstruction(const MCInst &Inst, 229 const MCSubtargetInfo &STI) { 230 MCStreamer::EmitInstruction(Inst, STI); 231 232 MCSection *Sec = getCurrentSectionOnly(); 233 Sec->setHasInstructions(true); 234 235 // Now that a machine instruction has been assembled into this section, make 236 // a line entry for any .loc directive that has been seen. 237 MCCVLineEntry::Make(this); 238 MCDwarfLineEntry::Make(this, getCurrentSection().first); 239 240 // If this instruction doesn't need relaxation, just emit it as data. 241 MCAssembler &Assembler = getAssembler(); 242 if (!Assembler.getBackend().mayNeedRelaxation(Inst)) { 243 EmitInstToData(Inst, STI); 244 return; 245 } 246 247 // Otherwise, relax and emit it as data if either: 248 // - The RelaxAll flag was passed 249 // - Bundling is enabled and this instruction is inside a bundle-locked 250 // group. We want to emit all such instructions into the same data 251 // fragment. 252 if (Assembler.getRelaxAll() || 253 (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) { 254 MCInst Relaxed; 255 getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed); 256 while (getAssembler().getBackend().mayNeedRelaxation(Relaxed)) 257 getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed); 258 EmitInstToData(Relaxed, STI); 259 return; 260 } 261 262 // Otherwise emit to a separate fragment. 263 EmitInstToFragment(Inst, STI); 264} 265 266void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst, 267 const MCSubtargetInfo &STI) { 268 if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled()) 269 llvm_unreachable("All instructions should have already been relaxed"); 270 271 // Always create a new, separate fragment here, because its size can change 272 // during relaxation. 273 MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI); 274 insert(IF); 275 276 SmallString<128> Code; 277 raw_svector_ostream VecOS(Code); 278 getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(), 279 STI); 280 IF->getContents().append(Code.begin(), Code.end()); 281} 282 283#ifndef NDEBUG 284static const char *const BundlingNotImplementedMsg = 285 "Aligned bundling is not implemented for this object format"; 286#endif 287 288void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) { 289 llvm_unreachable(BundlingNotImplementedMsg); 290} 291 292void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) { 293 llvm_unreachable(BundlingNotImplementedMsg); 294} 295 296void MCObjectStreamer::EmitBundleUnlock() { 297 llvm_unreachable(BundlingNotImplementedMsg); 298} 299 300void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 301 unsigned Column, unsigned Flags, 302 unsigned Isa, 303 unsigned Discriminator, 304 StringRef FileName) { 305 // In case we see two .loc directives in a row, make sure the 306 // first one gets a line entry. 307 MCDwarfLineEntry::Make(this, getCurrentSection().first); 308 309 this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, 310 Isa, Discriminator, FileName); 311} 312 313static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A, 314 const MCSymbol *B) { 315 MCContext &Context = OS.getContext(); 316 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 317 const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context); 318 const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context); 319 const MCExpr *AddrDelta = 320 MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context); 321 return AddrDelta; 322} 323 324static void emitDwarfSetLineAddr(MCObjectStreamer &OS, 325 MCDwarfLineTableParams Params, 326 int64_t LineDelta, const MCSymbol *Label, 327 int PointerSize) { 328 // emit the sequence to set the address 329 OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1); 330 OS.EmitULEB128IntValue(PointerSize + 1); 331 OS.EmitIntValue(dwarf::DW_LNE_set_address, 1); 332 OS.EmitSymbolValue(Label, PointerSize); 333 334 // emit the sequence for the LineDelta (from 1) and a zero address delta. 335 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); 336} 337 338void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 339 const MCSymbol *LastLabel, 340 const MCSymbol *Label, 341 unsigned PointerSize) { 342 if (!LastLabel) { 343 emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta, 344 Label, PointerSize); 345 return; 346 } 347 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel); 348 int64_t Res; 349 if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) { 350 MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta, 351 Res); 352 return; 353 } 354 insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta)); 355} 356 357void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 358 const MCSymbol *Label) { 359 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel); 360 int64_t Res; 361 if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) { 362 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); 363 return; 364 } 365 insert(new MCDwarfCallFrameFragment(*AddrDelta)); 366} 367 368void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, 369 unsigned Line, unsigned Column, 370 bool PrologueEnd, bool IsStmt, 371 StringRef FileName) { 372 // In case we see two .cv_loc directives in a row, make sure the 373 // first one gets a line entry. 374 MCCVLineEntry::Make(this); 375 376 this->MCStreamer::EmitCVLocDirective(FunctionId, FileNo, Line, Column, 377 PrologueEnd, IsStmt, FileName); 378} 379 380void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId, 381 const MCSymbol *Begin, 382 const MCSymbol *End) { 383 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin, 384 End); 385 this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End); 386} 387 388void MCObjectStreamer::EmitCVInlineLinetableDirective( 389 unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, 390 const MCSymbol *FnStartSym, const MCSymbol *FnEndSym, 391 ArrayRef<unsigned> SecondaryFunctionIds) { 392 getContext().getCVContext().emitInlineLineTableForFunction( 393 *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, 394 FnEndSym, SecondaryFunctionIds); 395 this->MCStreamer::EmitCVInlineLinetableDirective( 396 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym, 397 SecondaryFunctionIds); 398} 399 400void MCObjectStreamer::EmitCVDefRangeDirective( 401 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, 402 StringRef FixedSizePortion) { 403 getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion); 404 this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion); 405} 406 407void MCObjectStreamer::EmitCVStringTableDirective() { 408 getContext().getCVContext().emitStringTable(*this); 409} 410void MCObjectStreamer::EmitCVFileChecksumsDirective() { 411 getContext().getCVContext().emitFileChecksums(*this); 412} 413 414 415void MCObjectStreamer::EmitBytes(StringRef Data) { 416 MCCVLineEntry::Make(this); 417 MCDwarfLineEntry::Make(this, getCurrentSection().first); 418 MCDataFragment *DF = getOrCreateDataFragment(); 419 flushPendingLabels(DF, DF->getContents().size()); 420 DF->getContents().append(Data.begin(), Data.end()); 421} 422 423void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, 424 int64_t Value, 425 unsigned ValueSize, 426 unsigned MaxBytesToEmit) { 427 if (MaxBytesToEmit == 0) 428 MaxBytesToEmit = ByteAlignment; 429 insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit)); 430 431 // Update the maximum alignment on the current section if necessary. 432 MCSection *CurSec = getCurrentSection().first; 433 if (ByteAlignment > CurSec->getAlignment()) 434 CurSec->setAlignment(ByteAlignment); 435} 436 437void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment, 438 unsigned MaxBytesToEmit) { 439 EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit); 440 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true); 441} 442 443void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset, 444 unsigned char Value) { 445 insert(new MCOrgFragment(*Offset, Value)); 446} 447 448// Associate GPRel32 fixup with data and resize data area 449void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { 450 MCDataFragment *DF = getOrCreateDataFragment(); 451 flushPendingLabels(DF, DF->getContents().size()); 452 453 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 454 Value, FK_GPRel_4)); 455 DF->getContents().resize(DF->getContents().size() + 4, 0); 456} 457 458// Associate GPRel32 fixup with data and resize data area 459void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { 460 MCDataFragment *DF = getOrCreateDataFragment(); 461 flushPendingLabels(DF, DF->getContents().size()); 462 463 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 464 Value, FK_GPRel_4)); 465 DF->getContents().resize(DF->getContents().size() + 8, 0); 466} 467 468bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name, 469 const MCExpr *Expr, SMLoc Loc) { 470 int64_t OffsetValue; 471 if (!Offset.evaluateAsAbsolute(OffsetValue)) 472 llvm_unreachable("Offset is not absolute"); 473 474 if (OffsetValue < 0) 475 llvm_unreachable("Offset is negative"); 476 477 MCDataFragment *DF = getOrCreateDataFragment(); 478 flushPendingLabels(DF, DF->getContents().size()); 479 480 Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name); 481 if (!MaybeKind.hasValue()) 482 return true; 483 484 MCFixupKind Kind = *MaybeKind; 485 486 if (Expr == nullptr) 487 Expr = 488 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext()); 489 DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc)); 490 return false; 491} 492 493void MCObjectStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) { 494 const MCSection *Sec = getCurrentSection().first; 495 (void)Sec; 496 assert(Sec && "need a section"); 497 insert(new MCFillFragment(FillValue, NumBytes)); 498} 499 500void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue, 501 SMLoc Loc) { 502 MCDataFragment *DF = getOrCreateDataFragment(); 503 flushPendingLabels(DF, DF->getContents().size()); 504 505 int64_t IntNumBytes; 506 if (!NumBytes.evaluateAsAbsolute(IntNumBytes, getAssembler())) { 507 getContext().reportError(Loc, "expected absolute expression"); 508 return; 509 } 510 511 if (IntNumBytes <= 0) { 512 getContext().reportError(Loc, "invalid number of bytes"); 513 return; 514 } 515 516 emitFill(IntNumBytes, FillValue); 517} 518 519void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size, 520 int64_t Expr, SMLoc Loc) { 521 int64_t IntNumValues; 522 if (!NumValues.evaluateAsAbsolute(IntNumValues, getAssembler())) { 523 getContext().reportError(Loc, "expected absolute expression"); 524 return; 525 } 526 527 if (IntNumValues < 0) { 528 getContext().getSourceManager()->PrintMessage( 529 Loc, SourceMgr::DK_Warning, 530 "'.fill' directive with negative repeat count has no effect"); 531 return; 532 } 533 534 MCStreamer::emitFill(IntNumValues, Size, Expr); 535} 536 537void MCObjectStreamer::FinishImpl() { 538 // If we are generating dwarf for assembly source files dump out the sections. 539 if (getContext().getGenDwarfForAssembly()) 540 MCGenDwarfInfo::Emit(this); 541 542 // Dump out the dwarf file & directory tables and line tables. 543 MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams()); 544 545 flushPendingLabels(nullptr); 546 getAssembler().Finish(); 547} 548