From 09aaf53a05e3786eea374f3ce57574225036412d Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Tue, 28 Feb 2023 15:17:44 -0500 Subject: [PATCH] [RFC][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs. Details: https://github.com/rust-lang/rust/issues/102754 The MachO format uses 2 bits to encode these personality funtions, with 0 reserved for "no-personality". This means we can only have up to 3 personality. There are already three popular personalities: __gxx_personality_v0, __gcc_personality_v0, and __objc_personality_v0. As a result, any system that needs custom-personality will run into a problem. This patch implemented jyknight's proposal to simply force DWARFs for all non-canonical personality functions. Differential Revision: https://reviews.llvm.org/D144999 --- clang/include/clang/Basic/CodeGenOptions.def | 3 + clang/include/clang/Driver/Options.td | 3 + clang/lib/CodeGen/BackendUtil.cpp | 2 + clang/lib/Driver/ToolChains/Clang.cpp | 3 + clang/test/Driver/femit-dwarf-unwind.c | 4 +- clang/test/Driver/femit-dwarf-unwind.s | 4 +- clang/tools/driver/cc1as_main.cpp | 9 ++ lld/MachO/UnwindInfoSection.cpp | 7 +- lld/test/MachO/Inputs/eh-frame-x86_64-r.o | Bin 1520 -> 1520 bytes ...-unwind-both-local-and-dylib-personality.s | 85 +++++++++++++++++- lld/test/MachO/compact-unwind-generated.test | 2 +- lld/test/MachO/compact-unwind-lsda-folding.s | 2 +- lld/test/MachO/compact-unwind-stack-ind.s | 2 +- lld/test/MachO/compact-unwind.s | 12 +-- lld/test/MachO/eh-frame-personality-dedup.s | 4 +- lld/test/MachO/eh-frame.s | 19 ++-- lld/test/MachO/icf-only-lsda-folded.s | 2 +- lld/test/MachO/icf.s | 4 +- .../MachO/invalid/compact-unwind-bad-reloc.s | 2 +- .../invalid/compact-unwind-personalities.s | 21 ++++- llvm/include/llvm/MC/MCAsmBackend.h | 9 +- llvm/include/llvm/MC/MCContext.h | 1 + llvm/include/llvm/MC/MCTargetOptions.h | 4 + .../llvm/MC/MCTargetOptionsCommandFlags.h | 2 + llvm/lib/MC/MCAsmBackend.cpp | 11 +++ llvm/lib/MC/MCContext.cpp | 6 ++ llvm/lib/MC/MCStreamer.cpp | 2 +- llvm/lib/MC/MCTargetOptionsCommandFlags.cpp | 10 +++ .../MCTargetDesc/AArch64AsmBackend.cpp | 8 +- .../Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 7 +- .../ARM/MCTargetDesc/ARMAsmBackendDarwin.h | 5 +- .../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 8 +- .../CodeGen/X86/2014-08-29-CompactUnwind.ll | 2 +- llvm/test/CodeGen/X86/compact-unwind.ll | 12 +-- .../MC/AArch64/arm64-leaf-compact-unwind.s | 2 +- .../test/MC/MachO/AArch64/emit-dwarf-unwind.s | 8 +- .../test/MC/MachO/ARM/compact-unwind-armv7k.s | 2 +- llvm/test/MC/X86/compact-unwind.s | 2 +- 38 files changed, 232 insertions(+), 59 deletions(-) diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 5752c6e285b98b..53d92c4c76673c 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -114,6 +114,9 @@ CODEGENOPT(StackSizeSection , 1, 0) ///< Set when -fstack-size-section is enabl CODEGENOPT(ForceDwarfFrameSection , 1, 0) ///< Set when -fforce-dwarf-frame is ///< enabled. +///< Set when -femit-compact-unwind-non-canonical is enabled. +CODEGENOPT(EmitCompactUnwindNonCanonical, 1, 0) + ///< Set when -femit-dwarf-unwind is passed. ENUM_CODEGENOPT(EmitDwarfUnwind, llvm::EmitDwarfUnwindType, 2, llvm::EmitDwarfUnwindType::Default) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index f3026693e6d533..9f6922cbe56786 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3244,6 +3244,9 @@ def femit_dwarf_unwind_EQ : Joined<["-"], "femit-dwarf-unwind=">, NormalizedValues<["Always", "NoCompactUnwind", "Default"]>, NormalizedValuesScope<"llvm::EmitDwarfUnwindType">, MarshallingInfoEnum, "Default">; +defm emit_compact_unwind_non_canonical : BoolFOption<"emit-compact-unwind-non-canonical", + CodeGenOpts<"EmitCompactUnwindNonCanonical">, DefaultFalse, + PosFlag, NegFlag>; def g_Flag : Flag<["-"], "g">, Group, Flags<[CoreOption,FlangOption]>, HelpText<"Generate source-level debug information">; def gline_tables_only : Flag<["-"], "gline-tables-only">, Group, diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index d62d00a156f1c0..934e41c75f4d18 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -454,6 +454,8 @@ static bool initTargetOptions(DiagnosticsEngine &Diags, Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile; Options.MCOptions.EmitDwarfUnwind = CodeGenOpts.getEmitDwarfUnwind(); + Options.MCOptions.EmitCompactUnwindNonCanonical = + CodeGenOpts.EmitCompactUnwindNonCanonical; Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll; Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels; Options.MCOptions.MCUseDwarfDirectory = diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 2a44e8d6158b11..3d55047ec478ef 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2511,6 +2511,9 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, Args.AddLastArg(CmdArgs, options::OPT_femit_dwarf_unwind_EQ); + Args.addOptInFlag(CmdArgs, options::OPT_femit_compact_unwind_non_canonical, + options::OPT_fno_emit_compact_unwind_non_canonical); + // If you add more args here, also add them to the block below that // starts with "// If CollectArgsForIntegratedAssembler() isn't called below". diff --git a/clang/test/Driver/femit-dwarf-unwind.c b/clang/test/Driver/femit-dwarf-unwind.c index 6057c5e0e53486..89e733462c2c92 100644 --- a/clang/test/Driver/femit-dwarf-unwind.c +++ b/clang/test/Driver/femit-dwarf-unwind.c @@ -1,8 +1,8 @@ // REQUIRES: x86-registered-target // RUN: rm -rf %t; mkdir %t -// RUN: %clang -target x86_64-apple-macos11.0 -c %s -o %t/x86_64.o -// RUN: %clang -target x86_64-apple-macos11.0 -femit-dwarf-unwind=no-compact-unwind -c %s -o %t/x86_64-no-dwarf.o +// RUN: %clang -target x86_64-apple-macos11.0 -c %s -o %t/x86_64.o -femit-compact-unwind-non-canonical +// RUN: %clang -target x86_64-apple-macos11.0 -femit-dwarf-unwind=no-compact-unwind -femit-compact-unwind-non-canonical -c %s -o %t/x86_64-no-dwarf.o // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix=WITH-FDE // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix=NO-FDE diff --git a/clang/test/Driver/femit-dwarf-unwind.s b/clang/test/Driver/femit-dwarf-unwind.s index f2aa821b0cd5a2..41951352eeafdf 100644 --- a/clang/test/Driver/femit-dwarf-unwind.s +++ b/clang/test/Driver/femit-dwarf-unwind.s @@ -1,8 +1,8 @@ // REQUIRES: x86-registered-target // RUN: rm -rf %t; mkdir %t -// RUN: %clang -target x86_64-apple-macos11.0 -c %s -o %t/x86_64.o -// RUN: %clang -target x86_64-apple-macos11.0 -femit-dwarf-unwind=no-compact-unwind -c %s -o %t/x86_64-no-dwarf.o +// RUN: %clang -target x86_64-apple-macos11.0 -c %s -o %t/x86_64.o -femit-compact-unwind-non-canonical +// RUN: %clang -target x86_64-apple-macos11.0 -femit-dwarf-unwind=no-compact-unwind -c %s -o %t/x86_64-no-dwarf.o -femit-compact-unwind-non-canonical // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix=WITH-FDE // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix=NO-FDE diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp index ecfb1be8c55af7..08b453dc1e8348 100644 --- a/clang/tools/driver/cc1as_main.cpp +++ b/clang/tools/driver/cc1as_main.cpp @@ -142,6 +142,10 @@ struct AssemblerInvocation { /// Whether to emit DWARF unwind info. EmitDwarfUnwindType EmitDwarfUnwind; + // Whether to emit compact-unwind for non-canonical entries. + // Note: maybe overriden by other constraints. + unsigned EmitCompactUnwindNonCanonical : 1; + /// The name of the relocation model to use. std::string RelocationModel; @@ -181,6 +185,7 @@ struct AssemblerInvocation { DwarfVersion = 0; EmbedBitcode = 0; EmitDwarfUnwind = EmitDwarfUnwindType::Default; + EmitCompactUnwindNonCanonical = false; } static bool CreateFromArgs(AssemblerInvocation &Res, @@ -348,6 +353,9 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, .Case("default", EmitDwarfUnwindType::Default); } + Opts.EmitCompactUnwindNonCanonical = + Args.hasArg(OPT_femit_compact_unwind_non_canonical); + Opts.AsSecureLogFile = Args.getLastArgValue(OPT_as_secure_log_file); return Success; @@ -401,6 +409,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts, MCTargetOptions MCOptions; MCOptions.EmitDwarfUnwind = Opts.EmitDwarfUnwind; + MCOptions.EmitCompactUnwindNonCanonical = Opts.EmitCompactUnwindNonCanonical; MCOptions.AsSecureLogFile = Opts.AsSecureLogFile; std::unique_ptr MAI( diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp index 2dbd8ed202728d..7c2dd51430c193 100644 --- a/lld/MachO/UnwindInfoSection.cpp +++ b/lld/MachO/UnwindInfoSection.cpp @@ -343,7 +343,8 @@ void UnwindInfoSectionImpl::relocateCompactUnwind( if (!d->unwindEntry) return; - // If we have DWARF unwind info, create a CU entry that points to it. + // If we have DWARF unwind info, create a slimmed-down CU entry that points + // to it. if (d->unwindEntry->getName() == section_names::ehFrame) { // The unwinder will look for the DWARF entry starting at the hint, // assuming the hint points to a valid CFI record start. If it @@ -360,7 +361,9 @@ void UnwindInfoSectionImpl::relocateCompactUnwind( cu.encoding = target->modeDwarfEncoding | dwarfOffsetHint; const FDE &fde = cast(d->getFile())->fdes[d->unwindEntry]; cu.functionLength = fde.funcLength; - cu.personality = fde.personality; + // Omit the DWARF personality from compact-unwind entry so that we + // don't need to encode it. + cu.personality = nullptr; cu.lsda = fde.lsda; return; } diff --git a/lld/test/MachO/Inputs/eh-frame-x86_64-r.o b/lld/test/MachO/Inputs/eh-frame-x86_64-r.o index d98e14ec81bffb62e83c2ee34228ba0962144f12..0da6b0fa750d56374a272231dc0095c8fe8e5d61 100644 GIT binary patch delta 93 zcmeys{egRfE)z4GG4o^trp>H+0t^fclPj2oR*X8Up!H0AlhnGBB_}`8H5K U2b6CQ;ZI)9GM|xQvODWa0F{{x2><{9 delta 93 zcmeys{egRfE)z4uai+-zOq*E+7=U1M1(P$A0K;ZoW=}>#1&|0B7y?N?Mg;~I2$#VI W%IARc?IHZh%UR|#Dol1~T?qiZI1JhV diff --git a/lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s b/lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s index 9b9dd66a3b7879..676577d6b17e9f 100644 --- a/lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s +++ b/lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s @@ -3,8 +3,12 @@ # REQUIRES: x86 # RUN: rm -rf %t; split-file %s %t -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/user_2.s -o %t/user_2.o -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/user_3.s -o %t/user_3.o +# RUN: llvm-mc -emit-compact-unwind-non-canonical=true -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/user_2.s -o %t/user_2.o +# RUN: llvm-mc -emit-compact-unwind-non-canonical=true -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/user_3.s -o %t/user_3.o + +## Test case for linking 3+ personaltiies (all globals) without crashing because all the non-canonical are DWARFs +# RUN: llvm-mc -emit-compact-unwind-non-canonical=false -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/user_4.s -o %t/user_4.o + # RUN: yaml2obj %t/combined.yaml > %t/combined.o ## Pre-condition: check that ___gxx_personality_v0 really is locally defined in combined.o before we proceed. @@ -21,6 +25,12 @@ ## ___gxx_personality_v0 (global), ___gxx_personality_v0(local), _personality_1, and _personality_2 # RUN: %lld -lSystem -dylib %t/user_3.o %t/combined.o %t/user_2.o -o %t/c.out +## check that we can link with 3+ personalities without crashing because +## non-canonical personalities are dwarf. +## This has ___gxx_personality_v0(global), ___gxx_personality_v0(local), and _personality_{1,2,3,4} +## Only the ___gxx_personality_v0(global) should have compact-unwind. The rest should have DWARFs. +# RUN: %lld -lSystem -lc++ %t/user_4.o %t/combined.o -o %t/d.out + ## Postlink checks. # RUN: llvm-nm %t/a.out | FileCheck %s --check-prefix=POSTCHECK # POSTCHECK: {{.*}} U ___gxx_personality_v0 @@ -30,6 +40,8 @@ # RUN: llvm-objdump --macho --unwind-info --syms --indirect-symbols --bind %t/b.out | FileCheck %s --check-prefixes=BC,CHECK -D#%x,OFF=0x100000000 # RUN: llvm-objdump --macho --unwind-info --syms --indirect-symbols --bind %t/c.out | FileCheck %s --check-prefixes=BC,C,CHECK -D#%x,OFF=0 +# RUN: llvm-objdump --macho --indirect-symbols --unwind-info --bind %t/d.out | FileCheck %s --check-prefixes=D -D#%x,OFF=0x100000000 + # A: Indirect symbols for (__DATA_CONST,__got) # A-NEXT: address index name # A: 0x[[#%x,GXX_PERSONALITY_LO:]] [[#]] ___gxx_personality_v0 @@ -53,11 +65,80 @@ # A-NEXT: segment section address type addend dylib symbol # A-NEXT: __DATA_CONST __got 0x[[#GXX_PERSONALITY_LO-0]] pointer 0 libc++abi ___gxx_personality_v0 + +# D: Indirect symbols for (__DATA_CONST,__got) +# D-NEXT: address index name +# D: 0x[[#%x,GXX_PERSONALITY_HI:]] [[#]] ___gxx_personality_v0 +# D: 0x[[#%x,PERSONALITY_1:]] [[#]] _personality_1 +# D: 0x[[#%x,PERSONALITY_2:]] [[#]] _personality_2 +# D: 0x[[#%x,PERSONALITY_3:]] [[#]] _personality_3 +# D: 0x[[#%x,PERSONALITY_4:]] [[#]] _personality_4 +# D: 0x[[#%x,GXX_PERSONALITY_LO:]] [[#]] ___gxx_personality_v0 + +# D: Contents of __unwind_info section: +# D: Personality functions: (count = 1) + personality[1]: 0x{{0*}}[[#GXX_PERSONALITY_HI-OFF]] + +# D: Bind table: +# D: segment section address type addend dylib symbol +# D: __DATA_CONST __got 0x[[#GXX_PERSONALITY_HI-0]] pointer 0 libc++abi ___gxx_personality_v0 + + ## Error cases. ## Check that dylib symbols are picked (which means without libc++, we'd get an undefined symbol error. # RUN: not %lld -lSystem %t/user_2.o %t/combined.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERRORCHECK # ERRORCHECK: {{.*}} undefined symbol: ___gxx_personality_v0 +#--- user_4.s +.globl _main, _personality_1, _personality_2, _personality_3, _personality_4 + +.text + +_baz1: + .cfi_startproc + .cfi_personality 155, _personality_1 + .cfi_def_cfa_offset 16 + retq + .cfi_endproc + +_baz2: + .cfi_startproc + .cfi_personality 155, _personality_2 + .cfi_def_cfa_offset 16 + retq + .cfi_endproc + +_baz3: + .cfi_startproc + .cfi_personality 155, _personality_3 + .cfi_def_cfa_offset 16 + retq + .cfi_endproc + + +_baz4: + .cfi_startproc + .cfi_personality 155, _personality_4 + .cfi_def_cfa_offset 16 + retq + .cfi_endproc + +_main: + .cfi_startproc + .cfi_personality 155, ___gxx_personality_v0 + .cfi_def_cfa_offset 16 + retq + .cfi_endproc + +_personality_1: + retq +_personality_2: + retq +_personality_3: + retq +_personality_4: + retq + #--- user_3.s .globl _baz3 .private_extern ___gxx_personality_v0 diff --git a/lld/test/MachO/compact-unwind-generated.test b/lld/test/MachO/compact-unwind-generated.test index 4dbfbf5ce6809f..b81236b198c3bd 100644 --- a/lld/test/MachO/compact-unwind-generated.test +++ b/lld/test/MachO/compact-unwind-generated.test @@ -15,7 +15,7 @@ # those from the linked output # RUN: %python %S/tools/generate-cfi-funcs.py --seed=johnnyapple >%t.s -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 -o %t.o %t.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 -emit-compact-unwind-non-canonical=true -o %t.o %t.s # RUN: %lld -Z -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem -o %t %t.o # RUN: llvm-objdump --unwind-info --syms %t %t.o >%t.dump # RUN: %python %S/tools/validate-unwind-info.py %t.dump diff --git a/lld/test/MachO/compact-unwind-lsda-folding.s b/lld/test/MachO/compact-unwind-lsda-folding.s index 8e3d11fc6f7110..cdabe1b1fe685a 100644 --- a/lld/test/MachO/compact-unwind-lsda-folding.s +++ b/lld/test/MachO/compact-unwind-lsda-folding.s @@ -4,7 +4,7 @@ # REQUIRES: x86 # RUN: rm -rf %t; mkdir %t -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -o %t/lsda.o %s +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -emit-compact-unwind-non-canonical=true -o %t/lsda.o %s # RUN: %lld -dylib --icf=all -lSystem -lc++ -o %t/liblsda.dylib %t/lsda.o # RUN: llvm-objdump --macho --syms --unwind-info %t/liblsda.dylib | FileCheck %s diff --git a/lld/test/MachO/compact-unwind-stack-ind.s b/lld/test/MachO/compact-unwind-stack-ind.s index 13d5e929d2dbfb..045abbe2fc1d0c 100644 --- a/lld/test/MachO/compact-unwind-stack-ind.s +++ b/lld/test/MachO/compact-unwind-stack-ind.s @@ -1,5 +1,5 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 -emit-compact-unwind-non-canonical=true %s -o %t.o # RUN: %lld -arch x86_64 -dylib %t.o -o %t.dylib # RUN: llvm-objdump --macho --syms --unwind-info %t.dylib | FileCheck %s diff --git a/lld/test/MachO/compact-unwind.s b/lld/test/MachO/compact-unwind.s index 25af4dd7eae1da..fa73ccb10a32a2 100644 --- a/lld/test/MachO/compact-unwind.s +++ b/lld/test/MachO/compact-unwind.s @@ -1,21 +1,21 @@ # REQUIRES: x86, aarch64 # RUN: rm -rf %t; split-file %s %t -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/my-personality.s -o %t/x86_64-my-personality.o -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/main.s -o %t/x86_64-main.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 -emit-compact-unwind-non-canonical=true %t/my-personality.s -o %t/x86_64-my-personality.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 -emit-compact-unwind-non-canonical=true %t/main.s -o %t/x86_64-main.o # RUN: %lld -arch x86_64 -lSystem -lc++ %t/x86_64-my-personality.o %t/x86_64-main.o -o %t/x86_64-personality-first # RUN: llvm-objdump --macho --unwind-info --syms --indirect-symbols --rebase %t/x86_64-personality-first | FileCheck %s --check-prefixes=FIRST,CHECK -D#%x,BASE=0x100000000 -DSEG=__TEXT # RUN: %lld -dead_strip -arch x86_64 -lSystem -lc++ %t/x86_64-main.o %t/x86_64-my-personality.o -o %t/x86_64-personality-second # RUN: llvm-objdump --macho --unwind-info --syms --indirect-symbols --rebase %t/x86_64-personality-second | FileCheck %s --check-prefixes=SECOND,CHECK -D#%x,BASE=0x100000000 -DSEG=__TEXT -# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin19.0.0 %t/my-personality.s -o %t/arm64-my-personality.o -# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin19.0.0 %t/main.s -o %t/arm64-main.o +# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin19.0.0 -emit-compact-unwind-non-canonical=true %t/my-personality.s -o %t/arm64-my-personality.o +# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin19.0.0 -emit-compact-unwind-non-canonical=true %t/main.s -o %t/arm64-main.o # RUN: %lld -arch arm64 -lSystem -lc++ %t/arm64-my-personality.o %t/arm64-main.o -o %t/arm64-personality-first # RUN: llvm-objdump --macho --unwind-info --syms --indirect-symbols --rebase %t/arm64-personality-first | FileCheck %s --check-prefixes=FIRST,CHECK -D#%x,BASE=0x100000000 -DSEG=__TEXT # RUN: %lld -dead_strip -arch arm64 -lSystem -lc++ %t/arm64-main.o %t/arm64-my-personality.o -o %t/arm64-personality-second # RUN: llvm-objdump --macho --unwind-info --syms --indirect-symbols --rebase %t/arm64-personality-second | FileCheck %s --check-prefixes=SECOND,CHECK -D#%x,BASE=0x100000000 -DSEG=__TEXT -# RUN: llvm-mc -filetype=obj -triple=arm64_32-apple-watchos %t/my-personality.s -o %t/arm64-32-my-personality.o -# RUN: llvm-mc -filetype=obj -triple=arm64_32-apple-watchos %t/main.s -o %t/arm64-32-main.o +# RUN: llvm-mc -filetype=obj -triple=arm64_32-apple-watchos -emit-compact-unwind-non-canonical=true %t/my-personality.s -o %t/arm64-32-my-personality.o +# RUN: llvm-mc -filetype=obj -triple=arm64_32-apple-watchos -emit-compact-unwind-non-canonical=true %t/main.s -o %t/arm64-32-main.o # RUN: %lld-watchos -lSystem -lc++ %t/arm64-32-my-personality.o %t/arm64-32-main.o -o %t/arm64-32-personality-first # RUN: llvm-objdump --macho --unwind-info --syms --indirect-symbols --rebase %t/arm64-32-personality-first | FileCheck %s --check-prefixes=FIRST,CHECK -D#%x,BASE=0x4000 -DSEG=__TEXT # RUN: %lld-watchos -dead_strip -lSystem -lc++ %t/arm64-32-main.o %t/arm64-32-my-personality.o -o %t/arm64-32-personality-second diff --git a/lld/test/MachO/eh-frame-personality-dedup.s b/lld/test/MachO/eh-frame-personality-dedup.s index b14ddb23465def..8a2cabb369a101 100644 --- a/lld/test/MachO/eh-frame-personality-dedup.s +++ b/lld/test/MachO/eh-frame-personality-dedup.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: rm -rf %t; split-file %s %t -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/eh-frame.s -o %t/eh-frame.o -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/cu.s -o %t/cu.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 -emit-compact-unwind-non-canonical=true %t/eh-frame.s -o %t/eh-frame.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 -emit-compact-unwind-non-canonical=true %t/cu.s -o %t/cu.o # RUN: %lld -dylib %t/cu.o %t/eh-frame.o -o %t/out ## Sanity check: we want our input to contain a section (and not symbol) diff --git a/lld/test/MachO/eh-frame.s b/lld/test/MachO/eh-frame.s index 2ebcf96feccc21..64fd364c87a591 100644 --- a/lld/test/MachO/eh-frame.s +++ b/lld/test/MachO/eh-frame.s @@ -1,7 +1,7 @@ # REQUIRES: x86, aarch64 # RUN: rm -rf %t; mkdir %t -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos10.15 %s -o %t/eh-frame-x86_64.o +# RUN: llvm-mc -emit-compact-unwind-non-canonical=true -filetype=obj -triple=x86_64-apple-macos10.15 %s -o %t/eh-frame-x86_64.o # RUN: %lld -lSystem -lc++ %t/eh-frame-x86_64.o -o %t/eh-frame-x86_64 # RUN: llvm-objdump --macho --syms --indirect-symbols --unwind-info \ # RUN: --dwarf=frames %t/eh-frame-x86_64 | FileCheck %s -D#BASE=0x100000000 -D#DWARF_ENC=4 @@ -20,7 +20,7 @@ # RUN: llvm-nm -m %t/eh-frame-x86_64-r | FileCheck %s --check-prefix NO-EH-SYMS # RUN: llvm-readobj --section-headers %t/eh-frame-x86_64-r | FileCheck %s --check-prefix=ALIGN -D#ALIGN=3 -# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos11.0 %s -o %t/eh-frame-arm64.o +# RUN: llvm-mc -filetype=obj -emit-compact-unwind-non-canonical=true -triple=arm64-apple-macos11.0 %s -o %t/eh-frame-arm64.o # RUN: %lld -arch arm64 -lSystem -lc++ %t/eh-frame-arm64.o -o %t/eh-frame-arm64 # RUN: llvm-objdump --macho --syms --indirect-symbols --unwind-info \ # RUN: --dwarf=frames %t/eh-frame-arm64 | FileCheck %s -D#BASE=0x100000000 -D#DWARF_ENC=3 @@ -56,22 +56,21 @@ # CHECK-DAG: [[#%x,MY_PERSONALITY:]] g F __TEXT,__text _my_personality # CHECK: Contents of __unwind_info section: # CHECK: Version: 0x1 -# CHECK: Number of personality functions in array: 0x2 +# CHECK: Number of personality functions in array: 0x1 # CHECK: Number of indices in array: 0x2 -# CHECK: Personality functions: (count = 2) +# CHECK: Personality functions: (count = 1) # CHECK: personality[1]: 0x[[#%.8x,GXX_PERSONALITY_GOT - BASE]] -# CHECK: personality[2]: 0x[[#%.8x,MY_PERSONALITY_GOT - BASE]] # CHECK: LSDA descriptors: # CHECK: [0]: function offset=0x[[#%.8x,F - BASE]], LSDA offset=0x[[#%.8x,EXCEPT0 - BASE]] # CHECK: [1]: function offset=0x[[#%.8x,G - BASE]], LSDA offset=0x[[#%.8x,EXCEPT1 - BASE]] # CHECK: [2]: function offset=0x[[#%.8x,H - BASE]], LSDA offset=0x[[#%.8x,EXCEPT2 - BASE]] # CHECK: Second level indices: # CHECK: Second level index[0]: -# CHECK: [0]: function offset=0x[[#%.8x,F - BASE]], encoding[{{.*}}]=0x52{{.*}} -# CHECK: [1]: function offset=0x[[#%.8x,NO_UNWIND - BASE]], encoding[{{.*}}]=0x00000000 -# CHECK: [2]: function offset=0x[[#%.8x,G - BASE]], encoding[{{.*}}]=0x1[[#%x,DWARF_ENC]][[#%.6x, G_DWARF_OFF:]] -# CHECK: [3]: function offset=0x[[#%.8x,H - BASE]], encoding[{{.*}}]=0x2[[#%x,DWARF_ENC]][[#%.6x, H_DWARF_OFF:]] -# CHECK: [4]: function offset=0x[[#%.8x,MY_PERSONALITY - BASE]], encoding[{{.*}}]=0x00000000 +# CHECK [0]: function offset=0x[[#%.8x,F - BASE]], encoding[{{.*}}]=0x52{{.*}} +# CHECK [1]: function offset=0x[[#%.8x,NO_UNWIND - BASE]], encoding[{{.*}}]=0x00000000 +# CHECK: [2]: function offset=0x[[#%.8x,G - BASE]], encoding[{{.*}}]=0x0[[#%x,DWARF_ENC]][[#%.6x, G_DWARF_OFF:]] +# CHECK: [3]: function offset=0x[[#%.8x,H - BASE]], encoding[{{.*}}]=0x0[[#%x,DWARF_ENC]][[#%.6x, H_DWARF_OFF:]] +# CHECK: [4]: function offset=0x[[#%.8x,MY_PERSONALITY - BASE]], encoding[{{.*}}]=0x00000000 # CHECK: .debug_frame contents: # CHECK: .eh_frame contents: diff --git a/lld/test/MachO/icf-only-lsda-folded.s b/lld/test/MachO/icf-only-lsda-folded.s index 81cbe9955131d1..fb4296d3d37743 100644 --- a/lld/test/MachO/icf-only-lsda-folded.s +++ b/lld/test/MachO/icf-only-lsda-folded.s @@ -11,7 +11,7 @@ ## the broken output would only appear if the compact unwind entry that pointed ## to it was not itself folded. -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/test.s -o %t/test.o +# RUN: llvm-mc -emit-compact-unwind-non-canonical=true -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/test.s -o %t/test.o # RUN: %lld -dylib -dead_strip --icf=all %t/test.o -o %t/test # RUN: llvm-objdump --macho --syms --unwind-info %t/test | FileCheck %s diff --git a/lld/test/MachO/icf.s b/lld/test/MachO/icf.s index 03b474388f2eb3..68ed369188e914 100644 --- a/lld/test/MachO/icf.s +++ b/lld/test/MachO/icf.s @@ -7,8 +7,8 @@ ## groups, we use `mov` instructions with a variety of immediates, with ## different immediate values for each group. -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/main.s -o %t/main.o -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/abs.s -o %t/abs.o +# RUN: llvm-mc -emit-compact-unwind-non-canonical=true -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/main.s -o %t/main.o +# RUN: llvm-mc -emit-compact-unwind-non-canonical=true -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/abs.s -o %t/abs.o # RUN: %lld -lSystem --icf=all -o %t/main %t/main.o %t/abs.o # RUN: llvm-objdump -d --syms --dwarf=frames %t/main | FileCheck %s diff --git a/lld/test/MachO/invalid/compact-unwind-bad-reloc.s b/lld/test/MachO/invalid/compact-unwind-bad-reloc.s index 61c7a429683750..6507f5c057b9c3 100644 --- a/lld/test/MachO/invalid/compact-unwind-bad-reloc.s +++ b/lld/test/MachO/invalid/compact-unwind-bad-reloc.s @@ -1,6 +1,6 @@ # REQUIRES: x86 # RUN: rm -rf %t; split-file %s %t -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/bad-function.s -o %t/bad-function.o +# RUN: llvm-mc -emit-compact-unwind-non-canonical=true -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/bad-function.s -o %t/bad-function.o # RUN: not %lld -lSystem -dylib -lc++ %t/bad-function.o -o /dev/null 2>&1 | FileCheck %s # CHECK: error: {{.*}}bad-function.o:(__compact_unwind+0x0) references section __data which is not in segment __TEXT # CHECK: error: {{.*}}bad-function.o:(__compact_unwind+0x20) references section __data which is not in segment __TEXT diff --git a/lld/test/MachO/invalid/compact-unwind-personalities.s b/lld/test/MachO/invalid/compact-unwind-personalities.s index 94ed68b60159ca..25ee4bd17929ff 100644 --- a/lld/test/MachO/invalid/compact-unwind-personalities.s +++ b/lld/test/MachO/invalid/compact-unwind-personalities.s @@ -1,10 +1,29 @@ # REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %s -o %t.o + +# RUN: llvm-mc -emit-compact-unwind-non-canonical=true -filetype=obj -triple=x86_64-apple-darwin19.0.0 %s -o %t.o # RUN: not %lld -lSystem -lc++ %t.o -o %t 2>&1 | FileCheck %s --check-prefix=TOO-MANY # RUN: not %lld -lSystem %t.o -o %t 2>&1 | FileCheck %s --check-prefix=UNDEF # TOO-MANY: error: too many personalities (4) for compact unwind to encode # UNDEF: error: undefined symbol: ___gxx_personality_v0 +## Tests that we can handle more than 3 personalities with DWARFs +# RUN: llvm-mc -emit-compact-unwind-non-canonical=false -filetype=obj -triple=x86_64-apple-darwin19.0.0 %s -o %t-dwarf.o +# RUN: %lld -lSystem -lc++ %t-dwarf.o -o %t-dwarf +# RUN: llvm-objdump --macho --indirect-symbols --dwarf=frames %t-dwarf | FileCheck %s --check-prefix=DWARF -D#BASE=0x100000000 + +# DWARF: Indirect symbols +# DWARF: address index name +# DWARF: 0x[[#%x,GXX_PERSONALITY:]] {{.*}} ___gxx_personality_v0 +# DWARF: 0x[[#%x,PERSONALITY_1:]] {{.*}} _personality_1 +# DWARF: 0x[[#%x,PERSONALITY_2:]] {{.*}} _personality_2 +# DWARF: 0x[[#%x,PERSONALITY_3:]] {{.*}} _personality_3 +# DWARF: .eh_frame contents: +# DWARF: Personality Address: [[#%.16x,GXX_PERSONALITY]] +# DWARF: Personality Address: [[#%.16x,PERSONALITY_1]] +# DWARF: Personality Address: [[#%.16x,PERSONALITY_2]] +# DWARF: Personality Address: [[#%.16x,PERSONALITY_3]] + + .globl _main, _personality_1, _personality_2, _personality_3 .text diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h index 354f9d8e993f05..c219991f65a59b 100644 --- a/llvm/include/llvm/MC/MCAsmBackend.h +++ b/llvm/include/llvm/MC/MCAsmBackend.h @@ -25,7 +25,8 @@ class MCRelaxableFragment; class MCSymbol; class MCAsmLayout; class MCAssembler; -class MCCFIInstruction; +class MCContext; +struct MCDwarfFrameInfo; struct MCFixupKindInfo; class MCInst; class MCObjectStreamer; @@ -210,8 +211,8 @@ class MCAsmBackend { virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {} /// Generate the compact unwind encoding for the CFI instructions. - virtual uint32_t - generateCompactUnwindEncoding(ArrayRef) const { + virtual uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, + const MCContext *Ctxt) const { return 0; } @@ -219,6 +220,8 @@ class MCAsmBackend { virtual bool isMicroMips(const MCSymbol *Sym) const { return false; } + + bool isDarwinCanonicalPersonality(const MCSymbol *Sym) const; }; } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index 26ee1803cb6ef5..6669ebca4b6194 100644 --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -788,6 +788,7 @@ class MCContext { void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; } unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; } EmitDwarfUnwindType emitDwarfUnwindInfo() const; + bool emitCompactUnwindNonCanonical() const; void setGenDwarfFileNumber(unsigned FileNumber) { GenDwarfFileNumber = FileNumber; diff --git a/llvm/include/llvm/MC/MCTargetOptions.h b/llvm/include/llvm/MC/MCTargetOptions.h index 74fc60823a1b9f..9fc1e07d085eba 100644 --- a/llvm/include/llvm/MC/MCTargetOptions.h +++ b/llvm/include/llvm/MC/MCTargetOptions.h @@ -85,6 +85,10 @@ class MCTargetOptions { /// integrated assembler. std::vector IASSearchPaths; + // Whether to emit compact-unwind for non-canonical personality + // functions on Darwins. + bool EmitCompactUnwindNonCanonical : 1; + MCTargetOptions(); /// getABIName - If this returns a non-empty string this represents the diff --git a/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h b/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h index e7211740ec4819..7f6ee6c8be224a 100644 --- a/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h +++ b/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h @@ -35,6 +35,8 @@ bool getDwarf64(); EmitDwarfUnwindType getEmitDwarfUnwind(); +bool getEmitCompactUnwindNonCanonical(); + bool getShowMCInst(); bool getFatalWarnings(); diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp index c4e505146d44f0..6c6fd1af4f57de 100644 --- a/llvm/lib/MC/MCAsmBackend.cpp +++ b/llvm/lib/MC/MCAsmBackend.cpp @@ -115,3 +115,14 @@ bool MCAsmBackend::fixupNeedsRelaxationAdvanced( return true; return fixupNeedsRelaxation(Fixup, Value, DF, Layout); } + +bool MCAsmBackend::isDarwinCanonicalPersonality(const MCSymbol *Sym) const { + if (Sym && Sym->isMachO()) { + StringRef name = Sym->getName(); + // XXX: We intentionally leave out "__gcc_personality_v0" because, despite + // being system-defined like these two, it is not very commonly-used. + // Reserving an empty slot for it seems silly. + return name == "__gxx_personality_v0" || name == "__objc_personality_v0"; + } + return false; +} diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 6ec1a9ae8444df..871532a684f924 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -925,6 +925,12 @@ EmitDwarfUnwindType MCContext::emitDwarfUnwindInfo() const { return TargetOptions->EmitDwarfUnwind; } +bool MCContext::emitCompactUnwindNonCanonical() const { + if (TargetOptions) + return TargetOptions->EmitCompactUnwindNonCanonical; + return false; +} + void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) { // MCDwarf needs the root file as well as the compilation directory. // If we find a '.file 0' directive that will supersede these values. diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 0cb04594522b2b..c0e9f42406e9bc 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -126,7 +126,7 @@ void MCStreamer::emitExplicitComments() {} void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) { for (auto &FI : DwarfFrameInfos) FI.CompactUnwindEncoding = - (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0); + (MAB ? MAB->generateCompactUnwindEncoding(&FI, &Context) : 0); } /// EmitIntValue - Special case of EmitValue that avoids the client having to diff --git a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp index 0667ca59830ce4..8a4923e4792fb5 100644 --- a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp +++ b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp @@ -39,6 +39,7 @@ MCOPT(bool, IncrementalLinkerCompatible) MCOPT(int, DwarfVersion) MCOPT(bool, Dwarf64) MCOPT(EmitDwarfUnwindType, EmitDwarfUnwind) +MCOPT(bool, EmitCompactUnwindNonCanonical) MCOPT(bool, ShowMCInst) MCOPT(bool, FatalWarnings) MCOPT(bool, NoWarn) @@ -87,6 +88,14 @@ llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() { "Use target platform default"))); MCBINDOPT(EmitDwarfUnwind); + static cl::opt EmitCompactUnwindNonCanonical( + "emit-compact-unwind-non-canonical", + cl::desc( + "Whether to try to emit Compact Unwind for non canonical entries."), + cl::init( + false)); // By default, use DWARF for non-canonical personalities. + MCBINDOPT(EmitCompactUnwindNonCanonical); + static cl::opt ShowMCInst( "asm-show-inst", cl::desc("Emit internal instruction representation to assembly file")); @@ -135,6 +144,7 @@ MCTargetOptions llvm::mc::InitMCTargetOptionsFromFlags() { Options.MCNoDeprecatedWarn = getNoDeprecatedWarn(); Options.MCNoTypeCheck = getNoTypeCheck(); Options.EmitDwarfUnwind = getEmitDwarfUnwind(); + Options.EmitCompactUnwindNonCanonical = getEmitCompactUnwindNonCanonical(); Options.AsSecureLogFile = getAsSecureLogFile(); return Options; diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp index 2089a24f3a5a1e..7f20d736998299 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -564,10 +564,14 @@ class DarwinAArch64AsmBackend : public AArch64AsmBackend { } /// Generate the compact unwind encoding from the CFI directives. - uint32_t generateCompactUnwindEncoding( - ArrayRef Instrs) const override { + uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, + const MCContext *Ctxt) const override { + ArrayRef Instrs = FI->Instructions; if (Instrs.empty()) return CU::UNWIND_ARM64_MODE_FRAMELESS; + if (!isDarwinCanonicalPersonality(FI->Personality) && + !Ctxt->emitCompactUnwindNonCanonical()) + return CU::UNWIND_ARM64_MODE_DWARF; bool HasFP = false; unsigned StackSize = 0; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index df142b85256eb1..ea1363413b4a1e 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -1107,14 +1107,19 @@ enum CompactUnwindEncodings { /// encoded in compact unwind, the method returns UNWIND_ARM_MODE_DWARF which /// tells the runtime to fallback and unwind using dwarf. uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding( - ArrayRef Instrs) const { + const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const { DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "generateCU()\n"); // Only armv7k uses CFI based unwinding. if (Subtype != MachO::CPU_SUBTYPE_ARM_V7K) return 0; // No .cfi directives means no frame. + ArrayRef Instrs = FI->Instructions; if (Instrs.empty()) return 0; + if (!isDarwinCanonicalPersonality(FI->Personality) && + !Ctxt->emitCompactUnwindNonCanonical()) + return CU::UNWIND_ARM_MODE_DWARF; + // Start off assuming CFA is at SP+0. unsigned CFARegister = ARM::SP; int CFARegisterOffset = 0; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h index 85013b5f099a68..ace573c8fa96cf 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h @@ -11,6 +11,7 @@ #include "ARMAsmBackend.h" #include "llvm/BinaryFormat/MachO.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCObjectWriter.h" namespace llvm { @@ -32,8 +33,8 @@ class ARMAsmBackendDarwin : public ARMAsmBackend { /*Is64Bit=*/false, cantFail(MachO::getCPUType(TT)), Subtype); } - uint32_t generateCompactUnwindEncoding( - ArrayRef Instrs) const override; + uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, + const MCContext *Ctxt) const override; }; } // end namespace llvm diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index f06b695823fade..7ffa2d2f81c97e 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -1350,9 +1350,13 @@ class DarwinX86AsmBackend : public X86AsmBackend { /// Implementation of algorithm to generate the compact unwind encoding /// for the CFI instructions. - uint32_t - generateCompactUnwindEncoding(ArrayRef Instrs) const override { + uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI, + const MCContext *Ctxt) const override { + ArrayRef Instrs = FI->Instructions; if (Instrs.empty()) return 0; + if (!isDarwinCanonicalPersonality(FI->Personality) && + !Ctxt->emitCompactUnwindNonCanonical()) + return CU::UNWIND_MODE_DWARF; // Reset the saved registers. unsigned SavedRegIdx = 0; diff --git a/llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll b/llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll index 7461f746fec992..71fa028fc14351 100644 --- a/llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll +++ b/llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple x86_64-apple-darwin11 -mcpu corei7 -filetype=obj -o - | llvm-objdump -d --unwind-info -s - | FileCheck %s +; RUN: llc < %s -mtriple x86_64-apple-darwin11 -mcpu corei7 -emit-compact-unwind-non-canonical=true -filetype=obj -o - | llvm-objdump -d --unwind-info -s - | FileCheck %s ; Regression test for http://llvm.org/bugs/show_bug.cgi?id=20800. ; ModuleID = 'asan_report.ii' diff --git a/llvm/test/CodeGen/X86/compact-unwind.ll b/llvm/test/CodeGen/X86/compact-unwind.ll index b9860fb8553888..8e8845b281eaf8 100644 --- a/llvm/test/CodeGen/X86/compact-unwind.ll +++ b/llvm/test/CodeGen/X86/compact-unwind.ll @@ -1,17 +1,17 @@ -; RUN: llc < %s -frame-pointer=all -mtriple x86_64-apple-darwin11 -mcpu corei7 | FileCheck -check-prefix=ASM %s -; RUN: llc < %s -frame-pointer=all -mtriple x86_64-apple-darwin11 -mcpu corei7 -filetype=obj -o - \ +; RUN: llc < %s -frame-pointer=all -mtriple x86_64-apple-darwin11 -mcpu corei7 -emit-compact-unwind-non-canonical=true | FileCheck -check-prefix=ASM %s +; RUN: llc < %s -frame-pointer=all -mtriple x86_64-apple-darwin11 -mcpu corei7 -filetype=obj -emit-compact-unwind-non-canonical=true -o - \ ; RUN: | llvm-objdump --triple=x86_64-apple-darwin11 --unwind-info - \ ; RUN: | FileCheck -check-prefix=CU %s -; RUN: llc < %s -frame-pointer=all -mtriple x86_64-apple-darwin11 -mcpu corei7 \ -; RUN: | llvm-mc -triple x86_64-apple-darwin11 -filetype=obj -o - \ +; RUN: llc < %s -frame-pointer=all -mtriple x86_64-apple-darwin11 -mcpu corei7 -emit-compact-unwind-non-canonical=true \ +; RUN: | llvm-mc -triple x86_64-apple-darwin11 -filetype=obj -emit-compact-unwind-non-canonical=true -o - \ ; RUN: | llvm-objdump --triple=x86_64-apple-darwin11 --unwind-info - \ ; RUN: | FileCheck -check-prefix=FROM-ASM %s -; RUN: llc < %s -mtriple x86_64-apple-macosx10.8.0 -mcpu corei7 -filetype=obj -o - \ +; RUN: llc < %s -mtriple x86_64-apple-macosx10.8.0 -mcpu corei7 -filetype=obj -emit-compact-unwind-non-canonical=true -o - \ ; RUN: | llvm-objdump --triple=x86_64-apple-macosx10.8.0 --unwind-info - \ ; RUN: | FileCheck -check-prefix=NOFP-CU %s ; RUN: llc < %s -mtriple x86_64-apple-darwin11 -mcpu corei7 \ -; RUN: | llvm-mc -triple x86_64-apple-darwin11 -filetype=obj -o - \ +; RUN: | llvm-mc -triple x86_64-apple-darwin11 -filetype=obj -emit-compact-unwind-non-canonical=true -o - \ ; RUN: | llvm-objdump --triple=x86_64-apple-darwin11 --unwind-info - \ ; RUN: | FileCheck -check-prefix=NOFP-FROM-ASM %s diff --git a/llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s b/llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s index b40f11ac7b7036..80efa180318af6 100644 --- a/llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s +++ b/llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s @@ -1,4 +1,4 @@ -// RUN: llvm-mc -triple=arm64-apple-ios -filetype=obj < %s | \ +// RUN: llvm-mc -triple=arm64-apple-ios -filetype=obj -emit-compact-unwind-non-canonical=true < %s | \ // RUN: llvm-objdump --macho --unwind-info - | \ // RUN: FileCheck %s // diff --git a/llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s b/llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s index 89dc56b8aa87f0..9cd2c8ad49534a 100644 --- a/llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s +++ b/llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s @@ -1,11 +1,11 @@ // RUN: rm -rf %t; mkdir %t -// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o +// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o -emit-compact-unwind-non-canonical=true // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix TWO-FDES -// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o +// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o -emit-compact-unwind-non-canonical=true // RUN: llvm-objdump --macho --dwarf=frames %t/arm64.o | FileCheck %s --check-prefix ONE-FDE -// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o +// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o -emit-compact-unwind-non-canonical=true // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix ONE-FDE -// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o +// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o -emit-compact-unwind-non-canonical=true // RUN: llvm-objdump --macho --dwarf=frames %t/arm64-dwarf.o | FileCheck %s --check-prefix TWO-FDES // TWO-FDES: FDE diff --git a/llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s b/llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s index 51ec86b8d66af8..65890bcae750f8 100644 --- a/llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s +++ b/llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s @@ -1,4 +1,4 @@ -@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s +@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -emit-compact-unwind-non-canonical=true -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s @ CHECK: Contents of __compact_unwind section: diff --git a/llvm/test/MC/X86/compact-unwind.s b/llvm/test/MC/X86/compact-unwind.s index 4f84a2abb47799..8c835ce9af571a 100644 --- a/llvm/test/MC/X86/compact-unwind.s +++ b/llvm/test/MC/X86/compact-unwind.s @@ -1,4 +1,4 @@ -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s | llvm-objdump --unwind-info - | FileCheck %s +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s -emit-compact-unwind-non-canonical=true | llvm-objdump --unwind-info - | FileCheck %s .section __TEXT,__text,regular,pure_instructions .macosx_version_min 10, 10