-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LSDA] Take ttype_index into account when taking unwind action #106446
Conversation
If cs_action != 0, we should check the ttype_index field in action record. If ttype_index == 0, a clean up action is taken.
r? @cuviper (rustbot has picked a reviewer for you, use r? to override) |
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
I don't know these details about unwinding -- maybe r? @Amanieu |
I think this looks correct, based on the implementation in libcxxabi. However I think this change also needs to be applied to the SJLJ code path. |
I'm surprised this is needed though, I didn't think LLVM emitted code like this. Could you expand on the cases where this causes problems on AIX? |
Hi @Amanieu , there are numbers of such cases when bootstrapping rust on AIX. Here's the reduced case from ; ModuleID = 'bugpoint-reduced-simplified.bc'
source_filename = "getopts.b321dad9-cgu.8"
target datalayout = "E-m:a-i64:64-n32:64-S128-v256:256:256-v512:512:512"
target triple = "powerpc64-ibm-aix"
define hidden void @_RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts() unnamed_addr #0 personality ptr @rust_eh_personality {
br i1 poison, label %8, label %1
1: ; preds = %0
br label %2
2: ; preds = %5, %1
br i1 poison, label %3, label %5
3: ; preds = %2
invoke void @_RINvNvMs_NtCs3Cu2L953qsK_5alloc7raw_vecINtB7_6RawVecppE7reserve21do_reserve_and_handlehNtNtB9_5alloc6GlobalECsc4UU1XxBbkb_7getopts()
to label %4 unwind label %6
4: ; preds = %3
br label %5
5: ; preds = %4, %2
br i1 poison, label %8, label %2
6: ; preds = %3
%7 = landingpad { ptr, i32 }
cleanup
resume { ptr, i32 } %7
8: ; preds = %5, %0
ret void
}
declare i32 @rust_eh_personality(i32, i32, i64, ptr, ptr) unnamed_addr #0
declare hidden void @_RINvNvMs_NtCs3Cu2L953qsK_5alloc7raw_vecINtB7_6RawVecppE7reserve21do_reserve_and_handlehNtNtB9_5alloc6GlobalECsc4UU1XxBbkb_7getopts() unnamed_addr #0
attributes #0 = { "target-cpu"="pwr7" } On AIX, we have .csect .text[PR],5
.globl _RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts[DS],hidden # -- Begin function _RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts
.globl ._RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts,hidden
.align 4
.csect _RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts[DS],3
.vbyte 8, ._RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts # @_RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts
.vbyte 8, TOC[TC0]
.vbyte 8, 0
.csect .text[PR],5
._RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts:
L..func_begin0:
# %bb.0:
mflr 0
stdu 1, -112(1)
std 0, 128(1)
bc 12, 20, L..BB0_3
# %bb.1:
bc 12, 20, L..BB0_3
# %bb.2:
L..tmp0:
bl ._RINvNvMs_NtCs3Cu2L953qsK_5alloc7raw_vecINtB7_6RawVecppE7reserve21do_reserve_and_handlehNtNtB9_5alloc6GlobalECsc4UU1XxBbkb_7getopts[PR]
nop
L..tmp1:
L..BB0_3:
addi 1, 1, 112
ld 0, 16(1)
mtlr 0
blr
L..BB0_4:
L..tmp2:
bl ._Unwind_Resume[PR]
nop
L.._RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts0:
.vbyte 4, 0x00000000 # Traceback table begin
.byte 0x00 # Version = 0
.byte 0x09 # Language = CPlusPlus
.byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
# +HasTraceBackTableOffset, -IsInternalProcedure
# -HasControlledStorage, -IsTOCless
# -IsFloatingPointPresent
# -IsFloatingPointOperationLogOrAbortEnabled
.byte 0x41 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
# OnConditionDirective = 0, -IsCRSaved, +IsLRSaved
.byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
.byte 0x80 # +HasExtensionTable, -HasVectorInfo, NumOfGPRsSaved = 0
.byte 0x00 # NumberOfFixedParms = 0
.byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
.vbyte 4, L.._RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts0-._RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts # Function size
.vbyte 2, 0x00d7 # Function name len = 215
.byte "_RINvXs5_NtCs3Cu2L953qsK_5alloc6stringNtB6_6StringINtNtNtNtCs7eLrLyzl9su_4core4iter6traits7collect12FromIteratorReE9from_iterINtNtNtBS_8adapters4take4TakeINtNtNtBS_7sources6repeat6RepeatB1L_EEECsc4UU1XxBbkb_7getopts" # Function Name
.byte 0x08 # ExtensionTableFlag = TB_EH_INFO
.align 2
.vbyte 8, L..C0-TOC[TC0] # EHInfo Table
L..func_end0:
.csect .gcc_except_table[RO],2
.align 2
GCC_except_table0:
L..exception0:
.byte 255 # @LPStart Encoding = omit
.byte 255 # @TType Encoding = omit
.byte 3 # Call site Encoding = udata4
.byte 26
.vbyte 4, L..tmp0-L..func_begin0 # >> Call Site 1 <<
.vbyte 4, L..tmp1-L..tmp0 # Call between L..tmp0 and L..tmp1
.vbyte 4, L..tmp2-L..func_begin0 # jumps to L..tmp2
.byte 1 # On action: 1
.vbyte 4, L..tmp1-L..func_begin0 # >> Call Site 2 <<
.vbyte 4, L..func_end0-L..tmp1 # Call between L..tmp1 and L..func_end0
.vbyte 4, 0 # has no landing pad
.byte 0 # On action: cleanup
L..cst_end0:
.byte 0 # >> Action Record 1 <<
# Cleanup
.byte 0 # No further actions
.align 2
.csect .eh_info_table[RW],2
__ehinfo.0:
.vbyte 4, 0
.align 3
.vbyte 8, GCC_except_table0
.vbyte 8, rust_eh_personality[DS]
# -- End function
.extern .rust_eh_personality[PR]
.extern rust_eh_personality[DS]
.extern ._RINvNvMs_NtCs3Cu2L953qsK_5alloc7raw_vecINtB7_6RawVecppE7reserve21do_reserve_and_handlehNtNtB9_5alloc6GlobalECsc4UU1XxBbkb_7getopts[PR],hidden
.extern _RINvNvMs_NtCs3Cu2L953qsK_5alloc7raw_vecINtB7_6RawVecppE7reserve21do_reserve_and_handlehNtNtB9_5alloc6GlobalECsc4UU1XxBbkb_7getopts[DS],hidden
.extern ._Unwind_Resume[PR]
.extern _Unwind_Resume[DS]
.toc
L..C0:
.tc __ehinfo.0[TC],__ehinfo.0 You can check the action at
which is required by
Here's the LLVM's view of landingpad, https://github.com/llvm/llvm-project/blob/2d32a01b9fe2249b1a7dc57f7da1fadf804fbd8c/llvm/lib/CodeGen/MachineFunction.cpp#L766 |
LGTM. Could you also update the SJLJ code path? |
Also check |
That's quite a lot of duplicated code, this could be moved into |
Is it necessary to assert |
I don't think it is necessary. @bors r+ |
Rollup of 8 pull requests Successful merges: - rust-lang#105795 (Stabilize `abi_efiapi` feature) - rust-lang#106446 ([LSDA] Take ttype_index into account when taking unwind action) - rust-lang#106675 (Mark ZST as FFI-safe if all its fields are PhantomData) - rust-lang#106740 (Adding a hint on iterator type errors) - rust-lang#106741 (Fix reexport of `doc(hidden)` item) - rust-lang#106759 (Revert "Make nested RPITIT inherit the parent opaque's generics.") - rust-lang#106772 (Re-add mw to review rotation) - rust-lang#106778 (Exclude formatting commit from blame) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
If
cs_action != 0
, we should check thettype_index
field in action record. Ifttype_index == 0
, a clean up action is taken; otherwise catch action is taken.This can fix unwind failure on AIX which uses LLVM's libunwind by default. IIUC, rust's LSDA is borrowed from c++ and I'm assuming itanium-cxx-abi https://itanium-cxx-abi.github.io/cxx-abi/exceptions.pdf should be followed, so the fix follows what libcxxabi does. See https://github.com/llvm/llvm-project/blob/ec48682ce9f61d056361c5095f21e930b8365661/libcxxabi/src/cxa_personality.cpp#L152 for use of
ttype_index
.