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