MCStreamer.cpp revision 547be2699c547b79a7735858a64921d8ccf180f7
193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org//===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===// 293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// 393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// The LLVM Compiler Infrastructure 493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// 593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// This file is distributed under the University of Illinois Open Source 693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// License. See LICENSE.TXT for details. 793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// 893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org//===----------------------------------------------------------------------===// 993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "llvm/MC/MCAsmInfo.h" 1193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "llvm/MC/MCContext.h" 1293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "llvm/MC/MCStreamer.h" 1393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "llvm/MC/MCExpr.h" 1493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "llvm/MC/MCObjectWriter.h" 1593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "llvm/MC/MCSymbol.h" 1693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "llvm/Support/ErrorHandling.h" 1793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "llvm/Support/raw_ostream.h" 1893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "llvm/ADT/SmallString.h" 1993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "llvm/ADT/Twine.h" 2093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include <cstdlib> 2193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgusing namespace llvm; 2293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgMCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx), EmitEHFrame(true), 2493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org EmitDebugFrame(false), 2593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org CurrentW64UnwindInfo(0), 2693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org LastSymbol(0), 2787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org UniqueCodeBeginSuffix(0), 2887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org UniqueDataBeginSuffix(0) { 2987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org const MCSection *section = NULL; 3087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org SectionStack.push_back(std::make_pair(section, section)); 3188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org} 32d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org 3393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgMCStreamer::~MCStreamer() { 349a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i) 35d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org delete W64UnwindInfos[i]; 36d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org} 37ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 38ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.orgconst MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context, 3941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const MCSymbol *A, 40ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org const MCSymbol *B) { 41ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 4287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org const MCExpr *ARef = 4393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org MCSymbolRefExpr::Create(A, Variant, Context); 4493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const MCExpr *BRef = 4593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org MCSymbolRefExpr::Create(B, Variant, Context); 4693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const MCExpr *AddrDelta = 4793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context); 4893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return AddrDelta; 4993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 50ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 5187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgconst MCExpr *MCStreamer::ForceExpAbs(const MCExpr* Expr) { 5287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (Context.getAsmInfo().hasAggressiveSymbolFolding() || 53ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org isa<MCSymbolRefExpr>(Expr)) 54ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org return Expr; 55ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 56ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org MCSymbol *ABS = Context.CreateTempSymbol(); 5793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org EmitAssignment(ABS, Expr); 5893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return MCSymbolRefExpr::Create(ABS, Context); 5993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 6093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgraw_ostream &MCStreamer::GetCommentOS() { 6293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // By default, discard comments. 6393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org return nulls(); 6493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 6593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 6693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta, 6793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const MCSymbol *Label, int PointerSize) { 6893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // emit the sequence to set the address 6993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org EmitIntValue(dwarf::DW_LNS_extended_op, 1); 7093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org EmitULEB128IntValue(PointerSize + 1); 7193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org EmitIntValue(dwarf::DW_LNE_set_address, 1); 7293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org EmitSymbolValue(Label, PointerSize); 7393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // emit the sequence for the LineDelta (from 1) and a zero address delta. 7593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org MCDwarfLineAddr::Emit(this, LineDelta, 0); 7693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 7793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 7893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org/// EmitIntValue - Special case of EmitValue that avoids the client having to 7993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org/// pass in a MCExpr for constant integers. 8093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid MCStreamer::EmitIntValue(uint64_t Value, unsigned Size, 8193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org unsigned AddrSpace) { 8293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert(Size <= 8 && "Invalid size"); 8393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && 8493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org "Invalid size"); 8593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org char buf[8]; 8693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const bool isLittleEndian = Context.getAsmInfo().isLittleEndian(); 8793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org for (unsigned i = 0; i != Size; ++i) { 8893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org unsigned index = isLittleEndian ? i : (Size - i - 1); 8993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org buf[i] = uint8_t(Value >> (index * 8)); 90693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com } 91d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org EmitBytes(StringRef(buf, Size), AddrSpace); 92693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com} 939a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org 949a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the 959a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org/// client having to pass in a MCExpr for constant integers. 96e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.orgvoid MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace, 97e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org unsigned Padding) { 98e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org SmallString<32> Tmp; 99e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org raw_svector_ostream OSE(Tmp); 100e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org MCObjectWriter::EncodeULEB128(Value, OSE, Padding); 10187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org EmitBytes(OSE.str(), AddrSpace); 10287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org} 103e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 10493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the 10593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org/// client having to pass in a MCExpr for constant integers. 10693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) { 10793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org SmallString<32> Tmp; 10893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org raw_svector_ostream OSE(Tmp); 109 MCObjectWriter::EncodeSLEB128(Value, OSE); 110 EmitBytes(OSE.str(), AddrSpace); 111} 112 113void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size, 114 unsigned AddrSpace) { 115 const MCExpr *ABS = ForceExpAbs(Value); 116 EmitValue(ABS, Size, AddrSpace); 117} 118 119 120void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, 121 unsigned AddrSpace) { 122 EmitValueImpl(Value, Size, AddrSpace); 123} 124 125void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, 126 unsigned AddrSpace) { 127 EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size, 128 AddrSpace); 129} 130 131void MCStreamer::EmitGPRel32Value(const MCExpr *Value) { 132 report_fatal_error("unsupported directive in streamer"); 133} 134 135/// EmitFill - Emit NumBytes bytes worth of the value specified by 136/// FillValue. This implements directives such as '.space'. 137void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, 138 unsigned AddrSpace) { 139 const MCExpr *E = MCConstantExpr::Create(FillValue, getContext()); 140 for (uint64_t i = 0, e = NumBytes; i != e; ++i) 141 EmitValue(E, 1, AddrSpace); 142} 143 144bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo, 145 StringRef Directory, 146 StringRef Filename) { 147 return getContext().GetDwarfFile(Directory, Filename, FileNo) == 0; 148} 149 150void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 151 unsigned Column, unsigned Flags, 152 unsigned Isa, 153 unsigned Discriminator, 154 StringRef FileName) { 155 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa, 156 Discriminator); 157} 158 159MCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() { 160 if (FrameInfos.empty()) 161 return NULL; 162 return &FrameInfos.back(); 163} 164 165void MCStreamer::EnsureValidFrame() { 166 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 167 if (!CurFrame || CurFrame->End) 168 report_fatal_error("No open frame"); 169} 170 171void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, 172 MCSymbol *EHSymbol) { 173} 174 175void MCStreamer::EmitLabel(MCSymbol *Symbol) { 176 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 177 assert(getCurrentSection() && "Cannot emit before setting section!"); 178 Symbol->setSection(*getCurrentSection()); 179 LastSymbol = Symbol; 180} 181 182void MCStreamer::EmitDataRegion() { 183 if (RegionIndicator == Data) return; 184 185 MCContext &Context = getContext(); 186 const MCAsmInfo &MAI = Context.getAsmInfo(); 187 if (!MAI.getSupportsDataRegions()) return; 188 189 // Generate a unique symbol name. 190 MCSymbol *NewSym = Context.GetOrCreateSymbol(MAI.getDataBeginLabelName() + 191 Twine(UniqueDataBeginSuffix++)); 192 EmitLabel(NewSym); 193 194 RegionIndicator = Data; 195} 196 197void MCStreamer::EmitCodeRegion() { 198 if (RegionIndicator == Code) return; 199 200 MCContext &Context = getContext(); 201 const MCAsmInfo &MAI = Context.getAsmInfo(); 202 if (!MAI.getSupportsDataRegions()) return; 203 204 // Generate a unique symbol name. 205 MCSymbol *NewSym = Context.GetOrCreateSymbol(MAI.getCodeBeginLabelName() + 206 Twine(UniqueCodeBeginSuffix++)); 207 EmitLabel(NewSym); 208 209 RegionIndicator = Code; 210} 211 212void MCStreamer::EmitJumpTable8Region() { 213 if (RegionIndicator == JumpTable8) return; 214 215 MCContext &Context = getContext(); 216 const MCAsmInfo &MAI = Context.getAsmInfo(); 217 if (!MAI.getSupportsDataRegions()) return; 218 219 // Generate a unique symbol name. 220 MCSymbol *NewSym = 221 Context.GetOrCreateSymbol(MAI.getJumpTable8BeginLabelName() + 222 Twine(UniqueDataBeginSuffix++)); 223 EmitLabel(NewSym); 224 225 RegionIndicator = JumpTable8; 226} 227 228void MCStreamer::EmitJumpTable16Region() { 229 if (RegionIndicator == JumpTable16) return; 230 231 MCContext &Context = getContext(); 232 const MCAsmInfo &MAI = Context.getAsmInfo(); 233 if (!MAI.getSupportsDataRegions()) return; 234 235 // Generate a unique symbol name. 236 MCSymbol *NewSym = 237 Context.GetOrCreateSymbol(MAI.getJumpTable16BeginLabelName() + 238 Twine(UniqueDataBeginSuffix++)); 239 EmitLabel(NewSym); 240 241 RegionIndicator = JumpTable16; 242} 243 244 245void MCStreamer::EmitJumpTable32Region() { 246 if (RegionIndicator == JumpTable32) return; 247 248 MCContext &Context = getContext(); 249 const MCAsmInfo &MAI = Context.getAsmInfo(); 250 if (!MAI.getSupportsDataRegions()) return; 251 252 // Generate a unique symbol name. 253 MCSymbol *NewSym = 254 Context.GetOrCreateSymbol(MAI.getJumpTable32BeginLabelName() + 255 Twine(UniqueDataBeginSuffix++)); 256 EmitLabel(NewSym); 257 258 RegionIndicator = JumpTable32; 259} 260 261void MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) { 262 EnsureValidFrame(); 263 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 264 CurFrame->CompactUnwindEncoding = CompactUnwindEncoding; 265} 266 267void MCStreamer::EmitCFISections(bool EH, bool Debug) { 268 assert(EH || Debug); 269 EmitEHFrame = EH; 270 EmitDebugFrame = Debug; 271} 272 273void MCStreamer::EmitCFIStartProc() { 274 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 275 if (CurFrame && !CurFrame->End) 276 report_fatal_error("Starting a frame before finishing the previous one!"); 277 278 MCDwarfFrameInfo Frame; 279 EmitCFIStartProcImpl(Frame); 280 281 FrameInfos.push_back(Frame); 282 RegionIndicator = Code; 283} 284 285void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 286} 287 288void MCStreamer::RecordProcStart(MCDwarfFrameInfo &Frame) { 289 Frame.Function = LastSymbol; 290 // If the function is externally visible, we need to create a local 291 // symbol to avoid relocations. 292 StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix(); 293 if (LastSymbol && LastSymbol->getName().startswith(Prefix)) { 294 Frame.Begin = LastSymbol; 295 } else { 296 Frame.Begin = getContext().CreateTempSymbol(); 297 EmitLabel(Frame.Begin); 298 } 299} 300 301void MCStreamer::EmitCFIEndProc() { 302 EnsureValidFrame(); 303 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 304 CurFrame->End = getContext().CreateTempSymbol(); 305 EmitLabel(CurFrame->End); 306} 307 308void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { 309 EnsureValidFrame(); 310 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 311 MCSymbol *Label = getContext().CreateTempSymbol(); 312 EmitLabel(Label); 313 MachineLocation Dest(MachineLocation::VirtualFP); 314 MachineLocation Source(Register, -Offset); 315 MCCFIInstruction Instruction(Label, Dest, Source); 316 CurFrame->Instructions.push_back(Instruction); 317} 318 319void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 320 EnsureValidFrame(); 321 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 322 MCSymbol *Label = getContext().CreateTempSymbol(); 323 EmitLabel(Label); 324 MachineLocation Dest(MachineLocation::VirtualFP); 325 MachineLocation Source(MachineLocation::VirtualFP, -Offset); 326 MCCFIInstruction Instruction(Label, Dest, Source); 327 CurFrame->Instructions.push_back(Instruction); 328} 329 330void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { 331 EnsureValidFrame(); 332 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 333 MCSymbol *Label = getContext().CreateTempSymbol(); 334 EmitLabel(Label); 335 MachineLocation Dest(MachineLocation::VirtualFP); 336 MachineLocation Source(MachineLocation::VirtualFP, Adjustment); 337 MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source); 338 CurFrame->Instructions.push_back(Instruction); 339} 340 341void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { 342 EnsureValidFrame(); 343 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 344 MCSymbol *Label = getContext().CreateTempSymbol(); 345 EmitLabel(Label); 346 MachineLocation Dest(Register); 347 MachineLocation Source(MachineLocation::VirtualFP); 348 MCCFIInstruction Instruction(Label, Dest, Source); 349 CurFrame->Instructions.push_back(Instruction); 350} 351 352void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 353 EnsureValidFrame(); 354 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 355 MCSymbol *Label = getContext().CreateTempSymbol(); 356 EmitLabel(Label); 357 MachineLocation Dest(Register, Offset); 358 MachineLocation Source(Register, Offset); 359 MCCFIInstruction Instruction(Label, Dest, Source); 360 CurFrame->Instructions.push_back(Instruction); 361} 362 363void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { 364 EnsureValidFrame(); 365 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 366 MCSymbol *Label = getContext().CreateTempSymbol(); 367 EmitLabel(Label); 368 MachineLocation Dest(Register, Offset); 369 MachineLocation Source(Register, Offset); 370 MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source); 371 CurFrame->Instructions.push_back(Instruction); 372} 373 374void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, 375 unsigned Encoding) { 376 EnsureValidFrame(); 377 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 378 CurFrame->Personality = Sym; 379 CurFrame->PersonalityEncoding = Encoding; 380} 381 382void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 383 EnsureValidFrame(); 384 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 385 CurFrame->Lsda = Sym; 386 CurFrame->LsdaEncoding = Encoding; 387} 388 389void MCStreamer::EmitCFIRememberState() { 390 EnsureValidFrame(); 391 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 392 MCSymbol *Label = getContext().CreateTempSymbol(); 393 EmitLabel(Label); 394 MCCFIInstruction Instruction(MCCFIInstruction::RememberState, Label); 395 CurFrame->Instructions.push_back(Instruction); 396} 397 398void MCStreamer::EmitCFIRestoreState() { 399 // FIXME: Error if there is no matching cfi_remember_state. 400 EnsureValidFrame(); 401 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 402 MCSymbol *Label = getContext().CreateTempSymbol(); 403 EmitLabel(Label); 404 MCCFIInstruction Instruction(MCCFIInstruction::RestoreState, Label); 405 CurFrame->Instructions.push_back(Instruction); 406} 407 408void MCStreamer::EmitCFISameValue(int64_t Register) { 409 EnsureValidFrame(); 410 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 411 MCSymbol *Label = getContext().CreateTempSymbol(); 412 EmitLabel(Label); 413 MCCFIInstruction Instruction(MCCFIInstruction::SameValue, Label, Register); 414 CurFrame->Instructions.push_back(Instruction); 415} 416 417void MCStreamer::EmitCFIRestore(int64_t Register) { 418 EnsureValidFrame(); 419 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 420 MCSymbol *Label = getContext().CreateTempSymbol(); 421 EmitLabel(Label); 422 MCCFIInstruction Instruction(MCCFIInstruction::Restore, Label, Register); 423 CurFrame->Instructions.push_back(Instruction); 424} 425 426void MCStreamer::EmitCFIEscape(StringRef Values) { 427 EnsureValidFrame(); 428 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 429 MCSymbol *Label = getContext().CreateTempSymbol(); 430 EmitLabel(Label); 431 MCCFIInstruction Instruction(MCCFIInstruction::Escape, Label, Values); 432 CurFrame->Instructions.push_back(Instruction); 433} 434 435void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) { 436 W64UnwindInfos.push_back(Frame); 437 CurrentW64UnwindInfo = W64UnwindInfos.back(); 438} 439 440void MCStreamer::EnsureValidW64UnwindInfo() { 441 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 442 if (!CurFrame || CurFrame->End) 443 report_fatal_error("No open Win64 EH frame function!"); 444} 445 446void MCStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) { 447 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 448 if (CurFrame && !CurFrame->End) 449 report_fatal_error("Starting a function before ending the previous one!"); 450 MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo; 451 Frame->Begin = getContext().CreateTempSymbol(); 452 Frame->Function = Symbol; 453 EmitLabel(Frame->Begin); 454 setCurrentW64UnwindInfo(Frame); 455} 456 457void MCStreamer::EmitWin64EHEndProc() { 458 EnsureValidW64UnwindInfo(); 459 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 460 if (CurFrame->ChainedParent) 461 report_fatal_error("Not all chained regions terminated!"); 462 CurFrame->End = getContext().CreateTempSymbol(); 463 EmitLabel(CurFrame->End); 464} 465 466void MCStreamer::EmitWin64EHStartChained() { 467 EnsureValidW64UnwindInfo(); 468 MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo; 469 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 470 Frame->Begin = getContext().CreateTempSymbol(); 471 Frame->Function = CurFrame->Function; 472 Frame->ChainedParent = CurFrame; 473 EmitLabel(Frame->Begin); 474 setCurrentW64UnwindInfo(Frame); 475} 476 477void MCStreamer::EmitWin64EHEndChained() { 478 EnsureValidW64UnwindInfo(); 479 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 480 if (!CurFrame->ChainedParent) 481 report_fatal_error("End of a chained region outside a chained region!"); 482 CurFrame->End = getContext().CreateTempSymbol(); 483 EmitLabel(CurFrame->End); 484 CurrentW64UnwindInfo = CurFrame->ChainedParent; 485} 486 487void MCStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, 488 bool Except) { 489 EnsureValidW64UnwindInfo(); 490 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 491 if (CurFrame->ChainedParent) 492 report_fatal_error("Chained unwind areas can't have handlers!"); 493 CurFrame->ExceptionHandler = Sym; 494 if (!Except && !Unwind) 495 report_fatal_error("Don't know what kind of handler this is!"); 496 if (Unwind) 497 CurFrame->HandlesUnwind = true; 498 if (Except) 499 CurFrame->HandlesExceptions = true; 500} 501 502void MCStreamer::EmitWin64EHHandlerData() { 503 EnsureValidW64UnwindInfo(); 504 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 505 if (CurFrame->ChainedParent) 506 report_fatal_error("Chained unwind areas can't have handlers!"); 507} 508 509void MCStreamer::EmitWin64EHPushReg(unsigned Register) { 510 EnsureValidW64UnwindInfo(); 511 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 512 MCSymbol *Label = getContext().CreateTempSymbol(); 513 MCWin64EHInstruction Inst(Win64EH::UOP_PushNonVol, Label, Register); 514 EmitLabel(Label); 515 CurFrame->Instructions.push_back(Inst); 516} 517 518void MCStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) { 519 EnsureValidW64UnwindInfo(); 520 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 521 if (CurFrame->LastFrameInst >= 0) 522 report_fatal_error("Frame register and offset already specified!"); 523 if (Offset & 0x0F) 524 report_fatal_error("Misaligned frame pointer offset!"); 525 MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, NULL, Register, Offset); 526 CurFrame->LastFrameInst = CurFrame->Instructions.size(); 527 CurFrame->Instructions.push_back(Inst); 528} 529 530void MCStreamer::EmitWin64EHAllocStack(unsigned Size) { 531 EnsureValidW64UnwindInfo(); 532 if (Size & 7) 533 report_fatal_error("Misaligned stack allocation!"); 534 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 535 MCSymbol *Label = getContext().CreateTempSymbol(); 536 MCWin64EHInstruction Inst(Label, Size); 537 EmitLabel(Label); 538 CurFrame->Instructions.push_back(Inst); 539} 540 541void MCStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) { 542 EnsureValidW64UnwindInfo(); 543 if (Offset & 7) 544 report_fatal_error("Misaligned saved register offset!"); 545 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 546 MCSymbol *Label = getContext().CreateTempSymbol(); 547 MCWin64EHInstruction Inst( 548 Offset > 512*1024-8 ? Win64EH::UOP_SaveNonVolBig : Win64EH::UOP_SaveNonVol, 549 Label, Register, Offset); 550 EmitLabel(Label); 551 CurFrame->Instructions.push_back(Inst); 552} 553 554void MCStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) { 555 EnsureValidW64UnwindInfo(); 556 if (Offset & 0x0F) 557 report_fatal_error("Misaligned saved vector register offset!"); 558 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 559 MCSymbol *Label = getContext().CreateTempSymbol(); 560 MCWin64EHInstruction Inst( 561 Offset > 512*1024-16 ? Win64EH::UOP_SaveXMM128Big : Win64EH::UOP_SaveXMM128, 562 Label, Register, Offset); 563 EmitLabel(Label); 564 CurFrame->Instructions.push_back(Inst); 565} 566 567void MCStreamer::EmitWin64EHPushFrame(bool Code) { 568 EnsureValidW64UnwindInfo(); 569 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 570 if (CurFrame->Instructions.size() > 0) 571 report_fatal_error("If present, PushMachFrame must be the first UOP"); 572 MCSymbol *Label = getContext().CreateTempSymbol(); 573 MCWin64EHInstruction Inst(Win64EH::UOP_PushMachFrame, Label, Code); 574 EmitLabel(Label); 575 CurFrame->Instructions.push_back(Inst); 576} 577 578void MCStreamer::EmitWin64EHEndProlog() { 579 EnsureValidW64UnwindInfo(); 580 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 581 CurFrame->PrologEnd = getContext().CreateTempSymbol(); 582 EmitLabel(CurFrame->PrologEnd); 583} 584 585void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { 586 assert(0 && "This file format doesn't support this directive"); 587} 588 589void MCStreamer::EmitFnStart() { 590 errs() << "Not implemented yet\n"; 591 abort(); 592} 593 594void MCStreamer::EmitFnEnd() { 595 errs() << "Not implemented yet\n"; 596 abort(); 597} 598 599void MCStreamer::EmitCantUnwind() { 600 errs() << "Not implemented yet\n"; 601 abort(); 602} 603 604void MCStreamer::EmitHandlerData() { 605 errs() << "Not implemented yet\n"; 606 abort(); 607} 608 609void MCStreamer::EmitPersonality(const MCSymbol *Personality) { 610 errs() << "Not implemented yet\n"; 611 abort(); 612} 613 614void MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) { 615 errs() << "Not implemented yet\n"; 616 abort(); 617} 618 619void MCStreamer::EmitPad(int64_t Offset) { 620 errs() << "Not implemented yet\n"; 621 abort(); 622} 623 624void MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) { 625 errs() << "Not implemented yet\n"; 626 abort(); 627} 628 629/// EmitRawText - If this file is backed by an assembly streamer, this dumps 630/// the specified string in the output .s file. This capability is 631/// indicated by the hasRawTextSupport() predicate. 632void MCStreamer::EmitRawText(StringRef String) { 633 errs() << "EmitRawText called on an MCStreamer that doesn't support it, " 634 " something must not be fully mc'ized\n"; 635 abort(); 636} 637 638void MCStreamer::EmitRawText(const Twine &T) { 639 SmallString<128> Str; 640 T.toVector(Str); 641 EmitRawText(Str.str()); 642} 643 644void MCStreamer::EmitFrames(bool usingCFI) { 645 if (!getNumFrameInfos()) 646 return; 647 648 if (EmitEHFrame) 649 MCDwarfFrameEmitter::Emit(*this, usingCFI, true); 650 651 if (EmitDebugFrame) 652 MCDwarfFrameEmitter::Emit(*this, usingCFI, false); 653} 654 655void MCStreamer::EmitW64Tables() { 656 if (!getNumW64UnwindInfos()) 657 return; 658 659 MCWin64EHUnwindEmitter::Emit(*this); 660} 661 662void MCStreamer::Finish() { 663 if (!FrameInfos.empty() && !FrameInfos.back().End) 664 report_fatal_error("Unfinished frame!"); 665 666 FinishImpl(); 667} 668