-static TimerGroup &getDwarfTimerGroup() {
- static TimerGroup DwarfTimerGroup("Dwarf Exception");
- return DwarfTimerGroup;
-}
-
-DwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A,
- const MCAsmInfo *T)
- : Dwarf(OS, A, T, "eh"), shouldEmitTable(false), shouldEmitMoves(false),
- shouldEmitTableModule(false), shouldEmitMovesModule(false),
- ExceptionTimer(0) {
- if (TimePassesIsEnabled)
- ExceptionTimer = new Timer("Dwarf Exception Writer",
- getDwarfTimerGroup());
-}
-
-DwarfException::~DwarfException() {
- delete ExceptionTimer;
-}
-
-/// EmitCIE - Emit a Common Information Entry (CIE). This holds information that
-/// is shared among many Frame Description Entries. There is at least one CIE
-/// in every non-empty .debug_frame section.
-void DwarfException::EmitCIE(const Function *Personality, unsigned Index) {
- // Size and sign of stack growth.
- int stackGrowth =
- Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
- TargetFrameInfo::StackGrowsUp ?
- TD->getPointerSize() : -TD->getPointerSize();
-
- // Begin eh frame section.
- Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getEHFrameSection());
-
- if (MAI->is_EHSymbolPrivate())
- O << MAI->getPrivateGlobalPrefix();
-
- O << "EH_frame" << Index << ":\n";
- EmitLabel("section_eh_frame", Index);
-
- // Define base labels.
- EmitLabel("eh_frame_common", Index);
-
- // Define the eh frame length.
- EmitDifference("eh_frame_common_end", Index,
- "eh_frame_common_begin", Index, true);
- Asm->EOL("Length of Common Information Entry");
-
- // EH frame header.
- EmitLabel("eh_frame_common_begin", Index);
- Asm->EmitInt32((int)0);
- Asm->EOL("CIE Identifier Tag");
- Asm->EmitInt8(dwarf::DW_CIE_VERSION);
- Asm->EOL("CIE Version");
-
- // The personality presence indicates that language specific information will
- // show up in the eh frame.
- Asm->EmitString(Personality ? "zPLR" : "zR");
- Asm->EOL("CIE Augmentation");
-
- // Round out reader.
- Asm->EmitULEB128Bytes(1);
- Asm->EOL("CIE Code Alignment Factor");
- Asm->EmitSLEB128Bytes(stackGrowth);
- Asm->EOL("CIE Data Alignment Factor");
- Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
- Asm->EOL("CIE Return Address Column");
-
- // If there is a personality, we need to indicate the function's location.
- if (Personality) {
- Asm->EmitULEB128Bytes(7);
- Asm->EOL("Augmentation Size");
-
- if (MAI->getNeedsIndirectEncoding()) {
- Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 |
- dwarf::DW_EH_PE_indirect);
- Asm->EOL("Personality (pcrel sdata4 indirect)");
- } else {
- Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
- Asm->EOL("Personality (pcrel sdata4)");
- }
-
- PrintRelDirective(true);
- O << MAI->getPersonalityPrefix();
- Asm->EmitExternalGlobal((const GlobalVariable *)(Personality));
- O << MAI->getPersonalitySuffix();
- if (strcmp(MAI->getPersonalitySuffix(), "+4@GOTPCREL"))
- O << "-" << MAI->getPCSymbol();
- Asm->EOL("Personality");
-
- Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
- Asm->EOL("LSDA Encoding (pcrel sdata4)");
-
- Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
- Asm->EOL("FDE Encoding (pcrel sdata4)");
- } else {
- Asm->EmitULEB128Bytes(1);
- Asm->EOL("Augmentation Size");
-
- Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
- Asm->EOL("FDE Encoding (pcrel sdata4)");
- }
-
- // Indicate locations of general callee saved registers in frame.
- std::vector<MachineMove> Moves;
- RI->getInitialFrameState(Moves);
- EmitFrameMoves(NULL, 0, Moves, true);
-
- // On Darwin the linker honors the alignment of eh_frame, which means it must
- // be 8-byte on 64-bit targets to match what gcc does. Otherwise you get
- // holes which confuse readers of eh_frame.
- Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3,
- 0, 0, false);
- EmitLabel("eh_frame_common_end", Index);