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