llvm.org GIT mirror llvm / 671fa97
Output correct exception handling and frame info on x86-64 linux. This causes no regressions on 32 bit linux and 32 bit ppc. More tests pass on 64 bit ppc with no regressions. I didn't turn on eh on 64 bit linux because the intrinsics needed to compile the eh runtime aren't done yet. But if you turn it on and link with the mainline runtime then eh seems to work fine on x86-64 linux with this patch. Thanks to Dale for testing. The main point of the patch is that if you output that some object is encoded using 4 bytes you had better not output 8 bytes for it: the patch makes everything consistent. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50825 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan Sands 11 years ago
4 changed file(s) with 50 addition(s) and 62 deletion(s). Raw diff Collapse all Expand all
338338 /// handle a weak_definition of constant 0 for an omitted EH frame.
339339 bool SupportsWeakOmittedEHFrame; // Defaults to true.
340340
341 /// ShortenEHDataON64Bit - True if target exception table format requires
342 /// 32-bit data in certain places even when targeting 64-bits.
343 bool ShortenEHDataOn64Bit; // Defaults to false.
344
345341 /// DwarfSectionOffsetDirective - Special section offset directive.
346342 const char* DwarfSectionOffsetDirective; // Defaults to NULL
347343
634630 bool getSupportsWeakOmittedEHFrame() const {
635631 return SupportsWeakOmittedEHFrame;
636632 }
637 bool getShortenEHDataOn64Bit() const {
638 return ShortenEHDataOn64Bit;
639 }
640633 const char *getDwarfSectionOffsetDirective() const {
641634 return DwarfSectionOffsetDirective;
642635 }
27952795 /// shouldEmitFrameModule - Per-module flag to indicate if frame moves
27962796 /// should be emitted.
27972797 bool shouldEmitMovesModule;
2798
2798
27992799 /// EmitCommonEHFrame - Emit the common eh unwind frame.
28002800 ///
28012801 void EmitCommonEHFrame(const Function *Personality, unsigned Index) {
28122812
28132813 // Define base labels.
28142814 EmitLabel("eh_frame_common", Index);
2815
2815
28162816 // Define the eh frame length.
28172817 EmitDifference("eh_frame_common_end", Index,
28182818 "eh_frame_common_begin", Index, true);
28242824 Asm->EOL("CIE Identifier Tag");
28252825 Asm->EmitInt8(DW_CIE_VERSION);
28262826 Asm->EOL("CIE Version");
2827
2827
28282828 // The personality presence indicates that language specific information
28292829 // will show up in the eh frame.
28302830 Asm->EmitString(Personality ? "zPLR" : "zR");
28312831 Asm->EOL("CIE Augmentation");
2832
2832
28332833 // Round out reader.
28342834 Asm->EmitULEB128Bytes(1);
28352835 Asm->EOL("CIE Code Alignment Factor");
28362836 Asm->EmitSLEB128Bytes(stackGrowth);
2837 Asm->EOL("CIE Data Alignment Factor");
2837 Asm->EOL("CIE Data Alignment Factor");
28382838 Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
2839 Asm->EOL("CIE RA Column");
2840
2839 Asm->EOL("CIE Return Address Column");
2840
28412841 // If there is a personality, we need to indicate the functions location.
28422842 if (Personality) {
28432843 Asm->EmitULEB128Bytes(7);
28442844 Asm->EOL("Augmentation Size");
28452845
2846 if (TAI->getNeedsIndirectEncoding())
2846 if (TAI->getNeedsIndirectEncoding()) {
28472847 Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect);
2848 else
2848 Asm->EOL("Personality (pcrel sdata4 indirect)");
2849 } else {
28492850 Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4);
2850
2851 Asm->EOL("Personality (pcrel sdata4 indirect)");
2852
2853 PrintRelDirective(TAI->getShortenEHDataOn64Bit());
2851 Asm->EOL("Personality (pcrel sdata4)");
2852 }
2853
2854 PrintRelDirective(true);
28542855 O << TAI->getPersonalityPrefix();
28552856 Asm->EmitExternalGlobal((const GlobalVariable *)(Personality));
28562857 O << TAI->getPersonalitySuffix();
2857 if (!TAI->getShortenEHDataOn64Bit()) {
2858 O << "-" << TAI->getPCSymbol();
2859 }
2858 O << "-" << TAI->getPCSymbol();
28602859 Asm->EOL("Personality");
28612860
2862 Asm->EmitULEB128Bytes(DW_EH_PE_pcrel);
2863 Asm->EOL("LSDA Encoding (pcrel)");
2864 Asm->EmitULEB128Bytes(DW_EH_PE_pcrel);
2865 Asm->EOL("FDE Encoding (pcrel)");
2861 Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4);
2862 Asm->EOL("LSDA Encoding (pcrel sdata4)");
2863 Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4);
2864 Asm->EOL("FDE Encoding (pcrel sdata4)");
28662865 } else {
28672866 Asm->EmitULEB128Bytes(1);
28682867 Asm->EOL("Augmentation Size");
2869 Asm->EmitULEB128Bytes(DW_EH_PE_pcrel);
2870 Asm->EOL("FDE Encoding (pcrel)");
2868 Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4);
2869 Asm->EOL("FDE Encoding (pcrel sdata4)");
28712870 }
28722871
28732872 // Indicate locations of general callee saved registers in frame.
28812880 Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3,
28822881 0, 0, false);
28832882 EmitLabel("eh_frame_common_end", Index);
2884
2883
28852884 Asm->EOL();
28862885 }
2887
2886
28882887 /// EmitEHFrame - Emit function exception frame information.
28892888 ///
28902889 void EmitEHFrame(const FunctionEHFrameInfo &EHFrameInfo) {
29392938 true, true, false);
29402939 Asm->EOL("FDE CIE offset");
29412940
2942 EmitReference("eh_func_begin", EHFrameInfo.Number, true);
2941 EmitReference("eh_func_begin", EHFrameInfo.Number, true, true);
29432942 Asm->EOL("FDE initial location");
29442943 EmitDifference("eh_func_end", EHFrameInfo.Number,
2945 "eh_func_begin", EHFrameInfo.Number);
2944 "eh_func_begin", EHFrameInfo.Number, true);
29462945 Asm->EOL("FDE address range");
2947
2946
29482947 // If there is a personality and landing pads then point to the language
29492948 // specific data area in the exception table.
29502949 if (EHFrameInfo.PersonalityIndex) {
2951 Asm->EmitULEB128Bytes(TAI->getShortenEHDataOn64Bit() ? 8 : 4);
2950 Asm->EmitULEB128Bytes(4);
29522951 Asm->EOL("Augmentation size");
2953
2954 if (EHFrameInfo.hasLandingPads) {
2955 EmitReference("exception", EHFrameInfo.Number, true);
2956 } else if (TD->getPointerSize() == 8) {
2957 Asm->EmitInt64((int)0);
2958 } else {
2952
2953 if (EHFrameInfo.hasLandingPads)
2954 EmitReference("exception", EHFrameInfo.Number, true, true);
2955 else
29592956 Asm->EmitInt32((int)0);
2960 }
29612957 Asm->EOL("Language Specific Data Area");
29622958 } else {
29632959 Asm->EmitULEB128Bytes(0);
29642960 Asm->EOL("Augmentation size");
29652961 }
2966
2962
29672963 // Indicate locations of function specific callee saved registers in
29682964 // frame.
29692965 EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, true);
32663262 }
32673263
32683264 // Final tallies.
3269 unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
3270 sizeof(int32_t) + // Site length.
3271 sizeof(int32_t)); // Landing pad.
3265
3266 // Call sites.
3267 const unsigned SiteStartSize = sizeof(int32_t); // DW_EH_PE_udata4
3268 const unsigned SiteLengthSize = sizeof(int32_t); // DW_EH_PE_udata4
3269 const unsigned LandingPadSize = sizeof(int32_t); // DW_EH_PE_udata4
3270 unsigned SizeSites = CallSites.size() * (SiteStartSize +
3271 SiteLengthSize +
3272 LandingPadSize);
32723273 for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
32733274 SizeSites += Asm->SizeULEB128(CallSites[i].Action);
32743275
3275 unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
3276 // Type infos.
3277 const unsigned TypeInfoSize = TD->getPointerSize(); // DW_EH_PE_absptr
3278 unsigned SizeTypes = TypeInfos.size() * TypeInfoSize;
32763279
32773280 unsigned TypeOffset = sizeof(int8_t) + // Call site format
32783281 Asm->SizeULEB128(SizeSites) + // Call-site table length
33223325 }
33233326
33243327 EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount,
3325 TAI->getShortenEHDataOn64Bit(), true);
3328 true, true);
33263329 Asm->EOL("Region start");
33273330
33283331 if (!S.EndLabel) {
33293332 EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber,
3330 TAI->getShortenEHDataOn64Bit());
3333 true);
33313334 } else {
3332 EmitDifference("label", S.EndLabel, BeginTag, BeginNumber,
3333 TAI->getShortenEHDataOn64Bit());
3335 EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true);
33343336 }
33353337 Asm->EOL("Region length");
33363338
3337 if (!S.PadLabel) {
3338 if (TD->getPointerSize() == sizeof(int32_t) || TAI->getShortenEHDataOn64Bit())
3339 Asm->EmitInt32(0);
3340 else
3341 Asm->EmitInt64(0);
3342 } else {
3339 if (!S.PadLabel)
3340 Asm->EmitInt32(0);
3341 else
33433342 EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount,
3344 TAI->getShortenEHDataOn64Bit(), true);
3345 }
3343 true, true);
33463344 Asm->EOL("Landing pad");
33473345
33483346 Asm->EmitULEB128Bytes(S.Action);
8989 DwarfRequiresFrameSection(true),
9090 GlobalEHDirective(0),
9191 SupportsWeakOmittedEHFrame(true),
92 ShortenEHDataOn64Bit(false),
9392 DwarfSectionOffsetDirective(0),
9493 DwarfAbbrevSection(".debug_abbrev"),
9594 DwarfInfoSection(".debug_info"),
119119 GlobalEHDirective = "\t.globl\t";
120120 SupportsWeakOmittedEHFrame = false;
121121 AbsoluteEHSectionOffsets = false;
122 if (Subtarget->is64Bit())
123 ShortenEHDataOn64Bit = true;
124122 DwarfEHFrameSection =
125123 ".section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support";
126124 DwarfExceptionSection = ".section __DATA,__gcc_except_tab";