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