DwarfException.cpp revision 409914b773ffd53d53d214394d5636a76f673186
1//===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===// 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// This file contains support for writing dwarf exception info into asm files. 11// 12//===----------------------------------------------------------------------===// 13 14#include "DwarfException.h" 15#include "llvm/Module.h" 16#include "llvm/CodeGen/MachineModuleInfo.h" 17#include "llvm/CodeGen/MachineFrameInfo.h" 18#include "llvm/CodeGen/MachineLocation.h" 19#include "llvm/Support/Dwarf.h" 20#include "llvm/Support/Timer.h" 21#include "llvm/Support/raw_ostream.h" 22#include "llvm/Target/TargetAsmInfo.h" 23#include "llvm/Target/TargetRegisterInfo.h" 24#include "llvm/Target/TargetData.h" 25#include "llvm/Target/TargetFrameInfo.h" 26#include "llvm/Target/TargetOptions.h" 27#include "llvm/ADT/StringExtras.h" 28using namespace llvm; 29 30static TimerGroup &getDwarfTimerGroup() { 31 static TimerGroup DwarfTimerGroup("Dwarf Exception"); 32 return DwarfTimerGroup; 33} 34 35DwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A, 36 const TargetAsmInfo *T) 37 : Dwarf(OS, A, T, "eh"), shouldEmitTable(false), shouldEmitMoves(false), 38 shouldEmitTableModule(false), shouldEmitMovesModule(false), 39 ExceptionTimer(0) { 40 if (TimePassesIsEnabled) 41 ExceptionTimer = new Timer("Dwarf Exception Writer", 42 getDwarfTimerGroup()); 43} 44 45DwarfException::~DwarfException() { 46 delete ExceptionTimer; 47} 48 49void DwarfException::EmitCommonEHFrame(const Function *Personality, 50 unsigned Index) { 51 // Size and sign of stack growth. 52 int stackGrowth = 53 Asm->TM.getFrameInfo()->getStackGrowthDirection() == 54 TargetFrameInfo::StackGrowsUp ? 55 TD->getPointerSize() : -TD->getPointerSize(); 56 57 // Begin eh frame section. 58 Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection()); 59 60 if (TAI->is_EHSymbolPrivate()) 61 O << TAI->getPrivateGlobalPrefix(); 62 63 O << "EH_frame" << Index << ":\n"; 64 EmitLabel("section_eh_frame", Index); 65 66 // Define base labels. 67 EmitLabel("eh_frame_common", Index); 68 69 // Define the eh frame length. 70 EmitDifference("eh_frame_common_end", Index, 71 "eh_frame_common_begin", Index, true); 72 Asm->EOL("Length of Common Information Entry"); 73 74 // EH frame header. 75 EmitLabel("eh_frame_common_begin", Index); 76 Asm->EmitInt32((int)0); 77 Asm->EOL("CIE Identifier Tag"); 78 Asm->EmitInt8(dwarf::DW_CIE_VERSION); 79 Asm->EOL("CIE Version"); 80 81 // The personality presence indicates that language specific information will 82 // show up in the eh frame. 83 Asm->EmitString(Personality ? "zPLR" : "zR"); 84 Asm->EOL("CIE Augmentation"); 85 86 // Round out reader. 87 Asm->EmitULEB128Bytes(1); 88 Asm->EOL("CIE Code Alignment Factor"); 89 Asm->EmitSLEB128Bytes(stackGrowth); 90 Asm->EOL("CIE Data Alignment Factor"); 91 Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true)); 92 Asm->EOL("CIE Return Address Column"); 93 94 // If there is a personality, we need to indicate the functions location. 95 if (Personality) { 96 Asm->EmitULEB128Bytes(7); 97 Asm->EOL("Augmentation Size"); 98 99 if (TAI->getNeedsIndirectEncoding()) { 100 Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 | 101 dwarf::DW_EH_PE_indirect); 102 Asm->EOL("Personality (pcrel sdata4 indirect)"); 103 } else { 104 Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 105 Asm->EOL("Personality (pcrel sdata4)"); 106 } 107 108 PrintRelDirective(true); 109 O << TAI->getPersonalityPrefix(); 110 Asm->EmitExternalGlobal((const GlobalVariable *)(Personality)); 111 O << TAI->getPersonalitySuffix(); 112 if (strcmp(TAI->getPersonalitySuffix(), "+4@GOTPCREL")) 113 O << "-" << TAI->getPCSymbol(); 114 Asm->EOL("Personality"); 115 116 Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 117 Asm->EOL("LSDA Encoding (pcrel sdata4)"); 118 119 Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 120 Asm->EOL("FDE Encoding (pcrel sdata4)"); 121 } else { 122 Asm->EmitULEB128Bytes(1); 123 Asm->EOL("Augmentation Size"); 124 125 Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 126 Asm->EOL("FDE Encoding (pcrel sdata4)"); 127 } 128 129 // Indicate locations of general callee saved registers in frame. 130 std::vector<MachineMove> Moves; 131 RI->getInitialFrameState(Moves); 132 EmitFrameMoves(NULL, 0, Moves, true); 133 134 // On Darwin the linker honors the alignment of eh_frame, which means it must 135 // be 8-byte on 64-bit targets to match what gcc does. Otherwise you get 136 // holes which confuse readers of eh_frame. 137 Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, 138 0, 0, false); 139 EmitLabel("eh_frame_common_end", Index); 140 141 Asm->EOL(); 142} 143 144/// EmitEHFrame - Emit function exception frame information. 145/// 146void DwarfException::EmitEHFrame(const FunctionEHFrameInfo &EHFrameInfo) { 147 assert(!EHFrameInfo.function->hasAvailableExternallyLinkage() && 148 "Should not emit 'available externally' functions at all"); 149 150 const Function *TheFunc = EHFrameInfo.function; 151 152 Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection()); 153 154 // Externally visible entry into the functions eh frame info. If the 155 // corresponding function is static, this should not be externally visible. 156 if (!TheFunc->hasLocalLinkage()) 157 if (const char *GlobalEHDirective = TAI->getGlobalEHDirective()) 158 O << GlobalEHDirective << EHFrameInfo.FnName << "\n"; 159 160 // If corresponding function is weak definition, this should be too. 161 if (TheFunc->isWeakForLinker() && TAI->getWeakDefDirective()) 162 O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n"; 163 164 // If there are no calls then you can't unwind. This may mean we can omit the 165 // EH Frame, but some environments do not handle weak absolute symbols. If 166 // UnwindTablesMandatory is set we cannot do this optimization; the unwind 167 // info is to be available for non-EH uses. 168 if (!EHFrameInfo.hasCalls && !UnwindTablesMandatory && 169 (!TheFunc->isWeakForLinker() || 170 !TAI->getWeakDefDirective() || 171 TAI->getSupportsWeakOmittedEHFrame())) { 172 O << EHFrameInfo.FnName << " = 0\n"; 173 // This name has no connection to the function, so it might get 174 // dead-stripped when the function is not, erroneously. Prohibit 175 // dead-stripping unconditionally. 176 if (const char *UsedDirective = TAI->getUsedDirective()) 177 O << UsedDirective << EHFrameInfo.FnName << "\n\n"; 178 } else { 179 O << EHFrameInfo.FnName << ":\n"; 180 181 // EH frame header. 182 EmitDifference("eh_frame_end", EHFrameInfo.Number, 183 "eh_frame_begin", EHFrameInfo.Number, true); 184 Asm->EOL("Length of Frame Information Entry"); 185 186 EmitLabel("eh_frame_begin", EHFrameInfo.Number); 187 188 EmitSectionOffset("eh_frame_begin", "eh_frame_common", 189 EHFrameInfo.Number, EHFrameInfo.PersonalityIndex, 190 true, true, false); 191 192 Asm->EOL("FDE CIE offset"); 193 194 EmitReference("eh_func_begin", EHFrameInfo.Number, true, true); 195 Asm->EOL("FDE initial location"); 196 EmitDifference("eh_func_end", EHFrameInfo.Number, 197 "eh_func_begin", EHFrameInfo.Number, true); 198 Asm->EOL("FDE address range"); 199 200 // If there is a personality and landing pads then point to the language 201 // specific data area in the exception table. 202 if (EHFrameInfo.PersonalityIndex) { 203 Asm->EmitULEB128Bytes(4); 204 Asm->EOL("Augmentation size"); 205 206 if (EHFrameInfo.hasLandingPads) 207 EmitReference("exception", EHFrameInfo.Number, true, true); 208 else 209 Asm->EmitInt32((int)0); 210 Asm->EOL("Language Specific Data Area"); 211 } else { 212 Asm->EmitULEB128Bytes(0); 213 Asm->EOL("Augmentation size"); 214 } 215 216 // Indicate locations of function specific callee saved registers in frame. 217 EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, 218 true); 219 220 // On Darwin the linker honors the alignment of eh_frame, which means it 221 // must be 8-byte on 64-bit targets to match what gcc does. Otherwise you 222 // get holes which confuse readers of eh_frame. 223 Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, 224 0, 0, false); 225 EmitLabel("eh_frame_end", EHFrameInfo.Number); 226 227 // If the function is marked used, this table should be also. We cannot 228 // make the mark unconditional in this case, since retaining the table also 229 // retains the function in this case, and there is code around that depends 230 // on unused functions (calling undefined externals) being dead-stripped to 231 // link correctly. Yes, there really is. 232 if (MMI->isUsedFunction(EHFrameInfo.function)) 233 if (const char *UsedDirective = TAI->getUsedDirective()) 234 O << UsedDirective << EHFrameInfo.FnName << "\n\n"; 235 } 236} 237 238/// SharedTypeIds - How many leading type ids two landing pads have in common. 239unsigned DwarfException::SharedTypeIds(const LandingPadInfo *L, 240 const LandingPadInfo *R) { 241 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 242 unsigned LSize = LIds.size(), RSize = RIds.size(); 243 unsigned MinSize = LSize < RSize ? LSize : RSize; 244 unsigned Count = 0; 245 246 for (; Count != MinSize; ++Count) 247 if (LIds[Count] != RIds[Count]) 248 return Count; 249 250 return Count; 251} 252 253/// PadLT - Order landing pads lexicographically by type id. 254bool DwarfException::PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { 255 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 256 unsigned LSize = LIds.size(), RSize = RIds.size(); 257 unsigned MinSize = LSize < RSize ? LSize : RSize; 258 259 for (unsigned i = 0; i != MinSize; ++i) 260 if (LIds[i] != RIds[i]) 261 return LIds[i] < RIds[i]; 262 263 return LSize < RSize; 264} 265 266/// ComputeActionsTable - Compute the actions table and gather the first action 267/// index for each landing pad site. 268unsigned DwarfException:: 269ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, 270 SmallVectorImpl<ActionEntry> &Actions, 271 SmallVectorImpl<unsigned> &FirstActions) { 272 // Negative type IDs index into FilterIds. Positive type IDs index into 273 // TypeInfos. The value written for a positive type ID is just the type ID 274 // itself. For a negative type ID, however, the value written is the 275 // (negative) byte offset of the corresponding FilterIds entry. The byte 276 // offset is usually equal to the type ID (because the FilterIds entries are 277 // written using a variable width encoding, which outputs one byte per entry 278 // as long as the value written is not too large) but can differ. This kind 279 // of complication does not occur for positive type IDs because type infos are 280 // output using a fixed width encoding. FilterOffsets[i] holds the byte 281 // offset corresponding to FilterIds[i]. 282 283 const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 284 SmallVector<int, 16> FilterOffsets; 285 FilterOffsets.reserve(FilterIds.size()); 286 int Offset = -1; 287 288 for (std::vector<unsigned>::const_iterator 289 I = FilterIds.begin(), E = FilterIds.end(); I != E; ++I) { 290 FilterOffsets.push_back(Offset); 291 Offset -= TargetAsmInfo::getULEB128Size(*I); 292 } 293 294 FirstActions.reserve(LandingPads.size()); 295 296 int FirstAction = 0; 297 unsigned SizeActions = 0; 298 const LandingPadInfo *PrevLPI = 0; 299 300 for (SmallVectorImpl<const LandingPadInfo *>::const_iterator 301 I = LandingPads.begin(), E = LandingPads.end(); I != E; ++I) { 302 const LandingPadInfo *LPI = *I; 303 const std::vector<int> &TypeIds = LPI->TypeIds; 304 const unsigned NumShared = PrevLPI ? SharedTypeIds(LPI, PrevLPI) : 0; 305 unsigned SizeSiteActions = 0; 306 307 if (NumShared < TypeIds.size()) { 308 unsigned SizeAction = 0; 309 ActionEntry *PrevAction = 0; 310 311 if (NumShared) { 312 const unsigned SizePrevIds = PrevLPI->TypeIds.size(); 313 assert(Actions.size()); 314 PrevAction = &Actions.back(); 315 SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) + 316 TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 317 318 for (unsigned j = NumShared; j != SizePrevIds; ++j) { 319 SizeAction -= 320 TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 321 SizeAction += -PrevAction->NextAction; 322 PrevAction = PrevAction->Previous; 323 } 324 } 325 326 // Compute the actions. 327 for (unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) { 328 int TypeID = TypeIds[J]; 329 assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); 330 int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; 331 unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID); 332 333 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; 334 SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction); 335 SizeSiteActions += SizeAction; 336 337 ActionEntry Action = {ValueForTypeID, NextAction, PrevAction}; 338 Actions.push_back(Action); 339 PrevAction = &Actions.back(); 340 } 341 342 // Record the first action of the landing pad site. 343 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; 344 } // else identical - re-use previous FirstAction 345 346 FirstActions.push_back(FirstAction); 347 348 // Compute this sites contribution to size. 349 SizeActions += SizeSiteActions; 350 351 PrevLPI = LPI; 352 } 353 354 return SizeActions; 355} 356 357/// ComputeCallSiteTable - Compute the call-site table. The entry for an invoke 358/// has a try-range containing the call, a non-zero landing pad and an 359/// appropriate action. The entry for an ordinary call has a try-range 360/// containing the call and zero for the landing pad and the action. Calls 361/// marked 'nounwind' have no entry and must not be contained in the try-range 362/// of any entry - they form gaps in the table. Entries must be ordered by 363/// try-range address. 364void DwarfException:: 365ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, 366 const RangeMapType &PadMap, 367 const SmallVectorImpl<const LandingPadInfo *> &LandingPads, 368 const SmallVectorImpl<unsigned> &FirstActions) { 369 // The end label of the previous invoke or nounwind try-range. 370 unsigned LastLabel = 0; 371 372 // Whether there is a potentially throwing instruction (currently this means 373 // an ordinary call) between the end of the previous try-range and now. 374 bool SawPotentiallyThrowing = false; 375 376 // Whether the last CallSite entry was for an invoke. 377 bool PreviousIsInvoke = false; 378 379 // Visit all instructions in order of address. 380 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 381 I != E; ++I) { 382 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); 383 MI != E; ++MI) { 384 if (!MI->isLabel()) { 385 SawPotentiallyThrowing |= MI->getDesc().isCall(); 386 continue; 387 } 388 389 unsigned BeginLabel = MI->getOperand(0).getImm(); 390 assert(BeginLabel && "Invalid label!"); 391 392 // End of the previous try-range? 393 if (BeginLabel == LastLabel) 394 SawPotentiallyThrowing = false; 395 396 // Beginning of a new try-range? 397 RangeMapType::iterator L = PadMap.find(BeginLabel); 398 if (L == PadMap.end()) 399 // Nope, it was just some random label. 400 continue; 401 402 PadRange P = L->second; 403 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; 404 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && 405 "Inconsistent landing pad map!"); 406 407 // If some instruction between the previous try-range and this one may 408 // throw, create a call-site entry with no landing pad for the region 409 // between the try-ranges. 410 if (SawPotentiallyThrowing) { 411 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0}; 412 CallSites.push_back(Site); 413 PreviousIsInvoke = false; 414 } 415 416 LastLabel = LandingPad->EndLabels[P.RangeIndex]; 417 assert(BeginLabel && LastLabel && "Invalid landing pad!"); 418 419 if (LandingPad->LandingPadLabel) { 420 // This try-range is for an invoke. 421 CallSiteEntry Site = {BeginLabel, LastLabel, 422 LandingPad->LandingPadLabel, 423 FirstActions[P.PadIndex]}; 424 425 // Try to merge with the previous call-site. 426 if (PreviousIsInvoke) { 427 CallSiteEntry &Prev = CallSites.back(); 428 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { 429 // Extend the range of the previous entry. 430 Prev.EndLabel = Site.EndLabel; 431 continue; 432 } 433 } 434 435 // Otherwise, create a new call-site. 436 CallSites.push_back(Site); 437 PreviousIsInvoke = true; 438 } else { 439 // Create a gap. 440 PreviousIsInvoke = false; 441 } 442 } 443 } 444 445 // If some instruction between the previous try-range and the end of the 446 // function may throw, create a call-site entry with no landing pad for the 447 // region following the try-range. 448 if (SawPotentiallyThrowing) { 449 CallSiteEntry Site = {LastLabel, 0, 0, 0}; 450 CallSites.push_back(Site); 451 } 452} 453 454/// EmitExceptionTable - Emit landing pads and actions. 455/// 456/// The general organization of the table is complex, but the basic concepts are 457/// easy. First there is a header which describes the location and organization 458/// of the three components that follow. 459/// 460/// 1. The landing pad site information describes the range of code covered by 461/// the try. In our case it's an accumulation of the ranges covered by the 462/// invokes in the try. There is also a reference to the landing pad that 463/// handles the exception once processed. Finally an index into the actions 464/// table. 465/// 2. The action table, in our case, is composed of pairs of type ids and next 466/// action offset. Starting with the action index from the landing pad 467/// site, each type Id is checked for a match to the current exception. If 468/// it matches then the exception and type id are passed on to the landing 469/// pad. Otherwise the next action is looked up. This chain is terminated 470/// with a next action of zero. If no type id is found the the frame is 471/// unwound and handling continues. 472/// 3. Type id table contains references to all the C++ typeinfo for all 473/// catches in the function. This tables is reversed indexed base 1. 474void DwarfException::EmitExceptionTable() { 475 const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 476 const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 477 const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); 478 if (PadInfos.empty()) return; 479 480 // Sort the landing pads in order of their type ids. This is used to fold 481 // duplicate actions. 482 SmallVector<const LandingPadInfo *, 64> LandingPads; 483 LandingPads.reserve(PadInfos.size()); 484 485 for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) 486 LandingPads.push_back(&PadInfos[i]); 487 488 std::sort(LandingPads.begin(), LandingPads.end(), PadLT); 489 490 // Compute the actions table and gather the first action index for each 491 // landing pad site. 492 SmallVector<ActionEntry, 32> Actions; 493 SmallVector<unsigned, 64> FirstActions; 494 unsigned SizeActions = ComputeActionsTable(LandingPads, Actions, FirstActions); 495 496 // Invokes and nounwind calls have entries in PadMap (due to being bracketed 497 // by try-range labels when lowered). Ordinary calls do not, so appropriate 498 // try-ranges for them need be deduced. 499 RangeMapType PadMap; 500 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 501 const LandingPadInfo *LandingPad = LandingPads[i]; 502 for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { 503 unsigned BeginLabel = LandingPad->BeginLabels[j]; 504 assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); 505 PadRange P = { i, j }; 506 PadMap[BeginLabel] = P; 507 } 508 } 509 510 // Compute the call-site table. 511 SmallVector<CallSiteEntry, 64> CallSites; 512 ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions); 513 514 // Final tallies. 515 516 // Call sites. 517 const unsigned SiteStartSize = sizeof(int32_t); // DW_EH_PE_udata4 518 const unsigned SiteLengthSize = sizeof(int32_t); // DW_EH_PE_udata4 519 const unsigned LandingPadSize = sizeof(int32_t); // DW_EH_PE_udata4 520 unsigned SizeSites = CallSites.size() * (SiteStartSize + 521 SiteLengthSize + 522 LandingPadSize); 523 for (unsigned i = 0, e = CallSites.size(); i < e; ++i) 524 SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action); 525 526 // Type infos. 527 const unsigned TypeInfoSize = TD->getPointerSize(); // DW_EH_PE_absptr 528 unsigned SizeTypes = TypeInfos.size() * TypeInfoSize; 529 530 unsigned TypeOffset = sizeof(int8_t) + // Call site format 531 TargetAsmInfo::getULEB128Size(SizeSites) + // Call-site table length 532 SizeSites + SizeActions + SizeTypes; 533 534 unsigned TotalSize = sizeof(int8_t) + // LPStart format 535 sizeof(int8_t) + // TType format 536 TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset 537 TypeOffset; 538 539 unsigned SizeAlign = (4 - TotalSize) & 3; 540 541 // Begin the exception table. 542 Asm->SwitchToDataSection(TAI->getDwarfExceptionSection()); 543 Asm->EmitAlignment(2, 0, 0, false); 544 O << "GCC_except_table" << SubprogramCount << ":\n"; 545 546 for (unsigned i = 0; i != SizeAlign; ++i) { 547 Asm->EmitInt8(0); 548 Asm->EOL("Padding"); 549 } 550 551 EmitLabel("exception", SubprogramCount); 552 553 // Emit the header. 554 Asm->EmitInt8(dwarf::DW_EH_PE_omit); 555 Asm->EOL("LPStart format (DW_EH_PE_omit)"); 556 557#if 0 558 // FIXME: This should default to what the system wants, not just "absptr". 559 if (!TypeInfos.empty() || !FilterIds.empty()) { 560 Asm->EmitInt8(TAI->PreferredEHDataFormat(DwarfEncoding::Data, true)); 561 // FIXME: The comment here should correspond with what PreferredEHDataFormat 562 // returned. 563 Asm->EOL("TType format (DW_EH_PE_xxxxx)"); 564 Asm->EmitULEB128Bytes(TypeOffset); 565 Asm->EOL("TType base offset"); 566 } else { 567 Asm->EmitInt8(dwarf::DW_EH_PE_omit); 568 Asm->EOL("TType format (DW_EH_PE_omit)"); 569 } 570#else 571 Asm->EmitInt8(dwarf::DW_EH_PE_absptr); 572 Asm->EOL("TType format (DW_EH_PE_absptr)"); 573 Asm->EmitULEB128Bytes(TypeOffset); 574 Asm->EOL("TType base offset"); 575#endif 576 577 Asm->EmitInt8(dwarf::DW_EH_PE_udata4); 578 Asm->EOL("Call site format (DW_EH_PE_udata4)"); 579 Asm->EmitULEB128Bytes(SizeSites); 580 Asm->EOL("Call-site table length"); 581 582 // Emit the landing pad site information. 583 for (SmallVectorImpl<CallSiteEntry>::const_iterator 584 I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { 585 const CallSiteEntry &S = *I; 586 const char *BeginTag; 587 unsigned BeginNumber; 588 589 if (!S.BeginLabel) { 590 BeginTag = "eh_func_begin"; 591 BeginNumber = SubprogramCount; 592 } else { 593 BeginTag = "label"; 594 BeginNumber = S.BeginLabel; 595 } 596 597 EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount, 598 true, true); 599 Asm->EOL("Region start"); 600 601 if (!S.EndLabel) 602 EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber, 603 true); 604 else 605 EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true); 606 607 Asm->EOL("Region length"); 608 609 if (!S.PadLabel) 610 Asm->EmitInt32(0); 611 else 612 EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount, 613 true, true); 614 615 Asm->EOL("Landing pad"); 616 617 Asm->EmitULEB128Bytes(S.Action); 618 Asm->EOL("Action"); 619 } 620 621 // Emit the actions. 622 for (SmallVectorImpl<ActionEntry>::const_iterator 623 I = Actions.begin(), E = Actions.end(); I != E; ++I) { 624 const ActionEntry &Action = *I; 625 Asm->EmitSLEB128Bytes(Action.ValueForTypeID); 626 Asm->EOL("TypeInfo index"); 627 Asm->EmitSLEB128Bytes(Action.NextAction); 628 Asm->EOL("Next action"); 629 } 630 631 // Emit the type ids. 632 for (std::vector<GlobalVariable *>::const_reverse_iterator 633 I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { 634 GlobalVariable *GV = *I; 635 PrintRelDirective(); 636 637 if (GV) { 638 std::string GLN; 639 O << Asm->getGlobalLinkName(GV, GLN); 640 } else { 641 O << "0"; 642 } 643 644 Asm->EOL("TypeInfo"); 645 } 646 647 // Emit the filter typeids. 648 for (std::vector<unsigned>::const_iterator 649 I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { 650 unsigned TypeID = *I; 651 Asm->EmitULEB128Bytes(TypeID); 652 Asm->EOL("Filter TypeInfo index"); 653 } 654 655 Asm->EmitAlignment(2, 0, 0, false); 656} 657 658/// EndModule - Emit all exception information that should come after the 659/// content. 660void DwarfException::EndModule() { 661 if (TimePassesIsEnabled) 662 ExceptionTimer->startTimer(); 663 664 if (shouldEmitMovesModule || shouldEmitTableModule) { 665 const std::vector<Function *> Personalities = MMI->getPersonalities(); 666 for (unsigned i = 0; i < Personalities.size(); ++i) 667 EmitCommonEHFrame(Personalities[i], i); 668 669 for (std::vector<FunctionEHFrameInfo>::iterator I = EHFrames.begin(), 670 E = EHFrames.end(); I != E; ++I) 671 EmitEHFrame(*I); 672 } 673 674 if (TimePassesIsEnabled) 675 ExceptionTimer->stopTimer(); 676} 677 678/// BeginFunction - Gather pre-function exception information. Assumes being 679/// emitted immediately after the function entry point. 680void DwarfException::BeginFunction(MachineFunction *MF) { 681 if (TimePassesIsEnabled) 682 ExceptionTimer->startTimer(); 683 684 this->MF = MF; 685 shouldEmitTable = shouldEmitMoves = false; 686 687 if (MMI && TAI->doesSupportExceptionHandling()) { 688 // Map all labels and get rid of any dead landing pads. 689 MMI->TidyLandingPads(); 690 691 // If any landing pads survive, we need an EH table. 692 if (MMI->getLandingPads().size()) 693 shouldEmitTable = true; 694 695 // See if we need frame move info. 696 if (!MF->getFunction()->doesNotThrow() || UnwindTablesMandatory) 697 shouldEmitMoves = true; 698 699 if (shouldEmitMoves || shouldEmitTable) 700 // Assumes in correct section after the entry point. 701 EmitLabel("eh_func_begin", ++SubprogramCount); 702 } 703 704 shouldEmitTableModule |= shouldEmitTable; 705 shouldEmitMovesModule |= shouldEmitMoves; 706 707 if (TimePassesIsEnabled) 708 ExceptionTimer->stopTimer(); 709} 710 711/// EndFunction - Gather and emit post-function exception information. 712/// 713void DwarfException::EndFunction() { 714 if (TimePassesIsEnabled) 715 ExceptionTimer->startTimer(); 716 717 if (shouldEmitMoves || shouldEmitTable) { 718 EmitLabel("eh_func_end", SubprogramCount); 719 EmitExceptionTable(); 720 721 // Save EH frame information 722 EHFrames.push_back( 723 FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF), 724 SubprogramCount, 725 MMI->getPersonalityIndex(), 726 MF->getFrameInfo()->hasCalls(), 727 !MMI->getLandingPads().empty(), 728 MMI->getFrameMoves(), 729 MF->getFunction())); 730 } 731 732 if (TimePassesIsEnabled) 733 ExceptionTimer->stopTimer(); 734} 735