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