DwarfException.cpp revision 0530f42b442cdcca775f7163b95b5b0d99a4a9b4
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->doesRequireNonLocalEHFrameLabel()) 61 O << TAI->getEHGlobalPrefix(); 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 Function::LinkageTypes linkage = EHFrameInfo.function->getLinkage(); 151 Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection()); 152 153 // Externally visible entry into the functions eh frame info. If the 154 // corresponding function is static, this should not be externally visible. 155 if (linkage != Function::InternalLinkage && 156 linkage != Function::PrivateLinkage) { 157 if (const char *GlobalEHDirective = TAI->getGlobalEHDirective()) 158 O << GlobalEHDirective << EHFrameInfo.FnName << "\n"; 159 } 160 161 // If corresponding function is weak definition, this should be too. 162 if ((linkage == Function::WeakAnyLinkage || 163 linkage == Function::WeakODRLinkage || 164 linkage == Function::LinkOnceAnyLinkage || 165 linkage == Function::LinkOnceODRLinkage) && 166 TAI->getWeakDefDirective()) 167 O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n"; 168 169 // If there are no calls then you can't unwind. This may mean we can omit the 170 // EH Frame, but some environments do not handle weak absolute symbols. If 171 // UnwindTablesMandatory is set we cannot do this optimization; the unwind 172 // info is to be available for non-EH uses. 173 if (!EHFrameInfo.hasCalls && 174 !UnwindTablesMandatory && 175 ((linkage != Function::WeakAnyLinkage && 176 linkage != Function::WeakODRLinkage && 177 linkage != Function::LinkOnceAnyLinkage && 178 linkage != Function::LinkOnceODRLinkage) || 179 !TAI->getWeakDefDirective() || 180 TAI->getSupportsWeakOmittedEHFrame())) { 181 O << EHFrameInfo.FnName << " = 0\n"; 182 // This name has no connection to the function, so it might get 183 // dead-stripped when the function is not, erroneously. Prohibit 184 // dead-stripping unconditionally. 185 if (const char *UsedDirective = TAI->getUsedDirective()) 186 O << UsedDirective << EHFrameInfo.FnName << "\n\n"; 187 } else { 188 O << EHFrameInfo.FnName << ":\n"; 189 190 // EH frame header. 191 EmitDifference("eh_frame_end", EHFrameInfo.Number, 192 "eh_frame_begin", EHFrameInfo.Number, true); 193 Asm->EOL("Length of Frame Information Entry"); 194 195 EmitLabel("eh_frame_begin", EHFrameInfo.Number); 196 197 if (TAI->doesRequireNonLocalEHFrameLabel()) { 198 PrintRelDirective(true, true); 199 PrintLabelName("eh_frame_begin", EHFrameInfo.Number); 200 201 if (!TAI->isAbsoluteEHSectionOffsets()) 202 O << "-EH_frame" << EHFrameInfo.PersonalityIndex; 203 } else { 204 EmitSectionOffset("eh_frame_begin", "eh_frame_common", 205 EHFrameInfo.Number, EHFrameInfo.PersonalityIndex, 206 true, true, false); 207 } 208 209 Asm->EOL("FDE CIE offset"); 210 211 EmitReference("eh_func_begin", EHFrameInfo.Number, true, true); 212 Asm->EOL("FDE initial location"); 213 EmitDifference("eh_func_end", EHFrameInfo.Number, 214 "eh_func_begin", EHFrameInfo.Number, true); 215 Asm->EOL("FDE address range"); 216 217 // If there is a personality and landing pads then point to the language 218 // specific data area in the exception table. 219 if (EHFrameInfo.PersonalityIndex) { 220 Asm->EmitULEB128Bytes(4); 221 Asm->EOL("Augmentation size"); 222 223 if (EHFrameInfo.hasLandingPads) 224 EmitReference("exception", EHFrameInfo.Number, true, true); 225 else 226 Asm->EmitInt32((int)0); 227 Asm->EOL("Language Specific Data Area"); 228 } else { 229 Asm->EmitULEB128Bytes(0); 230 Asm->EOL("Augmentation size"); 231 } 232 233 // Indicate locations of function specific callee saved registers in frame. 234 EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, 235 true); 236 237 // On Darwin the linker honors the alignment of eh_frame, which means it 238 // must be 8-byte on 64-bit targets to match what gcc does. Otherwise you 239 // get holes which confuse readers of eh_frame. 240 Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, 241 0, 0, false); 242 EmitLabel("eh_frame_end", EHFrameInfo.Number); 243 244 // If the function is marked used, this table should be also. We cannot 245 // make the mark unconditional in this case, since retaining the table also 246 // retains the function in this case, and there is code around that depends 247 // on unused functions (calling undefined externals) being dead-stripped to 248 // link correctly. Yes, there really is. 249 if (MMI->getUsedFunctions().count(EHFrameInfo.function)) 250 if (const char *UsedDirective = TAI->getUsedDirective()) 251 O << UsedDirective << EHFrameInfo.FnName << "\n\n"; 252 } 253} 254 255/// EmitExceptionTable - Emit landing pads and actions. 256/// 257/// The general organization of the table is complex, but the basic concepts are 258/// easy. First there is a header which describes the location and organization 259/// of the three components that follow. 260/// 261/// 1. The landing pad site information describes the range of code covered by 262/// the try. In our case it's an accumulation of the ranges covered by the 263/// invokes in the try. There is also a reference to the landing pad that 264/// handles the exception once processed. Finally an index into the actions 265/// table. 266/// 2. The action table, in our case, is composed of pairs of type ids and next 267/// action offset. Starting with the action index from the landing pad 268/// site, each type Id is checked for a match to the current exception. If 269/// it matches then the exception and type id are passed on to the landing 270/// pad. Otherwise the next action is looked up. This chain is terminated 271/// with a next action of zero. If no type id is found the the frame is 272/// unwound and handling continues. 273/// 3. Type id table contains references to all the C++ typeinfo for all 274/// catches in the function. This tables is reversed indexed base 1. 275 276/// SharedTypeIds - How many leading type ids two landing pads have in common. 277unsigned DwarfException::SharedTypeIds(const LandingPadInfo *L, 278 const LandingPadInfo *R) { 279 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 280 unsigned LSize = LIds.size(), RSize = RIds.size(); 281 unsigned MinSize = LSize < RSize ? LSize : RSize; 282 unsigned Count = 0; 283 284 for (; Count != MinSize; ++Count) 285 if (LIds[Count] != RIds[Count]) 286 return Count; 287 288 return Count; 289} 290 291/// PadLT - Order landing pads lexicographically by type id. 292bool DwarfException::PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { 293 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 294 unsigned LSize = LIds.size(), RSize = RIds.size(); 295 unsigned MinSize = LSize < RSize ? LSize : RSize; 296 297 for (unsigned i = 0; i != MinSize; ++i) 298 if (LIds[i] != RIds[i]) 299 return LIds[i] < RIds[i]; 300 301 return LSize < RSize; 302} 303 304void DwarfException::EmitExceptionTable() { 305 const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 306 const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 307 const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); 308 if (PadInfos.empty()) return; 309 310 // Sort the landing pads in order of their type ids. This is used to fold 311 // duplicate actions. 312 SmallVector<const LandingPadInfo *, 64> LandingPads; 313 LandingPads.reserve(PadInfos.size()); 314 for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) 315 LandingPads.push_back(&PadInfos[i]); 316 std::sort(LandingPads.begin(), LandingPads.end(), PadLT); 317 318 // Negative type ids index into FilterIds, positive type ids index into 319 // TypeInfos. The value written for a positive type id is just the type id 320 // itself. For a negative type id, however, the value written is the 321 // (negative) byte offset of the corresponding FilterIds entry. The byte 322 // offset is usually equal to the type id, because the FilterIds entries are 323 // written using a variable width encoding which outputs one byte per entry as 324 // long as the value written is not too large, but can differ. This kind of 325 // complication does not occur for positive type ids because type infos are 326 // output using a fixed width encoding. FilterOffsets[i] holds the byte 327 // offset corresponding to FilterIds[i]. 328 SmallVector<int, 16> FilterOffsets; 329 FilterOffsets.reserve(FilterIds.size()); 330 int Offset = -1; 331 for(std::vector<unsigned>::const_iterator I = FilterIds.begin(), 332 E = FilterIds.end(); I != E; ++I) { 333 FilterOffsets.push_back(Offset); 334 Offset -= TargetAsmInfo::getULEB128Size(*I); 335 } 336 337 // Compute the actions table and gather the first action index for each 338 // landing pad site. 339 SmallVector<ActionEntry, 32> Actions; 340 SmallVector<unsigned, 64> FirstActions; 341 FirstActions.reserve(LandingPads.size()); 342 343 int FirstAction = 0; 344 unsigned SizeActions = 0; 345 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 346 const LandingPadInfo *LP = LandingPads[i]; 347 const std::vector<int> &TypeIds = LP->TypeIds; 348 const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0; 349 unsigned SizeSiteActions = 0; 350 351 if (NumShared < TypeIds.size()) { 352 unsigned SizeAction = 0; 353 ActionEntry *PrevAction = 0; 354 355 if (NumShared) { 356 const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size(); 357 assert(Actions.size()); 358 PrevAction = &Actions.back(); 359 SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) + 360 TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 361 362 for (unsigned j = NumShared; j != SizePrevIds; ++j) { 363 SizeAction -= 364 TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 365 SizeAction += -PrevAction->NextAction; 366 PrevAction = PrevAction->Previous; 367 } 368 } 369 370 // Compute the actions. 371 for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) { 372 int TypeID = TypeIds[I]; 373 assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); 374 int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; 375 unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID); 376 377 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; 378 SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction); 379 SizeSiteActions += SizeAction; 380 381 ActionEntry Action = {ValueForTypeID, NextAction, PrevAction}; 382 Actions.push_back(Action); 383 384 PrevAction = &Actions.back(); 385 } 386 387 // Record the first action of the landing pad site. 388 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; 389 } // else identical - re-use previous FirstAction 390 391 FirstActions.push_back(FirstAction); 392 393 // Compute this sites contribution to size. 394 SizeActions += SizeSiteActions; 395 } 396 397 // Compute the call-site table. The entry for an invoke has a try-range 398 // containing the call, a non-zero landing pad and an appropriate action. The 399 // entry for an ordinary call has a try-range containing the call and zero for 400 // the landing pad and the action. Calls marked 'nounwind' have no entry and 401 // must not be contained in the try-range of any entry - they form gaps in the 402 // table. Entries must be ordered by try-range address. 403 SmallVector<CallSiteEntry, 64> CallSites; 404 405 RangeMapType PadMap; 406 407 // Invokes and nounwind calls have entries in PadMap (due to being bracketed 408 // by try-range labels when lowered). Ordinary calls do not, so appropriate 409 // try-ranges for them need be deduced. 410 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 411 const LandingPadInfo *LandingPad = LandingPads[i]; 412 for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { 413 unsigned BeginLabel = LandingPad->BeginLabels[j]; 414 assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); 415 PadRange P = { i, j }; 416 PadMap[BeginLabel] = P; 417 } 418 } 419 420 // The end label of the previous invoke or nounwind try-range. 421 unsigned LastLabel = 0; 422 423 // Whether there is a potentially throwing instruction (currently this means 424 // an ordinary call) between the end of the previous try-range and now. 425 bool SawPotentiallyThrowing = false; 426 427 // Whether the last callsite entry was for an invoke. 428 bool PreviousIsInvoke = false; 429 430 // Visit all instructions in order of address. 431 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 432 I != E; ++I) { 433 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); 434 MI != E; ++MI) { 435 if (!MI->isLabel()) { 436 SawPotentiallyThrowing |= MI->getDesc().isCall(); 437 continue; 438 } 439 440 unsigned BeginLabel = MI->getOperand(0).getImm(); 441 assert(BeginLabel && "Invalid label!"); 442 443 // End of the previous try-range? 444 if (BeginLabel == LastLabel) 445 SawPotentiallyThrowing = false; 446 447 // Beginning of a new try-range? 448 RangeMapType::iterator L = PadMap.find(BeginLabel); 449 if (L == PadMap.end()) 450 // Nope, it was just some random label. 451 continue; 452 453 PadRange P = L->second; 454 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; 455 456 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && 457 "Inconsistent landing pad map!"); 458 459 // If some instruction between the previous try-range and this one may 460 // throw, create a call-site entry with no landing pad for the region 461 // between the try-ranges. 462 if (SawPotentiallyThrowing) { 463 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0}; 464 CallSites.push_back(Site); 465 PreviousIsInvoke = false; 466 } 467 468 LastLabel = LandingPad->EndLabels[P.RangeIndex]; 469 assert(BeginLabel && LastLabel && "Invalid landing pad!"); 470 471 if (LandingPad->LandingPadLabel) { 472 // This try-range is for an invoke. 473 CallSiteEntry Site = {BeginLabel, LastLabel, 474 LandingPad->LandingPadLabel, 475 FirstActions[P.PadIndex]}; 476 477 // Try to merge with the previous call-site. 478 if (PreviousIsInvoke) { 479 CallSiteEntry &Prev = CallSites.back(); 480 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { 481 // Extend the range of the previous entry. 482 Prev.EndLabel = Site.EndLabel; 483 continue; 484 } 485 } 486 487 // Otherwise, create a new call-site. 488 CallSites.push_back(Site); 489 PreviousIsInvoke = true; 490 } else { 491 // Create a gap. 492 PreviousIsInvoke = false; 493 } 494 } 495 } 496 497 // If some instruction between the previous try-range and the end of the 498 // function may throw, create a call-site entry with no landing pad for the 499 // region following the try-range. 500 if (SawPotentiallyThrowing) { 501 CallSiteEntry Site = {LastLabel, 0, 0, 0}; 502 CallSites.push_back(Site); 503 } 504 505 // Final tallies. 506 507 // Call sites. 508 const unsigned SiteStartSize = sizeof(int32_t); // DW_EH_PE_udata4 509 const unsigned SiteLengthSize = sizeof(int32_t); // DW_EH_PE_udata4 510 const unsigned LandingPadSize = sizeof(int32_t); // DW_EH_PE_udata4 511 unsigned SizeSites = CallSites.size() * (SiteStartSize + 512 SiteLengthSize + 513 LandingPadSize); 514 for (unsigned i = 0, e = CallSites.size(); i < e; ++i) 515 SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action); 516 517 // Type infos. 518 const unsigned TypeInfoSize = TD->getPointerSize(); // DW_EH_PE_absptr 519 unsigned SizeTypes = TypeInfos.size() * TypeInfoSize; 520 521 unsigned TypeOffset = sizeof(int8_t) + // Call site format 522 TargetAsmInfo::getULEB128Size(SizeSites) + // Call-site table length 523 SizeSites + SizeActions + SizeTypes; 524 525 unsigned TotalSize = sizeof(int8_t) + // LPStart format 526 sizeof(int8_t) + // TType format 527 TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset 528 TypeOffset; 529 530 unsigned SizeAlign = (4 - TotalSize) & 3; 531 532 // Begin the exception table. 533 Asm->SwitchToDataSection(TAI->getDwarfExceptionSection()); 534 Asm->EmitAlignment(2, 0, 0, false); 535 O << "GCC_except_table" << SubprogramCount << ":\n"; 536 537 for (unsigned i = 0; i != SizeAlign; ++i) { 538 Asm->EmitInt8(0); 539 Asm->EOL("Padding"); 540 } 541 542 EmitLabel("exception", SubprogramCount); 543 544 // Emit the header. 545 Asm->EmitInt8(dwarf::DW_EH_PE_omit); 546 Asm->EOL("LPStart format (DW_EH_PE_omit)"); 547 Asm->EmitInt8(dwarf::DW_EH_PE_absptr); 548 Asm->EOL("TType format (DW_EH_PE_absptr)"); 549 Asm->EmitULEB128Bytes(TypeOffset); 550 Asm->EOL("TType base offset"); 551 Asm->EmitInt8(dwarf::DW_EH_PE_udata4); 552 Asm->EOL("Call site format (DW_EH_PE_udata4)"); 553 Asm->EmitULEB128Bytes(SizeSites); 554 Asm->EOL("Call-site table length"); 555 556 // Emit the landing pad site information. 557 for (unsigned i = 0; i < CallSites.size(); ++i) { 558 CallSiteEntry &S = CallSites[i]; 559 const char *BeginTag; 560 unsigned BeginNumber; 561 562 if (!S.BeginLabel) { 563 BeginTag = "eh_func_begin"; 564 BeginNumber = SubprogramCount; 565 } else { 566 BeginTag = "label"; 567 BeginNumber = S.BeginLabel; 568 } 569 570 EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount, 571 true, true); 572 Asm->EOL("Region start"); 573 574 if (!S.EndLabel) 575 EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber, 576 true); 577 else 578 EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true); 579 580 Asm->EOL("Region length"); 581 582 if (!S.PadLabel) 583 Asm->EmitInt32(0); 584 else 585 EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount, 586 true, true); 587 588 Asm->EOL("Landing pad"); 589 590 Asm->EmitULEB128Bytes(S.Action); 591 Asm->EOL("Action"); 592 } 593 594 // Emit the actions. 595 for (unsigned I = 0, N = Actions.size(); I != N; ++I) { 596 ActionEntry &Action = Actions[I]; 597 598 Asm->EmitSLEB128Bytes(Action.ValueForTypeID); 599 Asm->EOL("TypeInfo index"); 600 Asm->EmitSLEB128Bytes(Action.NextAction); 601 Asm->EOL("Next action"); 602 } 603 604 // Emit the type ids. 605 for (unsigned M = TypeInfos.size(); M; --M) { 606 GlobalVariable *GV = TypeInfos[M - 1]; 607 PrintRelDirective(); 608 609 if (GV) { 610 std::string GLN; 611 O << Asm->getGlobalLinkName(GV, GLN); 612 } else { 613 O << "0"; 614 } 615 616 Asm->EOL("TypeInfo"); 617 } 618 619 // Emit the filter typeids. 620 for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) { 621 unsigned TypeID = FilterIds[j]; 622 Asm->EmitULEB128Bytes(TypeID); 623 Asm->EOL("Filter TypeInfo index"); 624 } 625 626 Asm->EmitAlignment(2, 0, 0, false); 627} 628 629/// EndModule - Emit all exception information that should come after the 630/// content. 631void DwarfException::EndModule() { 632 if (TimePassesIsEnabled) 633 ExceptionTimer->startTimer(); 634 635 if (shouldEmitMovesModule || shouldEmitTableModule) { 636 const std::vector<Function *> Personalities = MMI->getPersonalities(); 637 for (unsigned i = 0; i < Personalities.size(); ++i) 638 EmitCommonEHFrame(Personalities[i], i); 639 640 for (std::vector<FunctionEHFrameInfo>::iterator I = EHFrames.begin(), 641 E = EHFrames.end(); I != E; ++I) 642 EmitEHFrame(*I); 643 } 644 645 if (TimePassesIsEnabled) 646 ExceptionTimer->stopTimer(); 647} 648 649/// BeginFunction - Gather pre-function exception information. Assumes being 650/// emitted immediately after the function entry point. 651void DwarfException::BeginFunction(MachineFunction *MF) { 652 if (TimePassesIsEnabled) 653 ExceptionTimer->startTimer(); 654 655 this->MF = MF; 656 shouldEmitTable = shouldEmitMoves = false; 657 658 if (MMI && TAI->doesSupportExceptionHandling()) { 659 // Map all labels and get rid of any dead landing pads. 660 MMI->TidyLandingPads(); 661 662 // If any landing pads survive, we need an EH table. 663 if (MMI->getLandingPads().size()) 664 shouldEmitTable = true; 665 666 // See if we need frame move info. 667 if (!MF->getFunction()->doesNotThrow() || UnwindTablesMandatory) 668 shouldEmitMoves = true; 669 670 if (shouldEmitMoves || shouldEmitTable) 671 // Assumes in correct section after the entry point. 672 EmitLabel("eh_func_begin", ++SubprogramCount); 673 } 674 675 shouldEmitTableModule |= shouldEmitTable; 676 shouldEmitMovesModule |= shouldEmitMoves; 677 678 if (TimePassesIsEnabled) 679 ExceptionTimer->stopTimer(); 680} 681 682/// EndFunction - Gather and emit post-function exception information. 683/// 684void DwarfException::EndFunction() { 685 if (TimePassesIsEnabled) 686 ExceptionTimer->startTimer(); 687 688 if (shouldEmitMoves || shouldEmitTable) { 689 EmitLabel("eh_func_end", SubprogramCount); 690 EmitExceptionTable(); 691 692 // Save EH frame information 693 std::string Name; 694 EHFrames.push_back( 695 FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF, Name), 696 SubprogramCount, 697 MMI->getPersonalityIndex(), 698 MF->getFrameInfo()->hasCalls(), 699 !MMI->getLandingPads().empty(), 700 MMI->getFrameMoves(), 701 MF->getFunction())); 702 } 703 704 if (TimePassesIsEnabled) 705 ExceptionTimer->stopTimer(); 706} 707