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