DwarfException.cpp revision a14f4474b2d915579e9e9bd8bf4080d7f25e7dcd
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/MachineFunction.h" 19#include "llvm/CodeGen/MachineLocation.h" 20#include "llvm/MC/MCStreamer.h" 21#include "llvm/MC/MCAsmInfo.h" 22#include "llvm/Target/TargetData.h" 23#include "llvm/Target/TargetFrameInfo.h" 24#include "llvm/Target/TargetLoweringObjectFile.h" 25#include "llvm/Target/TargetOptions.h" 26#include "llvm/Target/TargetRegisterInfo.h" 27#include "llvm/Support/Dwarf.h" 28#include "llvm/Support/Timer.h" 29#include "llvm/Support/raw_ostream.h" 30#include "llvm/ADT/StringExtras.h" 31using namespace llvm; 32 33static TimerGroup &getDwarfTimerGroup() { 34 static TimerGroup DwarfTimerGroup("Dwarf Exception"); 35 return DwarfTimerGroup; 36} 37 38DwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A, 39 const MCAsmInfo *T) 40 : Dwarf(OS, A, T, "eh"), shouldEmitTable(false), shouldEmitMoves(false), 41 shouldEmitTableModule(false), shouldEmitMovesModule(false), 42 ExceptionTimer(0) { 43 if (TimePassesIsEnabled) 44 ExceptionTimer = new Timer("Dwarf Exception Writer", 45 getDwarfTimerGroup()); 46} 47 48DwarfException::~DwarfException() { 49 delete ExceptionTimer; 50} 51 52/// EmitCIE - Emit a Common Information Entry (CIE). This holds information that 53/// is shared among many Frame Description Entries. There is at least one CIE 54/// in every non-empty .debug_frame section. 55void DwarfException::EmitCIE(const Function *Personality, unsigned Index) { 56 // Size and sign of stack growth. 57 int stackGrowth = 58 Asm->TM.getFrameInfo()->getStackGrowthDirection() == 59 TargetFrameInfo::StackGrowsUp ? 60 TD->getPointerSize() : -TD->getPointerSize(); 61 62 // Begin eh frame section. 63 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getEHFrameSection()); 64 65 if (MAI->is_EHSymbolPrivate()) 66 O << MAI->getPrivateGlobalPrefix(); 67 68 O << "EH_frame" << Index << ":\n"; 69 EmitLabel("section_eh_frame", Index); 70 71 // Define base labels. 72 EmitLabel("eh_frame_common", Index); 73 74 // Define the eh frame length. 75 EmitDifference("eh_frame_common_end", Index, 76 "eh_frame_common_begin", Index, true); 77 Asm->EOL("Length of Common Information Entry"); 78 79 // EH frame header. 80 EmitLabel("eh_frame_common_begin", Index); 81 Asm->EmitInt32((int)0); 82 Asm->EOL("CIE Identifier Tag"); 83 Asm->EmitInt8(dwarf::DW_CIE_VERSION); 84 Asm->EOL("CIE Version"); 85 86 // The personality presence indicates that language specific information will 87 // show up in the eh frame. 88 Asm->EmitString(Personality ? "zPLR" : "zR"); 89 Asm->EOL("CIE Augmentation"); 90 91 // Round out reader. 92 Asm->EmitULEB128Bytes(1); 93 Asm->EOL("CIE Code Alignment Factor"); 94 Asm->EmitSLEB128Bytes(stackGrowth); 95 Asm->EOL("CIE Data Alignment Factor"); 96 Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true)); 97 Asm->EOL("CIE Return Address Column"); 98 99 // If there is a personality, we need to indicate the function's location. 100 if (Personality) { 101 Asm->EmitULEB128Bytes(7); 102 Asm->EOL("Augmentation Size"); 103 104 if (MAI->getNeedsIndirectEncoding()) { 105 Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 | 106 dwarf::DW_EH_PE_indirect); 107 Asm->EOL("Personality (pcrel sdata4 indirect)"); 108 } else { 109 Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 110 Asm->EOL("Personality (pcrel sdata4)"); 111 } 112 113 PrintRelDirective(true); 114 O << MAI->getPersonalityPrefix(); 115 Asm->EmitExternalGlobal((const GlobalVariable *)(Personality)); 116 O << MAI->getPersonalitySuffix(); 117 if (strcmp(MAI->getPersonalitySuffix(), "+4@GOTPCREL")) 118 O << "-" << MAI->getPCSymbol(); 119 Asm->EOL("Personality"); 120 121 Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 122 Asm->EOL("LSDA Encoding (pcrel sdata4)"); 123 124 Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 125 Asm->EOL("FDE Encoding (pcrel sdata4)"); 126 } else { 127 Asm->EmitULEB128Bytes(1); 128 Asm->EOL("Augmentation Size"); 129 130 Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 131 Asm->EOL("FDE Encoding (pcrel sdata4)"); 132 } 133 134 // Indicate locations of general callee saved registers in frame. 135 std::vector<MachineMove> Moves; 136 RI->getInitialFrameState(Moves); 137 EmitFrameMoves(NULL, 0, Moves, true); 138 139 // On Darwin the linker honors the alignment of eh_frame, which means it must 140 // be 8-byte on 64-bit targets to match what gcc does. Otherwise you get 141 // holes which confuse readers of eh_frame. 142 Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, 143 0, 0, false); 144 EmitLabel("eh_frame_common_end", Index); 145 146 Asm->EOL(); 147} 148 149/// EmitFDE - Emit the Frame Description Entry (FDE) for the function. 150void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { 151 assert(!EHFrameInfo.function->hasAvailableExternallyLinkage() && 152 "Should not emit 'available externally' functions at all"); 153 154 const Function *TheFunc = EHFrameInfo.function; 155 156 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getEHFrameSection()); 157 158 // Externally visible entry into the functions eh frame info. If the 159 // corresponding function is static, this should not be externally visible. 160 if (!TheFunc->hasLocalLinkage()) 161 if (const char *GlobalEHDirective = MAI->getGlobalEHDirective()) 162 O << GlobalEHDirective << EHFrameInfo.FnName << "\n"; 163 164 // If corresponding function is weak definition, this should be too. 165 if (TheFunc->isWeakForLinker() && MAI->getWeakDefDirective()) 166 O << MAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n"; 167 168 // If there are no calls then you can't unwind. This may mean we can omit the 169 // EH Frame, but some environments do not handle weak absolute symbols. If 170 // UnwindTablesMandatory is set we cannot do this optimization; the unwind 171 // info is to be available for non-EH uses. 172 if (!EHFrameInfo.hasCalls && !UnwindTablesMandatory && 173 (!TheFunc->isWeakForLinker() || 174 !MAI->getWeakDefDirective() || 175 MAI->getSupportsWeakOmittedEHFrame())) { 176 O << EHFrameInfo.FnName << " = 0\n"; 177 // This name has no connection to the function, so it might get 178 // dead-stripped when the function is not, erroneously. Prohibit 179 // dead-stripping unconditionally. 180 if (const char *UsedDirective = MAI->getUsedDirective()) 181 O << UsedDirective << EHFrameInfo.FnName << "\n\n"; 182 } else { 183 O << EHFrameInfo.FnName << ":\n"; 184 185 // EH frame header. 186 EmitDifference("eh_frame_end", EHFrameInfo.Number, 187 "eh_frame_begin", EHFrameInfo.Number, true); 188 Asm->EOL("Length of Frame Information Entry"); 189 190 EmitLabel("eh_frame_begin", EHFrameInfo.Number); 191 192 EmitSectionOffset("eh_frame_begin", "eh_frame_common", 193 EHFrameInfo.Number, EHFrameInfo.PersonalityIndex, 194 true, true, false); 195 196 Asm->EOL("FDE CIE offset"); 197 198 EmitReference("eh_func_begin", EHFrameInfo.Number, true, true); 199 Asm->EOL("FDE initial location"); 200 EmitDifference("eh_func_end", EHFrameInfo.Number, 201 "eh_func_begin", EHFrameInfo.Number, true); 202 Asm->EOL("FDE address range"); 203 204 // If there is a personality and landing pads then point to the language 205 // specific data area in the exception table. 206 if (MMI->getPersonalities()[0] != NULL) { 207 Asm->EmitULEB128Bytes(4); 208 Asm->EOL("Augmentation size"); 209 210 if (EHFrameInfo.hasLandingPads) 211 EmitReference("exception", EHFrameInfo.Number, true, true); 212 else 213 Asm->EmitInt32((int)0); 214 Asm->EOL("Language Specific Data Area"); 215 } else { 216 Asm->EmitULEB128Bytes(0); 217 Asm->EOL("Augmentation size"); 218 } 219 220 // Indicate locations of function specific callee saved registers in frame. 221 EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, 222 true); 223 224 // On Darwin the linker honors the alignment of eh_frame, which means it 225 // must be 8-byte on 64-bit targets to match what gcc does. Otherwise you 226 // get holes which confuse readers of eh_frame. 227 Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, 228 0, 0, false); 229 EmitLabel("eh_frame_end", EHFrameInfo.Number); 230 231 // If the function is marked used, this table should be also. We cannot 232 // make the mark unconditional in this case, since retaining the table also 233 // retains the function in this case, and there is code around that depends 234 // on unused functions (calling undefined externals) being dead-stripped to 235 // link correctly. Yes, there really is. 236 if (MMI->isUsedFunction(EHFrameInfo.function)) 237 if (const char *UsedDirective = MAI->getUsedDirective()) 238 O << UsedDirective << EHFrameInfo.FnName << "\n\n"; 239 } 240 241 Asm->EOL(); 242} 243 244/// SharedTypeIds - How many leading type ids two landing pads have in common. 245unsigned DwarfException::SharedTypeIds(const LandingPadInfo *L, 246 const LandingPadInfo *R) { 247 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 248 unsigned LSize = LIds.size(), RSize = RIds.size(); 249 unsigned MinSize = LSize < RSize ? LSize : RSize; 250 unsigned Count = 0; 251 252 for (; Count != MinSize; ++Count) 253 if (LIds[Count] != RIds[Count]) 254 return Count; 255 256 return Count; 257} 258 259/// PadLT - Order landing pads lexicographically by type id. 260bool DwarfException::PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { 261 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 262 unsigned LSize = LIds.size(), RSize = RIds.size(); 263 unsigned MinSize = LSize < RSize ? LSize : RSize; 264 265 for (unsigned i = 0; i != MinSize; ++i) 266 if (LIds[i] != RIds[i]) 267 return LIds[i] < RIds[i]; 268 269 return LSize < RSize; 270} 271 272/// ComputeActionsTable - Compute the actions table and gather the first action 273/// index for each landing pad site. 274unsigned DwarfException:: 275ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, 276 SmallVectorImpl<ActionEntry> &Actions, 277 SmallVectorImpl<unsigned> &FirstActions) { 278 279 // The action table follows the call-site table in the LSDA. The individual 280 // records are of two types: 281 // 282 // * Catch clause 283 // * Exception specification 284 // 285 // The two record kinds have the same format, with only small differences. 286 // They are distinguished by the "switch value" field: Catch clauses 287 // (TypeInfos) have strictly positive switch values, and exception 288 // specifications (FilterIds) have strictly negative switch values. Value 0 289 // indicates a catch-all clause. 290 // 291 // Negative type IDs index into FilterIds. Positive type IDs index into 292 // TypeInfos. The value written for a positive type ID is just the type ID 293 // itself. For a negative type ID, however, the value written is the 294 // (negative) byte offset of the corresponding FilterIds entry. The byte 295 // offset is usually equal to the type ID (because the FilterIds entries are 296 // written using a variable width encoding, which outputs one byte per entry 297 // as long as the value written is not too large) but can differ. This kind 298 // of complication does not occur for positive type IDs because type infos are 299 // output using a fixed width encoding. FilterOffsets[i] holds the byte 300 // offset corresponding to FilterIds[i]. 301 302 const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 303 SmallVector<int, 16> FilterOffsets; 304 FilterOffsets.reserve(FilterIds.size()); 305 int Offset = -1; 306 307 for (std::vector<unsigned>::const_iterator 308 I = FilterIds.begin(), E = FilterIds.end(); I != E; ++I) { 309 FilterOffsets.push_back(Offset); 310 Offset -= MCAsmInfo::getULEB128Size(*I); 311 } 312 313 FirstActions.reserve(LandingPads.size()); 314 315 int FirstAction = 0; 316 unsigned SizeActions = 0; 317 const LandingPadInfo *PrevLPI = 0; 318 319 for (SmallVectorImpl<const LandingPadInfo *>::const_iterator 320 I = LandingPads.begin(), E = LandingPads.end(); I != E; ++I) { 321 const LandingPadInfo *LPI = *I; 322 const std::vector<int> &TypeIds = LPI->TypeIds; 323 const unsigned NumShared = PrevLPI ? SharedTypeIds(LPI, PrevLPI) : 0; 324 unsigned SizeSiteActions = 0; 325 326 if (NumShared < TypeIds.size()) { 327 unsigned SizeAction = 0; 328 ActionEntry *PrevAction = 0; 329 330 if (NumShared) { 331 const unsigned SizePrevIds = PrevLPI->TypeIds.size(); 332 assert(Actions.size()); 333 PrevAction = &Actions.back(); 334 SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) + 335 MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 336 337 for (unsigned j = NumShared; j != SizePrevIds; ++j) { 338 SizeAction -= 339 MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 340 SizeAction += -PrevAction->NextAction; 341 PrevAction = PrevAction->Previous; 342 } 343 } 344 345 // Compute the actions. 346 for (unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) { 347 int TypeID = TypeIds[J]; 348 assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); 349 int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; 350 unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID); 351 352 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; 353 SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction); 354 SizeSiteActions += SizeAction; 355 356 ActionEntry Action = { ValueForTypeID, NextAction, PrevAction }; 357 Actions.push_back(Action); 358 PrevAction = &Actions.back(); 359 } 360 361 // Record the first action of the landing pad site. 362 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; 363 } // else identical - re-use previous FirstAction 364 365 // Information used when created the call-site table. The action record 366 // field of the call site record is the offset of the first associated 367 // action record, relative to the start of the actions table. This value is 368 // biased by 1 (1 in dicating the start of the actions table), and 0 369 // indicates that there are no actions. 370 FirstActions.push_back(FirstAction); 371 372 // Compute this sites contribution to size. 373 SizeActions += SizeSiteActions; 374 375 PrevLPI = LPI; 376 } 377 378 return SizeActions; 379} 380 381/// ComputeCallSiteTable - Compute the call-site table. The entry for an invoke 382/// has a try-range containing the call, a non-zero landing pad, and an 383/// appropriate action. The entry for an ordinary call has a try-range 384/// containing the call and zero for the landing pad and the action. Calls 385/// marked 'nounwind' have no entry and must not be contained in the try-range 386/// of any entry - they form gaps in the table. Entries must be ordered by 387/// try-range address. 388void DwarfException:: 389ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, 390 const RangeMapType &PadMap, 391 const SmallVectorImpl<const LandingPadInfo *> &LandingPads, 392 const SmallVectorImpl<unsigned> &FirstActions) { 393 // The end label of the previous invoke or nounwind try-range. 394 unsigned LastLabel = 0; 395 396 // Whether there is a potentially throwing instruction (currently this means 397 // an ordinary call) between the end of the previous try-range and now. 398 bool SawPotentiallyThrowing = false; 399 400 // Whether the last CallSite entry was for an invoke. 401 bool PreviousIsInvoke = false; 402 403 // Visit all instructions in order of address. 404 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 405 I != E; ++I) { 406 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); 407 MI != E; ++MI) { 408 if (!MI->isLabel()) { 409 SawPotentiallyThrowing |= MI->getDesc().isCall(); 410 continue; 411 } 412 413 unsigned BeginLabel = MI->getOperand(0).getImm(); 414 assert(BeginLabel && "Invalid label!"); 415 416 // End of the previous try-range? 417 if (BeginLabel == LastLabel) 418 SawPotentiallyThrowing = false; 419 420 // Beginning of a new try-range? 421 RangeMapType::iterator L = PadMap.find(BeginLabel); 422 if (L == PadMap.end()) 423 // Nope, it was just some random label. 424 continue; 425 426 const PadRange &P = L->second; 427 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; 428 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && 429 "Inconsistent landing pad map!"); 430 431 // For Dwarf exception handling (SjLj handling doesn't use this). If some 432 // instruction between the previous try-range and this one may throw, 433 // create a call-site entry with no landing pad for the region between the 434 // try-ranges. 435 if (SawPotentiallyThrowing && 436 MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) { 437 CallSiteEntry Site = { LastLabel, BeginLabel, 0, 0 }; 438 CallSites.push_back(Site); 439 PreviousIsInvoke = false; 440 } 441 442 LastLabel = LandingPad->EndLabels[P.RangeIndex]; 443 assert(BeginLabel && LastLabel && "Invalid landing pad!"); 444 445 if (LandingPad->LandingPadLabel) { 446 // This try-range is for an invoke. 447 CallSiteEntry Site = { 448 BeginLabel, 449 LastLabel, 450 LandingPad->LandingPadLabel, 451 FirstActions[P.PadIndex] 452 }; 453 454 // Try to merge with the previous call-site. 455 if (PreviousIsInvoke) { 456 CallSiteEntry &Prev = CallSites.back(); 457 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { 458 // Extend the range of the previous entry. 459 Prev.EndLabel = Site.EndLabel; 460 continue; 461 } 462 } 463 464 // Otherwise, create a new call-site. 465 CallSites.push_back(Site); 466 PreviousIsInvoke = true; 467 } else { 468 // Create a gap. 469 PreviousIsInvoke = false; 470 } 471 } 472 } 473 474 // If some instruction between the previous try-range and the end of the 475 // function may throw, create a call-site entry with no landing pad for the 476 // region following the try-range. 477 if (SawPotentiallyThrowing && 478 MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) { 479 CallSiteEntry Site = { LastLabel, 0, 0, 0 }; 480 CallSites.push_back(Site); 481 } 482} 483 484/// EmitExceptionTable - Emit landing pads and actions. 485/// 486/// The general organization of the table is complex, but the basic concepts are 487/// easy. First there is a header which describes the location and organization 488/// of the three components that follow. 489/// 490/// 1. The landing pad site information describes the range of code covered by 491/// the try. In our case it's an accumulation of the ranges covered by the 492/// invokes in the try. There is also a reference to the landing pad that 493/// handles the exception once processed. Finally an index into the actions 494/// table. 495/// 2. The action table, in our case, is composed of pairs of type IDs and next 496/// action offset. Starting with the action index from the landing pad 497/// site, each type ID is checked for a match to the current exception. If 498/// it matches then the exception and type id are passed on to the landing 499/// pad. Otherwise the next action is looked up. This chain is terminated 500/// with a next action of zero. If no type id is found the the frame is 501/// unwound and handling continues. 502/// 3. Type ID table contains references to all the C++ typeinfo for all 503/// catches in the function. This tables is reversed indexed base 1. 504void DwarfException::EmitExceptionTable() { 505 const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 506 const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 507 const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); 508 if (PadInfos.empty()) return; 509 510 // Sort the landing pads in order of their type ids. This is used to fold 511 // duplicate actions. 512 SmallVector<const LandingPadInfo *, 64> LandingPads; 513 LandingPads.reserve(PadInfos.size()); 514 515 for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) 516 LandingPads.push_back(&PadInfos[i]); 517 518 std::sort(LandingPads.begin(), LandingPads.end(), PadLT); 519 520 // Compute the actions table and gather the first action index for each 521 // landing pad site. 522 SmallVector<ActionEntry, 32> Actions; 523 SmallVector<unsigned, 64> FirstActions; 524 unsigned SizeActions = ComputeActionsTable(LandingPads, Actions, FirstActions); 525 526 // Invokes and nounwind calls have entries in PadMap (due to being bracketed 527 // by try-range labels when lowered). Ordinary calls do not, so appropriate 528 // try-ranges for them need be deduced when using Dwarf exception handling. 529 RangeMapType PadMap; 530 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 531 const LandingPadInfo *LandingPad = LandingPads[i]; 532 for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { 533 unsigned BeginLabel = LandingPad->BeginLabels[j]; 534 assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); 535 PadRange P = { i, j }; 536 PadMap[BeginLabel] = P; 537 } 538 } 539 540 // Compute the call-site table. 541 SmallVector<CallSiteEntry, 64> CallSites; 542 ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions); 543 544 // Final tallies. 545 546 // Call sites. 547 const unsigned SiteStartSize = sizeof(int32_t); // DW_EH_PE_udata4 548 const unsigned SiteLengthSize = sizeof(int32_t); // DW_EH_PE_udata4 549 const unsigned LandingPadSize = sizeof(int32_t); // DW_EH_PE_udata4 550 unsigned SizeSites; 551 552 bool HaveTTData = (MAI->getExceptionHandlingType() == ExceptionHandling::SjLj) 553 ? (!TypeInfos.empty() || !FilterIds.empty()) : true; 554 555 556 if (MAI->getExceptionHandlingType() == ExceptionHandling::SjLj) { 557 SizeSites = 0; 558 } else 559 SizeSites = CallSites.size() * 560 (SiteStartSize + SiteLengthSize + LandingPadSize); 561 for (unsigned i = 0, e = CallSites.size(); i < e; ++i) { 562 SizeSites += MCAsmInfo::getULEB128Size(CallSites[i].Action); 563 if (MAI->getExceptionHandlingType() == ExceptionHandling::SjLj) 564 SizeSites += MCAsmInfo::getULEB128Size(i); 565 } 566 // Type infos. 567 const unsigned TypeInfoSize = TD->getPointerSize(); // DW_EH_PE_absptr 568 unsigned SizeTypes = TypeInfos.size() * TypeInfoSize; 569 570 unsigned TypeOffset = sizeof(int8_t) + // Call site format 571 MCAsmInfo::getULEB128Size(SizeSites) + // Call-site table length 572 SizeSites + SizeActions + SizeTypes; 573 574 unsigned TotalSize = sizeof(int8_t) + // LPStart format 575 sizeof(int8_t) + // TType format 576 (HaveTTData ? 577 MCAsmInfo::getULEB128Size(TypeOffset) : 0) + // TType base offset 578 TypeOffset; 579 580 unsigned SizeAlign = (4 - TotalSize) & 3; 581 582 // Begin the exception table. 583 const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection(); 584 Asm->OutStreamer.SwitchSection(LSDASection); 585 Asm->EmitAlignment(2, 0, 0, false); 586 O << "GCC_except_table" << SubprogramCount << ":\n"; 587 588 for (unsigned i = 0; i != SizeAlign; ++i) { 589 Asm->EmitInt8(0); 590 Asm->EOL("Padding"); 591 } 592 593 EmitLabel("exception", SubprogramCount); 594 if (MAI->getExceptionHandlingType() == ExceptionHandling::SjLj) { 595 std::string SjLjName = "_lsda_"; 596 SjLjName += MF->getFunction()->getName().str(); 597 EmitLabel(SjLjName.c_str(), 0); 598 } 599 600 // Emit the header. 601 Asm->EmitInt8(dwarf::DW_EH_PE_omit); 602 Asm->EOL("@LPStart format (DW_EH_PE_omit)"); 603 604#if 0 605 if (TypeInfos.empty() && FilterIds.empty()) { 606 // If there are no typeinfos or filters, there is nothing to emit, optimize 607 // by specifying the "omit" encoding. 608 Asm->EmitInt8(dwarf::DW_EH_PE_omit); 609 Asm->EOL("@TType format (DW_EH_PE_omit)"); 610 } else { 611 // Okay, we have actual filters or typeinfos to emit. As such, we need to 612 // pick a type encoding for them. We're about to emit a list of pointers to 613 // typeinfo objects at the end of the LSDA. However, unless we're in static 614 // mode, this reference will require a relocation by the dynamic linker. 615 // 616 // Because of this, we have a couple of options: 617 // 1) If we are in -static mode, we can always use an absolute reference 618 // from the LSDA, because the static linker will resolve it. 619 // 2) Otherwise, if the LSDA section is writable, we can output the direct 620 // reference to the typeinfo and allow the dynamic linker to relocate 621 // it. Since it is in a writable section, the dynamic linker won't 622 // have a problem. 623 // 3) Finally, if we're in PIC mode and the LDSA section isn't writable, 624 // we need to use some form of indirection. For example, on Darwin, 625 // we can output a statically-relocatable reference to a dyld stub. The 626 // offset to the stub is constant, but the contents are in a section 627 // that is updated by the dynamic linker. This is easy enough, but we 628 // need to tell the personality function of the unwinder to indirect 629 // through the dyld stub. 630 // 631 // FIXME: When this is actually implemented, we'll have to emit the stubs 632 // somewhere. This predicate should be moved to a shared location that is 633 // in target-independent code. 634 // 635 if (LSDASection->isWritable() || 636 Asm->TM.getRelocationModel() == Reloc::Static) { 637 Asm->EmitInt8(DW_EH_PE_absptr); 638 Asm->EOL("TType format (DW_EH_PE_absptr)"); 639 } else { 640 Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4); 641 Asm->EOL("TType format (DW_EH_PE_pcrel | DW_EH_PE_indirect" 642 " | DW_EH_PE_sdata4)"); 643 } 644 Asm->EmitULEB128Bytes(TypeOffset); 645 Asm->EOL("TType base offset"); 646 } 647#else 648 // For SjLj exceptions, if there is no TypeInfo, then we just explicitly 649 // say that we're omitting that bit. 650 // FIXME: does this apply to Dwarf also? The above #if 0 implies yes? 651 if (!HaveTTData) { 652 Asm->EmitInt8(dwarf::DW_EH_PE_omit); 653 Asm->EOL("@TType format (DW_EH_PE_omit)"); 654 } else { 655 Asm->EmitInt8(dwarf::DW_EH_PE_absptr); 656 Asm->EOL("@TType format (DW_EH_PE_absptr)"); 657 Asm->EmitULEB128Bytes(TypeOffset); 658 Asm->EOL("@TType base offset"); 659 } 660#endif 661 662 // SjLj Exception handilng 663 if (MAI->getExceptionHandlingType() == ExceptionHandling::SjLj) { 664 Asm->EmitInt8(dwarf::DW_EH_PE_udata4); 665 Asm->EOL("Call site format (DW_EH_PE_udata4)"); 666 Asm->EmitULEB128Bytes(SizeSites); 667 Asm->EOL("Call site table length"); 668 669 // Emit the landing pad site information. 670 unsigned idx = 0; 671 for (SmallVectorImpl<CallSiteEntry>::const_iterator 672 I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { 673 const CallSiteEntry &S = *I; 674 675 // Offset of the landing pad, counted in 16-byte bundles relative to the 676 // @LPStart address. 677 Asm->EmitULEB128Bytes(idx); 678 Asm->EOL("Landing pad"); 679 680 // Offset of the first associated action record, relative to the start of 681 // the action table. This value is biased by 1 (1 indicates the start of 682 // the action table), and 0 indicates that there are no actions. 683 Asm->EmitULEB128Bytes(S.Action); 684 Asm->EOL("Action"); 685 } 686 } else { 687 // DWARF Exception handling 688 assert(MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf); 689 690 // The call-site table is a list of all call sites that may throw an 691 // exception (including C++ 'throw' statements) in the procedure 692 // fragment. It immediately follows the LSDA header. Each entry indicates, 693 // for a given call, the first corresponding action record and corresponding 694 // landing pad. 695 // 696 // The table begins with the number of bytes, stored as an LEB128 697 // compressed, unsigned integer. The records immediately follow the record 698 // count. They are sorted in increasing call-site address. Each record 699 // indicates: 700 // 701 // * The position of the call-site. 702 // * The position of the landing pad. 703 // * The first action record for that call site. 704 // 705 // A missing entry in the call-site table indicates that a call is not 706 // supposed to throw. Such calls include: 707 // 708 // * Calls to destructors within cleanup code. C++ semantics forbids these 709 // calls to throw. 710 // * Calls to intrinsic routines in the standard library which are known 711 // not to throw (sin, memcpy, et al). 712 // 713 // If the runtime does not find the call-site entry for a given call, it 714 // will call `terminate()'. 715 716 // Emit the landing pad call site table. 717 Asm->EmitInt8(dwarf::DW_EH_PE_udata4); 718 Asm->EOL("Call site format (DW_EH_PE_udata4)"); 719 Asm->EmitULEB128Bytes(SizeSites); 720 Asm->EOL("Call site table size"); 721 722 for (SmallVectorImpl<CallSiteEntry>::const_iterator 723 I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { 724 const CallSiteEntry &S = *I; 725 const char *BeginTag; 726 unsigned BeginNumber; 727 728 if (!S.BeginLabel) { 729 BeginTag = "eh_func_begin"; 730 BeginNumber = SubprogramCount; 731 } else { 732 BeginTag = "label"; 733 BeginNumber = S.BeginLabel; 734 } 735 736 // Offset of the call site relative to the previous call site, counted in 737 // number of 16-byte bundles. The first call site is counted relative to 738 // the start of the procedure fragment. 739 EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount, 740 true, true); 741 Asm->EOL("Region start"); 742 743 if (!S.EndLabel) 744 EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber, 745 true); 746 else 747 EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true); 748 749 Asm->EOL("Region length"); 750 751 // Offset of the landing pad, counted in 16-byte bundles relative to the 752 // @LPStart address. 753 if (!S.PadLabel) 754 Asm->EmitInt32(0); 755 else 756 EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount, 757 true, true); 758 759 Asm->EOL("Landing pad"); 760 761 // Offset of the first associated action record, relative to the start of 762 // the action table. This value is biased by 1 (1 indicates the start of 763 // the action table), and 0 indicates that there are no actions. 764 Asm->EmitULEB128Bytes(S.Action); 765 Asm->EOL("Action"); 766 } 767 } 768 769 // Emit the Action Table. 770 for (SmallVectorImpl<ActionEntry>::const_iterator 771 I = Actions.begin(), E = Actions.end(); I != E; ++I) { 772 const ActionEntry &Action = *I; 773 774 // Type Filter 775 // 776 // Used by the runtime to match the type of the thrown exception to the 777 // type of the catch clauses or the types in the exception specification. 778 779 Asm->EmitSLEB128Bytes(Action.ValueForTypeID); 780 Asm->EOL("TypeInfo index"); 781 782 // Action Record 783 // 784 // Self-relative signed displacement in bytes of the next action record, 785 // or 0 if there is no next action record. 786 787 Asm->EmitSLEB128Bytes(Action.NextAction); 788 Asm->EOL("Next action"); 789 } 790 791 // Emit the Catch Clauses. The code for the catch clauses following the same 792 // try is similar to a switch statement. The catch clause action record 793 // informs the runtime about the type of a catch clause and about the 794 // associated switch value. 795 // 796 // Action Record Fields: 797 // 798 // * Filter Value 799 // Positive value, starting at 1. Index in the types table of the 800 // __typeinfo for the catch-clause type. 1 is the first word preceding 801 // TTBase, 2 is the second word, and so on. Used by the runtime to check 802 // if the thrown exception type matches the catch-clause type. Back-end 803 // generated switch statements check against this value. 804 // 805 // * Next 806 // Signed offset, in bytes from the start of this field, to the next 807 // chained action record, or zero if none. 808 // 809 // The order of the action records determined by the next field is the order 810 // of the catch clauses as they appear in the source code, and must be kept in 811 // the same order. As a result, changing the order of the catch clause would 812 // change the semantics of the program. 813 for (std::vector<GlobalVariable *>::const_reverse_iterator 814 I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { 815 const GlobalVariable *GV = *I; 816 PrintRelDirective(); 817 818 if (GV) { 819 std::string GLN; 820 O << Asm->getGlobalLinkName(GV, GLN); 821 } else { 822 O << "0"; 823 } 824 825 Asm->EOL("TypeInfo"); 826 } 827 828 // Emit the Type Table. 829 for (std::vector<unsigned>::const_iterator 830 I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { 831 unsigned TypeID = *I; 832 Asm->EmitULEB128Bytes(TypeID); 833 Asm->EOL("Filter TypeInfo index"); 834 } 835 836 Asm->EmitAlignment(2, 0, 0, false); 837} 838 839/// EndModule - Emit all exception information that should come after the 840/// content. 841void DwarfException::EndModule() { 842 if (MAI->getExceptionHandlingType() != ExceptionHandling::Dwarf) 843 return; 844 if (TimePassesIsEnabled) 845 ExceptionTimer->startTimer(); 846 847 if (shouldEmitMovesModule || shouldEmitTableModule) { 848 const std::vector<Function *> Personalities = MMI->getPersonalities(); 849 for (unsigned i = 0; i < Personalities.size(); ++i) 850 EmitCIE(Personalities[i], i); 851 852 for (std::vector<FunctionEHFrameInfo>::iterator I = EHFrames.begin(), 853 E = EHFrames.end(); I != E; ++I) 854 EmitFDE(*I); 855 } 856 857 if (TimePassesIsEnabled) 858 ExceptionTimer->stopTimer(); 859} 860 861/// BeginFunction - Gather pre-function exception information. Assumes being 862/// emitted immediately after the function entry point. 863void DwarfException::BeginFunction(MachineFunction *MF) { 864 if (TimePassesIsEnabled) 865 ExceptionTimer->startTimer(); 866 867 this->MF = MF; 868 shouldEmitTable = shouldEmitMoves = false; 869 870 if (MMI && MAI->doesSupportExceptionHandling()) { 871 // Map all labels and get rid of any dead landing pads. 872 MMI->TidyLandingPads(); 873 874 // If any landing pads survive, we need an EH table. 875 if (MMI->getLandingPads().size()) 876 shouldEmitTable = true; 877 878 // See if we need frame move info. 879 if (!MF->getFunction()->doesNotThrow() || UnwindTablesMandatory) 880 shouldEmitMoves = true; 881 882 if (shouldEmitMoves || shouldEmitTable) 883 // Assumes in correct section after the entry point. 884 EmitLabel("eh_func_begin", ++SubprogramCount); 885 } 886 887 shouldEmitTableModule |= shouldEmitTable; 888 shouldEmitMovesModule |= shouldEmitMoves; 889 890 if (TimePassesIsEnabled) 891 ExceptionTimer->stopTimer(); 892} 893 894/// EndFunction - Gather and emit post-function exception information. 895/// 896void DwarfException::EndFunction() { 897 if (TimePassesIsEnabled) 898 ExceptionTimer->startTimer(); 899 900 if (shouldEmitMoves || shouldEmitTable) { 901 EmitLabel("eh_func_end", SubprogramCount); 902 EmitExceptionTable(); 903 904 // Save EH frame information 905 EHFrames.push_back( 906 FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF), 907 SubprogramCount, 908 MMI->getPersonalityIndex(), 909 MF->getFrameInfo()->hasCalls(), 910 !MMI->getLandingPads().empty(), 911 MMI->getFrameMoves(), 912 MF->getFunction())); 913 } 914 915 if (TimePassesIsEnabled) 916 ExceptionTimer->stopTimer(); 917} 918