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