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