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