MCObjectStreamer.cpp revision 6c1d4972cf1cd6b6072e31c05f97abb1ed7a8497
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 MCInstFragment *IF = new MCInstFragment(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 229const char *BundlingNotImplementedMsg = 230 "Aligned bundling is not implemented for this object format"; 231 232void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) { 233 llvm_unreachable(BundlingNotImplementedMsg); 234} 235 236void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) { 237 llvm_unreachable(BundlingNotImplementedMsg); 238} 239 240void MCObjectStreamer::EmitBundleUnlock() { 241 llvm_unreachable(BundlingNotImplementedMsg); 242} 243 244void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 245 const MCSymbol *LastLabel, 246 const MCSymbol *Label, 247 unsigned PointerSize) { 248 if (!LastLabel) { 249 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); 250 return; 251 } 252 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 253 int64_t Res; 254 if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 255 MCDwarfLineAddr::Emit(this, LineDelta, Res); 256 return; 257 } 258 AddrDelta = ForceExpAbs(AddrDelta); 259 new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData()); 260} 261 262void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 263 const MCSymbol *Label) { 264 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 265 int64_t Res; 266 if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 267 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); 268 return; 269 } 270 AddrDelta = ForceExpAbs(AddrDelta); 271 new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData()); 272} 273 274void MCObjectStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 275 assert(AddrSpace == 0 && "Address space must be 0!"); 276 getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 277} 278 279void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, 280 int64_t Value, 281 unsigned ValueSize, 282 unsigned MaxBytesToEmit) { 283 if (MaxBytesToEmit == 0) 284 MaxBytesToEmit = ByteAlignment; 285 new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 286 getCurrentSectionData()); 287 288 // Update the maximum alignment on the current section if necessary. 289 if (ByteAlignment > getCurrentSectionData()->getAlignment()) 290 getCurrentSectionData()->setAlignment(ByteAlignment); 291} 292 293void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment, 294 unsigned MaxBytesToEmit) { 295 EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit); 296 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true); 297} 298 299bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, 300 unsigned char Value) { 301 int64_t Res; 302 if (Offset->EvaluateAsAbsolute(Res, getAssembler())) { 303 new MCOrgFragment(*Offset, Value, getCurrentSectionData()); 304 return false; 305 } 306 307 MCSymbol *CurrentPos = getContext().CreateTempSymbol(); 308 EmitLabel(CurrentPos); 309 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 310 const MCExpr *Ref = 311 MCSymbolRefExpr::Create(CurrentPos, Variant, getContext()); 312 const MCExpr *Delta = 313 MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext()); 314 315 if (!Delta->EvaluateAsAbsolute(Res, getAssembler())) 316 return true; 317 EmitFill(Res, Value, 0); 318 return false; 319} 320 321// Associate GPRel32 fixup with data and resize data area 322void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { 323 MCDataFragment *DF = getOrCreateDataFragment(); 324 325 DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 326 Value, FK_GPRel_4)); 327 DF->getContents().resize(DF->getContents().size() + 4, 0); 328} 329 330// Associate GPRel32 fixup with data and resize data area 331void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { 332 MCDataFragment *DF = getOrCreateDataFragment(); 333 334 DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 335 Value, FK_GPRel_4)); 336 DF->getContents().resize(DF->getContents().size() + 8, 0); 337} 338 339void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, 340 unsigned AddrSpace) { 341 assert(AddrSpace == 0 && "Address space must be 0!"); 342 // FIXME: A MCFillFragment would be more memory efficient but MCExpr has 343 // problems evaluating expressions across multiple fragments. 344 getOrCreateDataFragment()->getContents().append(NumBytes, FillValue); 345} 346 347void MCObjectStreamer::FinishImpl() { 348 // Dump out the dwarf file & directory tables and line tables. 349 const MCSymbol *LineSectionSymbol = NULL; 350 if (getContext().hasDwarfFiles()) 351 LineSectionSymbol = MCDwarfFileTable::Emit(this); 352 353 // If we are generating dwarf for assembly source files dump out the sections. 354 if (getContext().getGenDwarfForAssembly()) 355 MCGenDwarfInfo::Emit(this, LineSectionSymbol); 356 357 getAssembler().Finish(); 358} 359