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