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 47MCFragment *MCObjectStreamer::getCurrentFragment() const { 48 assert(getCurrentSectionData() && "No current section!"); 49 50 if (!getCurrentSectionData()->empty()) 51 return &getCurrentSectionData()->getFragmentList().back(); 52 53 return 0; 54} 55 56MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { 57 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 58 if (!F) 59 F = new MCDataFragment(getCurrentSectionData()); 60 return F; 61} 62 63const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { 64 switch (Value->getKind()) { 65 case MCExpr::Target: 66 cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler); 67 break; 68 69 case MCExpr::Constant: 70 break; 71 72 case MCExpr::Binary: { 73 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 74 AddValueSymbols(BE->getLHS()); 75 AddValueSymbols(BE->getRHS()); 76 break; 77 } 78 79 case MCExpr::SymbolRef: 80 Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 81 break; 82 83 case MCExpr::Unary: 84 AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 85 break; 86 } 87 88 return Value; 89} 90 91void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, 92 unsigned AddrSpace) { 93 assert(AddrSpace == 0 && "Address space must be 0!"); 94 MCDataFragment *DF = getOrCreateDataFragment(); 95 96 // Avoid fixups when possible. 97 int64_t AbsValue; 98 if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) { 99 EmitIntValue(AbsValue, Size, AddrSpace); 100 return; 101 } 102 DF->addFixup(MCFixup::Create(DF->getContents().size(), 103 Value, 104 MCFixup::getKindForSize(Size, false))); 105 DF->getContents().resize(DF->getContents().size() + Size, 0); 106} 107 108void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 109 RecordProcStart(Frame); 110} 111 112void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 113 RecordProcEnd(Frame); 114} 115 116void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { 117 MCStreamer::EmitLabel(Symbol); 118 119 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 120 121 // FIXME: This is wasteful, we don't necessarily need to create a data 122 // fragment. Instead, we should mark the symbol as pointing into the data 123 // fragment if it exists, otherwise we should just queue the label and set its 124 // fragment pointer when we emit the next fragment. 125 MCDataFragment *F = getOrCreateDataFragment(); 126 assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 127 SD.setFragment(F); 128 SD.setOffset(F->getContents().size()); 129} 130 131void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { 132 int64_t IntValue; 133 if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 134 EmitULEB128IntValue(IntValue); 135 return; 136 } 137 Value = ForceExpAbs(Value); 138 new MCLEBFragment(*Value, false, getCurrentSectionData()); 139} 140 141void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { 142 int64_t IntValue; 143 if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) { 144 EmitSLEB128IntValue(IntValue); 145 return; 146 } 147 Value = ForceExpAbs(Value); 148 new MCLEBFragment(*Value, true, getCurrentSectionData()); 149} 150 151void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, 152 const MCSymbol *Symbol) { 153 report_fatal_error("This file format doesn't support weak aliases."); 154} 155 156void MCObjectStreamer::ChangeSection(const MCSection *Section) { 157 assert(Section && "Cannot switch to a null section!"); 158 159 CurSectionData = &getAssembler().getOrCreateSectionData(*Section); 160} 161 162void MCObjectStreamer::EmitInstruction(const MCInst &Inst) { 163 // Scan for values. 164 for (unsigned i = Inst.getNumOperands(); i--; ) 165 if (Inst.getOperand(i).isExpr()) 166 AddValueSymbols(Inst.getOperand(i).getExpr()); 167 168 getCurrentSectionData()->setHasInstructions(true); 169 170 // Now that a machine instruction has been assembled into this section, make 171 // a line entry for any .loc directive that has been seen. 172 MCLineEntry::Make(this, getCurrentSection()); 173 174 // If this instruction doesn't need relaxation, just emit it as data. 175 if (!getAssembler().getBackend().mayNeedRelaxation(Inst)) { 176 EmitInstToData(Inst); 177 return; 178 } 179 180 // Otherwise, if we are relaxing everything, relax the instruction as much as 181 // possible and emit it as data. 182 if (getAssembler().getRelaxAll()) { 183 MCInst Relaxed; 184 getAssembler().getBackend().relaxInstruction(Inst, Relaxed); 185 while (getAssembler().getBackend().mayNeedRelaxation(Relaxed)) 186 getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed); 187 EmitInstToData(Relaxed); 188 return; 189 } 190 191 // Otherwise emit to a separate fragment. 192 EmitInstToFragment(Inst); 193} 194 195void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) { 196 MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData()); 197 198 SmallString<128> Code; 199 raw_svector_ostream VecOS(Code); 200 getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups()); 201 VecOS.flush(); 202 IF->getCode().append(Code.begin(), Code.end()); 203} 204 205void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, 206 const MCSymbol *LastLabel, 207 const MCSymbol *Label, 208 unsigned PointerSize) { 209 if (!LastLabel) { 210 EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); 211 return; 212 } 213 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 214 int64_t Res; 215 if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 216 MCDwarfLineAddr::Emit(this, LineDelta, Res); 217 return; 218 } 219 AddrDelta = ForceExpAbs(AddrDelta); 220 new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData()); 221} 222 223void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, 224 const MCSymbol *Label) { 225 const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); 226 int64_t Res; 227 if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) { 228 MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); 229 return; 230 } 231 AddrDelta = ForceExpAbs(AddrDelta); 232 new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData()); 233} 234 235bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, 236 unsigned char Value) { 237 int64_t Res; 238 if (Offset->EvaluateAsAbsolute(Res, getAssembler())) { 239 new MCOrgFragment(*Offset, Value, getCurrentSectionData()); 240 return false; 241 } 242 243 MCSymbol *CurrentPos = getContext().CreateTempSymbol(); 244 EmitLabel(CurrentPos); 245 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 246 const MCExpr *Ref = 247 MCSymbolRefExpr::Create(CurrentPos, Variant, getContext()); 248 const MCExpr *Delta = 249 MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext()); 250 251 if (!Delta->EvaluateAsAbsolute(Res, getAssembler())) 252 return true; 253 EmitFill(Res, Value, 0); 254 return false; 255} 256 257// Associate GPRel32 fixup with data and resize data area 258void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { 259 MCDataFragment *DF = getOrCreateDataFragment(); 260 261 DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4)); 262 DF->getContents().resize(DF->getContents().size() + 4, 0); 263} 264 265// Associate GPRel32 fixup with data and resize data area 266void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { 267 MCDataFragment *DF = getOrCreateDataFragment(); 268 269 DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4)); 270 DF->getContents().resize(DF->getContents().size() + 8, 0); 271} 272 273void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, 274 unsigned AddrSpace) { 275 assert(AddrSpace == 0 && "Address space must be 0!"); 276 // FIXME: A MCFillFragment would be more memory efficient but MCExpr has 277 // problems evaluating expressions across multiple fragments. 278 getOrCreateDataFragment()->getContents().append(NumBytes, FillValue); 279} 280 281void MCObjectStreamer::FinishImpl() { 282 // Dump out the dwarf file & directory tables and line tables. 283 const MCSymbol *LineSectionSymbol = NULL; 284 if (getContext().hasDwarfFiles()) 285 LineSectionSymbol = MCDwarfFileTable::Emit(this); 286 287 // If we are generating dwarf for assembly source files dump out the sections. 288 if (getContext().getGenDwarfForAssembly()) 289 MCGenDwarfInfo::Emit(this, LineSectionSymbol); 290 291 getAssembler().Finish(); 292} 293