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