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