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