Skip to content

Commit 1bdbe3a

Browse files
authored
Rollup merge of #161368 - hsanzg:uw-ex-align, r=bjorn3,tgross35
Double-word align `_Unwind_Exception` The [Itanium C++ ABI spec](https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html) states that the `_Unwind_Exception` type must be double-word aligned (see Section 1.2). The missing alignment option does not seem to cause problems when a) using Rust's panic mechanism (because the exception object passed to `_Unwind_RaiseException` is [heap-allocated](https://github.com/rust-lang/rust/blob/f7d782a3be46d6bb4b9792fe69a61db389ba1769/library/panic_unwind/src/gcc.rs#L62) and thus double-word aligned by accident---although this is not guaranteed) or b) when linking against libgcc's unwinder. Most people don't need to unwind stacks themselves, so case (a) usually applies; and case (b) is the default for the `amd64-unknown-linux-gnu` target. Thus, misalignments seem unlikely to cause trouble in practice. However, I recently copied over some of the type definitions in `library/unwind` into a personal project, built `rustc` with `rust.llvm-libunwind = "system"`, and installed LLVM's `libunwind-24-dev`. Calling `_Unwind_RaiseException` with a thread-local `_Unwind_Exception` object led to a segfault due to the too-small default alignment. So `libunwind` seems to depend on the double-word alignment. N.B.: Both `libunwind` and `libgcc` have comments [1, 2] saying that the "double-word" alignment is a bit ambiguous when interpreted in a target-agnostic sense, and they both add `__attribute__((__aligned__))` to `_Unwind_Exception`, with no specific alignment value (the default is the maximum alignment of any integer type). Rust doesn't have such a "default" alignment, so I interpreted "double-word" in a target-dependent manner via `cfg_attr` + the `target_pointer_width` feature. \[1]: https://github.com/llvm/llvm-project/blob/196786fa5fe4225539678fc7904a383eca05374e/libunwind/include/unwind_itanium.h#L41 \[2]: https://github.com/gcc-mirror/gcc/blob/50a2eb56b9a350ecced4db4942e92d463dab8d8f/libgcc/unwind-generic.h#L106
2 parents b7dba0e + ac623ff commit 1bdbe3a

1 file changed

Lines changed: 6 additions & 0 deletions

File tree

library/unwind/src/types.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ pub const unwinder_private_data_size: usize =
4343
};
4444

4545
#[repr(C)]
46+
// The Itanium C++ ABI requires this type to have "double-word" alignment,
47+
// which libunwind and libgcc interpret as the maximum alignment of any
48+
// scalar type on the current target.
49+
#[cfg_attr(target_pointer_width = "16", repr(align(4)))]
50+
#[cfg_attr(target_pointer_width = "32", repr(align(8)))]
51+
#[cfg_attr(target_pointer_width = "64", repr(align(16)))]
4652
pub struct _Unwind_Exception {
4753
pub exception_class: _Unwind_Exception_Class,
4854
pub exception_cleanup: _Unwind_Exception_Cleanup_Fn,

0 commit comments

Comments
 (0)