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