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