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