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