MCStreamer.cpp revision debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2be
1//===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===// 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/MCAsmInfo.h" 11#include "llvm/MC/MCContext.h" 12#include "llvm/MC/MCStreamer.h" 13#include "llvm/MC/MCExpr.h" 14#include "llvm/MC/MCObjectWriter.h" 15#include "llvm/MC/MCSymbol.h" 16#include "llvm/Support/ErrorHandling.h" 17#include "llvm/Support/raw_ostream.h" 18#include "llvm/ADT/SmallString.h" 19#include "llvm/ADT/Twine.h" 20#include <cstdlib> 21using namespace llvm; 22 23MCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx) { 24 const MCSection *section = NULL; 25 SectionStack.push_back(std::make_pair(section, section)); 26} 27 28MCStreamer::~MCStreamer() { 29} 30 31const MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context, 32 const MCSymbol *A, 33 const MCSymbol *B) { 34 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 35 const MCExpr *ARef = 36 MCSymbolRefExpr::Create(A, Variant, Context); 37 const MCExpr *BRef = 38 MCSymbolRefExpr::Create(B, Variant, Context); 39 const MCExpr *AddrDelta = 40 MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context); 41 return AddrDelta; 42} 43 44const MCExpr *MCStreamer::ForceExpAbs(MCStreamer *Streamer, 45 MCContext &Context, const MCExpr* Expr) { 46 if (Context.getAsmInfo().hasAggressiveSymbolFolding()) 47 return Expr; 48 49 MCSymbol *ABS = Context.CreateTempSymbol(); 50 Streamer->EmitAssignment(ABS, Expr); 51 return MCSymbolRefExpr::Create(ABS, Context); 52} 53 54raw_ostream &MCStreamer::GetCommentOS() { 55 // By default, discard comments. 56 return nulls(); 57} 58 59void MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta, 60 const MCSymbol *Label, int PointerSize) { 61 // emit the sequence to set the address 62 EmitIntValue(dwarf::DW_LNS_extended_op, 1); 63 EmitULEB128IntValue(PointerSize + 1); 64 EmitIntValue(dwarf::DW_LNE_set_address, 1); 65 EmitSymbolValue(Label, PointerSize); 66 67 // emit the sequence for the LineDelta (from 1) and a zero address delta. 68 MCDwarfLineAddr::Emit(this, LineDelta, 0); 69} 70 71/// EmitIntValue - Special case of EmitValue that avoids the client having to 72/// pass in a MCExpr for constant integers. 73void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size, 74 unsigned AddrSpace) { 75 assert(Size <= 8 && "Invalid size"); 76 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && 77 "Invalid size"); 78 char buf[8]; 79 // FIXME: Endianness assumption. 80 for (unsigned i = 0; i != Size; ++i) 81 buf[i] = uint8_t(Value >> (i * 8)); 82 EmitBytes(StringRef(buf, Size), AddrSpace); 83} 84 85/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the 86/// client having to pass in a MCExpr for constant integers. 87void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace) { 88 SmallString<32> Tmp; 89 raw_svector_ostream OSE(Tmp); 90 MCObjectWriter::EncodeULEB128(Value, OSE); 91 EmitBytes(OSE.str(), AddrSpace); 92} 93 94/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the 95/// client having to pass in a MCExpr for constant integers. 96void MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) { 97 SmallString<32> Tmp; 98 raw_svector_ostream OSE(Tmp); 99 MCObjectWriter::EncodeSLEB128(Value, OSE); 100 EmitBytes(OSE.str(), AddrSpace); 101} 102 103void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size, 104 unsigned AddrSpace) { 105 if (getContext().getAsmInfo().hasAggressiveSymbolFolding()) { 106 EmitValue(Value, Size, AddrSpace); 107 return; 108 } 109 MCSymbol *ABS = getContext().CreateTempSymbol(); 110 EmitAssignment(ABS, Value); 111 EmitSymbolValue(ABS, Size, AddrSpace); 112} 113 114 115void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, 116 unsigned AddrSpace) { 117 EmitValueImpl(Value, Size, AddrSpace); 118} 119 120void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, 121 unsigned AddrSpace) { 122 EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size, 123 AddrSpace); 124} 125 126void MCStreamer::EmitGPRel32Value(const MCExpr *Value) { 127 report_fatal_error("unsupported directive in streamer"); 128} 129 130/// EmitFill - Emit NumBytes bytes worth of the value specified by 131/// FillValue. This implements directives such as '.space'. 132void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, 133 unsigned AddrSpace) { 134 const MCExpr *E = MCConstantExpr::Create(FillValue, getContext()); 135 for (uint64_t i = 0, e = NumBytes; i != e; ++i) 136 EmitValue(E, 1, AddrSpace); 137} 138 139bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo, 140 StringRef Filename) { 141 return getContext().GetDwarfFile(Filename, FileNo) == 0; 142} 143 144void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 145 unsigned Column, unsigned Flags, 146 unsigned Isa, 147 unsigned Discriminator, 148 StringRef FileName) { 149 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa, 150 Discriminator); 151} 152 153MCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() { 154 if (FrameInfos.empty()) 155 return NULL; 156 return &FrameInfos.back(); 157} 158 159void MCStreamer::EnsureValidFrame() { 160 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 161 if (!CurFrame || CurFrame->End) 162 report_fatal_error("No open frame"); 163} 164 165void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, 166 MCSymbol *EHSymbol) { 167} 168 169void MCStreamer::EmitLabel(MCSymbol *Symbol) { 170 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 171 assert(getCurrentSection() && "Cannot emit before setting section!"); 172 Symbol->setSection(*getCurrentSection()); 173 174 StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix(); 175 if (!Symbol->getName().startswith(Prefix)) 176 LastNonPrivate = Symbol; 177} 178 179void MCStreamer::EmitCFIStartProc() { 180 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 181 if (CurFrame && !CurFrame->End) 182 report_fatal_error("Starting a frame before finishing the previous one!"); 183 MCDwarfFrameInfo Frame; 184 Frame.Begin = getContext().CreateTempSymbol(); 185 Frame.Function = LastNonPrivate; 186 EmitLabel(Frame.Begin); 187 FrameInfos.push_back(Frame); 188} 189 190void MCStreamer::EmitCFIEndProc() { 191 EnsureValidFrame(); 192 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 193 CurFrame->End = getContext().CreateTempSymbol(); 194 EmitLabel(CurFrame->End); 195} 196 197void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { 198 EnsureValidFrame(); 199 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 200 MCSymbol *Label = getContext().CreateTempSymbol(); 201 EmitLabel(Label); 202 MachineLocation Dest(MachineLocation::VirtualFP); 203 MachineLocation Source(Register, -Offset); 204 MCCFIInstruction Instruction(Label, Dest, Source); 205 CurFrame->Instructions.push_back(Instruction); 206} 207 208void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 209 EnsureValidFrame(); 210 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 211 MCSymbol *Label = getContext().CreateTempSymbol(); 212 EmitLabel(Label); 213 MachineLocation Dest(MachineLocation::VirtualFP); 214 MachineLocation Source(MachineLocation::VirtualFP, -Offset); 215 MCCFIInstruction Instruction(Label, Dest, Source); 216 CurFrame->Instructions.push_back(Instruction); 217} 218 219void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { 220 EnsureValidFrame(); 221 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 222 MCSymbol *Label = getContext().CreateTempSymbol(); 223 EmitLabel(Label); 224 MachineLocation Dest(MachineLocation::VirtualFP); 225 MachineLocation Source(MachineLocation::VirtualFP, Adjustment); 226 MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source); 227 CurFrame->Instructions.push_back(Instruction); 228} 229 230void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { 231 EnsureValidFrame(); 232 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 233 MCSymbol *Label = getContext().CreateTempSymbol(); 234 EmitLabel(Label); 235 MachineLocation Dest(Register); 236 MachineLocation Source(MachineLocation::VirtualFP); 237 MCCFIInstruction Instruction(Label, Dest, Source); 238 CurFrame->Instructions.push_back(Instruction); 239} 240 241void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 242 EnsureValidFrame(); 243 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 244 MCSymbol *Label = getContext().CreateTempSymbol(); 245 EmitLabel(Label); 246 MachineLocation Dest(Register, Offset); 247 MachineLocation Source(Register, Offset); 248 MCCFIInstruction Instruction(Label, Dest, Source); 249 CurFrame->Instructions.push_back(Instruction); 250} 251 252void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { 253 EnsureValidFrame(); 254 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 255 MCSymbol *Label = getContext().CreateTempSymbol(); 256 EmitLabel(Label); 257 MachineLocation Dest(Register, Offset); 258 MachineLocation Source(Register, Offset); 259 MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source); 260 CurFrame->Instructions.push_back(Instruction); 261} 262 263void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, 264 unsigned Encoding) { 265 EnsureValidFrame(); 266 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 267 CurFrame->Personality = Sym; 268 CurFrame->PersonalityEncoding = Encoding; 269} 270 271void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 272 EnsureValidFrame(); 273 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 274 CurFrame->Lsda = Sym; 275 CurFrame->LsdaEncoding = Encoding; 276} 277 278void MCStreamer::EmitCFIRememberState() { 279 EnsureValidFrame(); 280 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 281 MCSymbol *Label = getContext().CreateTempSymbol(); 282 EmitLabel(Label); 283 MCCFIInstruction Instruction(MCCFIInstruction::Remember, Label); 284 CurFrame->Instructions.push_back(Instruction); 285} 286 287void MCStreamer::EmitCFIRestoreState() { 288 // FIXME: Error if there is no matching cfi_remember_state. 289 EnsureValidFrame(); 290 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 291 MCSymbol *Label = getContext().CreateTempSymbol(); 292 EmitLabel(Label); 293 MCCFIInstruction Instruction(MCCFIInstruction::Restore, Label); 294 CurFrame->Instructions.push_back(Instruction); 295} 296 297void MCStreamer::EmitCFISameValue(int64_t Register) { 298 EnsureValidFrame(); 299 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 300 MCSymbol *Label = getContext().CreateTempSymbol(); 301 EmitLabel(Label); 302 MCCFIInstruction Instruction(MCCFIInstruction::SameValue, Label, Register); 303 CurFrame->Instructions.push_back(Instruction); 304} 305 306void MCStreamer::EmitFnStart() { 307 errs() << "Not implemented yet\n"; 308 abort(); 309} 310 311void MCStreamer::EmitFnEnd() { 312 errs() << "Not implemented yet\n"; 313 abort(); 314} 315 316void MCStreamer::EmitCantUnwind() { 317 errs() << "Not implemented yet\n"; 318 abort(); 319} 320 321void MCStreamer::EmitHandlerData() { 322 errs() << "Not implemented yet\n"; 323 abort(); 324} 325 326void MCStreamer::EmitPersonality(const MCSymbol *Personality) { 327 errs() << "Not implemented yet\n"; 328 abort(); 329} 330 331void MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) { 332 errs() << "Not implemented yet\n"; 333 abort(); 334} 335 336void MCStreamer::EmitPad(int64_t Offset) { 337 errs() << "Not implemented yet\n"; 338 abort(); 339} 340 341void MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) { 342 errs() << "Not implemented yet\n"; 343 abort(); 344} 345 346/// EmitRawText - If this file is backed by an assembly streamer, this dumps 347/// the specified string in the output .s file. This capability is 348/// indicated by the hasRawTextSupport() predicate. 349void MCStreamer::EmitRawText(StringRef String) { 350 errs() << "EmitRawText called on an MCStreamer that doesn't support it, " 351 " something must not be fully mc'ized\n"; 352 abort(); 353} 354 355void MCStreamer::EmitRawText(const Twine &T) { 356 SmallString<128> Str; 357 T.toVector(Str); 358 EmitRawText(Str.str()); 359} 360