Skip to content

[runtimes][PAC] Harden unwinding when possible (#138571) #143230

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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 70 additions & 6 deletions compiler-rt/lib/builtins/gcc_personality_v0.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,45 @@ EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *, PCONTEXT,
_Unwind_Personality_Fn);
#endif

#if __has_feature(ptrauth_qualifier)
#include <ptrauth.h>
#if __has_feature(ptrauth_restricted_intptr_qualifier)
#define __ptrauth_gcc_personality_intptr(key, addressDiscriminated, \
Comment on lines 32 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of not checking for __has_include(<ptrauth.h>) separately and instead gluing #include <ptrauth.h> unconditionally to its users, which are usually already guarded with some __has_feature(...) test. I wonder if this pattern can be used in more places affected by this patch.

discriminator) \
__ptrauth_restricted_intptr(key, addressDiscriminated, discriminator)
#else
#define __ptrauth_gcc_personality_intptr(key, addressDiscriminated, \
discriminator) \
__ptrauth(key, addressDiscriminated, discriminator)
#endif
#else
#define __ptrauth_gcc_personality_intptr(...)
#endif

#define __ptrauth_gcc_personality_func_key ptrauth_key_function_pointer

// ptrauth_string_discriminator("__gcc_personality_v0'funcStart") == 0xDFEB
#define __ptrauth_gcc_personality_func_start \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This macro has __ptrauth_gcc_personality_ prefix while some other ones have a shorter __ptrauth_gcc_ prefix - is this intentional? If not and if the longer gcc_personality version was intended, I think it may be worth coming up with a shorter prefix to keep variable definitions single-line. On the other hand, it is still hard to keep most of the definitions single-line even with __ptrauth_gcc_ prefix.

By the way, do we need two underscores in front of our own macro definitions (at least as long as they are completely private)? Are there any code style suggestions for or against this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah the problem here is that I was finding the length of the qualifiers was actively making it hard to read the code.

I need to go through and come up with some more compact but still understandable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just went for consistency over brevity.

__ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1, 0xDFEB)

// ptrauth_string_discriminator("__gcc_personality_v0'start") == 0x52DC
#define __ptrauth_gcc_personality_start \
__ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1, 0x52DC)

// ptrauth_string_discriminator("__gcc_personality_v0'length") == 0xFFF7
#define __ptrauth_gcc_personality_length \
__ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1, 0xFFF7)

// ptrauth_string_discriminator("__gcc_personality_v0'landingPadOffset") == 0x6498
#define __ptrauth_gcc_personality_lpoffset \
__ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1, 0x6498)

// ptrauth_string_discriminator("__gcc_personality_v0'landingPad") == 0xA134
#define __ptrauth_gcc_personality_lpad_disc 0xA134
#define __ptrauth_gcc_personality_lpad \
__ptrauth_gcc_personality_intptr(__ptrauth_gcc_personality_func_key, 1, \
__ptrauth_gcc_personality_lpad_disc)

// Pointer encodings documented at:
// http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html

Expand Down Expand Up @@ -205,7 +244,8 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
return continueUnwind(exceptionObject, context);

uintptr_t pc = (uintptr_t)_Unwind_GetIP(context) - 1;
uintptr_t funcStart = (uintptr_t)_Unwind_GetRegionStart(context);
uintptr_t __ptrauth_gcc_personality_func_start funcStart =
(uintptr_t)_Unwind_GetRegionStart(context);
uintptr_t pcOffset = pc - funcStart;

// Parse LSDA header.
Expand All @@ -224,11 +264,14 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
const uint8_t *callSiteTableEnd = callSiteTableStart + callSiteTableLength;
const uint8_t *p = callSiteTableStart;
while (p < callSiteTableEnd) {
uintptr_t start = readEncodedPointer(&p, callSiteEncoding);
size_t length = readEncodedPointer(&p, callSiteEncoding);
size_t landingPad = readEncodedPointer(&p, callSiteEncoding);
uintptr_t __ptrauth_gcc_personality_start start =
readEncodedPointer(&p, callSiteEncoding);
size_t __ptrauth_gcc_personality_length length =
readEncodedPointer(&p, callSiteEncoding);
size_t __ptrauth_gcc_personality_lpoffset landingPadOffset =
readEncodedPointer(&p, callSiteEncoding);
readULEB128(&p); // action value not used for C code
if (landingPad == 0)
if (landingPadOffset == 0)
continue; // no landing pad for this entry
if ((start <= pcOffset) && (pcOffset < (start + length))) {
// Found landing pad for the PC.
Expand All @@ -238,7 +281,28 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
(uintptr_t)exceptionObject);
_Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
_Unwind_SetIP(context, (funcStart + landingPad));
size_t __ptrauth_gcc_personality_lpad landingPad =
funcStart + landingPadOffset;
#if __has_feature(ptrauth_qualifier)
uintptr_t stackPointer = _Unwind_GetGR(context, -2);
const uintptr_t existingDiscriminator =
ptrauth_blend_discriminator(&landingPad,
__ptrauth_gcc_personality_lpad_disc);
// newIP is authenticated as if it were qualified with a pseudo qualifier
// along the lines of:
// __ptrauth(ptrauth_key_return_address, <stackPointer>, 0)
// where the stack pointer is used in place of the strict storage
// address.
uintptr_t newIP =
(uintptr_t)ptrauth_auth_and_resign(*(void **)&landingPad,
__ptrauth_gcc_personality_func_key,
existingDiscriminator,
ptrauth_key_return_address,
stackPointer);
_Unwind_SetIP(context, newIP);
#else
_Unwind_SetIP(context, landingPad);
#endif
return _URC_INSTALL_CONTEXT;
}
}
Expand Down
46 changes: 46 additions & 0 deletions libcxxabi/include/__cxxabi_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,52 @@
#define _LIBCXXABI_DTOR_FUNC
#endif

#if __has_include(<ptrauth.h>)
# include <ptrauth.h>
#endif
Comment on lines +106 to +108
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it is a supported configuration when ptrauth.h header is not available, but __has_extension(ptrauth_qualifier) is true? Note that the macro definitions guarded with #if __has_extension(ptrauth_qualifier) still refer to identifiers like ptrauth_key_process_dependent_data.

Maybe this could be simplified by assuming that __ptrauth_cxxabi_* are defined to non-empty expressions if and only if __has_extension(ptrauth_qualifier) is true, and in that case ptrauth.h header must exist:

#if __has_extension(ptrauth_qualifier)
#  include <ptrauth.h>
// ptrauth_string_discriminator("__cxa_exception::actionRecord") == 0xFC91
#  define __ptrauth_cxxabi_action_record \
            __ptrauth(ptrauth_key_process_dependent_data, 1, 0xFC91)
// ...
#endif

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is something I'm unsure about - there's a lot of checks for the header scattered everywhere but also plenty of places that rely on the feature existing and blindly including the header.

I'm ok putting the ptrauth.h includes unconditionally inside the feature check on the basis that if the header isn't present the ptrauth enabled paths will fail to build


#if __has_extension(ptrauth_qualifier)

// ptrauth_string_discriminator("__cxa_exception::actionRecord") == 0xFC91
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] I'm not sure whether this is that important, but we can easily make these documentation lines stricter by turning them from human-readable comments into machine-readable static_asserts :) On one hand, the specific constants being used are not important, on the other their derivations may help the developer make sure these constants are reasonably unique (since they are produced by hashing some sensible strings) without re-computing these hashes by custom code.

# define __ptrauth_cxxabi_action_record \
__ptrauth(ptrauth_key_process_dependent_data, 1, 0xFC91)

// ptrauth_string_discriminator("__cxa_exception::languageSpecificData") == 0xE8EE
# define __ptrauth_cxxabi_lsd \
__ptrauth(ptrauth_key_process_dependent_data, 1, 0xE8EE)

// ptrauth_string_discriminator("__cxa_exception::catchTemp") == 0xFA58
# define __ptrauth_cxxabi_catch_temp \
__ptrauth(ptrauth_key_process_dependent_data, 1, 0xFA58)

// ptrauth_string_discriminator("__cxa_exception::adjustedPtr") == 0x99E4
# define __ptrauth_cxxabi_adjusted_ptr \
__ptrauth(ptrauth_key_process_dependent_data, 1, 0x99E4)

// ptrauth_string_discriminator("__cxa_exception::unexpectedHandler") == 0x99A9
# define __ptrauth_cxxabi_unexpected_handler \
__ptrauth(ptrauth_key_function_pointer, 1, 0x99A9)

// ptrauth_string_discriminator("__cxa_exception::terminateHandler") == 0x0886)
# define __ptrauth_cxxabi_terminate_handler \
__ptrauth(ptrauth_key_function_pointer, 1, 0x886)

// ptrauth_string_discriminator("__cxa_exception::exceptionDestructor") == 0xC088
# define __ptrauth_cxxabi_exception_destructor \
__ptrauth(ptrauth_key_function_pointer, 1, 0xC088)

#else

# define __ptrauth_cxxabi_action_record
# define __ptrauth_cxxabi_lsd
# define __ptrauth_cxxabi_catch_temp
# define __ptrauth_cxxabi_adjusted_ptr
# define __ptrauth_cxxabi_unexpected_handler
# define __ptrauth_cxxabi_terminate_handler
# define __ptrauth_cxxabi_exception_destructor

#endif

#if __cplusplus < 201103L
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this was removed accidentally during merging. W/o this, the build is just broken.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by failing to compile we ensure there are no memory safety bugs. :D

# define _LIBCXXABI_NOEXCEPT throw()
#else
Expand Down
33 changes: 19 additions & 14 deletions libcxxabi/src/cxa_exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ struct _LIBCXXABI_HIDDEN __cxa_exception {
// In Wasm, a destructor returns its argument
void *(_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *);
#else
void (_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *);
void(_LIBCXXABI_DTOR_FUNC* __ptrauth_cxxabi_exception_destructor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] Missing space after void: void (_LIBCXXABI_DTOR_FUNC* ...

exceptionDestructor)(void*);
#endif
std::unexpected_handler unexpectedHandler;
std::terminate_handler terminateHandler;
std::unexpected_handler __ptrauth_cxxabi_unexpected_handler unexpectedHandler;
std::terminate_handler __ptrauth_cxxabi_terminate_handler terminateHandler;

__cxa_exception *nextException;

Expand All @@ -61,10 +62,10 @@ struct _LIBCXXABI_HIDDEN __cxa_exception {
int propagationCount;
#else
int handlerSwitchValue;
const unsigned char *actionRecord;
const unsigned char *languageSpecificData;
void *catchTemp;
void *adjustedPtr;
const unsigned char* __ptrauth_cxxabi_action_record actionRecord;
const unsigned char* __ptrauth_cxxabi_lsd languageSpecificData;
void* __ptrauth_cxxabi_catch_temp catchTemp;
void* __ptrauth_cxxabi_adjusted_ptr adjustedPtr;
#endif

#if !defined(__LP64__) && !defined(_WIN64) && !defined(_LIBCXXABI_ARM_EHABI)
Expand All @@ -79,16 +80,19 @@ struct _LIBCXXABI_HIDDEN __cxa_exception {
// http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html
// The layout of this structure MUST match the layout of __cxa_exception, with
// primaryException instead of referenceCount.
// The tags used in the pointer authentication qualifiers also need to match
// those of the corresponding members in __cxa_exception.
struct _LIBCXXABI_HIDDEN __cxa_dependent_exception {
#if defined(__LP64__) || defined(_WIN64) || defined(_LIBCXXABI_ARM_EHABI)
void* reserve; // padding.
void* primaryException;
#endif

std::type_info *exceptionType;
void (_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *);
std::unexpected_handler unexpectedHandler;
std::terminate_handler terminateHandler;
void(_LIBCXXABI_DTOR_FUNC* __ptrauth_cxxabi_exception_destructor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] Missing space after void: void (_LIBCXXABI_DTOR_FUNC* ...

exceptionDestructor)(void*);
std::unexpected_handler __ptrauth_cxxabi_unexpected_handler unexpectedHandler;
std::terminate_handler __ptrauth_cxxabi_terminate_handler terminateHandler;

__cxa_exception *nextException;

Expand All @@ -99,10 +103,11 @@ struct _LIBCXXABI_HIDDEN __cxa_dependent_exception {
int propagationCount;
#else
int handlerSwitchValue;
const unsigned char *actionRecord;
const unsigned char *languageSpecificData;
void * catchTemp;
void *adjustedPtr;

const unsigned char* __ptrauth_cxxabi_action_record actionRecord;
const unsigned char* __ptrauth_cxxabi_lsd languageSpecificData;
void* __ptrauth_cxxabi_catch_temp catchTemp;
void* __ptrauth_cxxabi_adjusted_ptr adjustedPtr;
#endif

#if !defined(__LP64__) && !defined(_WIN64) && !defined(_LIBCXXABI_ARM_EHABI)
Expand Down
103 changes: 95 additions & 8 deletions libcxxabi/src/cxa_personality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,49 @@
#include "cxa_handlers.h"
#include "private_typeinfo.h"
#include "unwind.h"
#include "libunwind.h"

#if __has_include(<ptrauth.h>)
# include <ptrauth.h>
#endif

#if __has_extension(ptrauth_qualifier)
// The actual value of the discriminators listed below is not important.
// The derivation of the constants is only being included for the purpose
// of maintaining a record of how they were originally produced.

// ptrauth_string_discriminator("scan_results::languageSpecificData") == 0xE50D)
#define __ptrauth_scan_results_lsd \
__ptrauth(ptrauth_key_process_dependent_code, 1, 0xE50D)

// ptrauth_string_discriminator("scan_results::actionRecord") == 0x9823
#define __ptrauth_scan_results_action_record \
__ptrauth(ptrauth_key_process_dependent_code, 1, 0x9823)

// scan result is broken up as we have a manual re-sign that requires each component
#define __ptrauth_scan_results_landingpad_key ptrauth_key_process_dependent_code
// ptrauth_string_discriminator("scan_results::landingPad") == 0xD27C
#define __ptrauth_scan_results_landingpad_disc 0xD27C
#define __ptrauth_scan_results_landingpad \
__ptrauth(__ptrauth_scan_results_landingpad_key, 1, __ptrauth_scan_results_landingpad_disc)

#if __has_extension(__ptrauth_restricted_intptr)
#define __ptrauth_scan_results_landingpad_intptr \
__ptrauth_restricted_intptr(__ptrauth_scan_results_landingpad_key, 1, \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this should go under #if __has_extension(ptrauth_restricted_intptr_qualifier) (just like in other places touched by this PR, see libunwind.h for example). As far as I can see, __ptrauth_restricted_intptr is not yet supported by mainline, and using that causes compile errors on my side.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it actually needs the ptrauth/ptrauth_intptr macros to deal with that separate spelling. Will add it to my current refactoring fixes.

__ptrauth_scan_results_landingpad_disc)
#else
#define __ptrauth_scan_results_landingpad_intptr \
__ptrauth(__ptrauth_scan_results_landingpad_key, 1, \
__ptrauth_scan_results_landingpad_disc)
#endif

#else
#define __ptrauth_scan_results_lsd
#define __ptrauth_scan_results_action_record
#define __ptrauth_scan_results_landingpad
#define __ptrauth_scan_results_landingpad_intptr
#endif


// TODO: This is a temporary workaround for libc++abi to recognize that it's being
// built against LLVM's libunwind. LLVM's libunwind started reporting _LIBUNWIND_VERSION
Expand Down Expand Up @@ -527,12 +570,17 @@ get_thrown_object_ptr(_Unwind_Exception* unwind_exception)
namespace
{

typedef const uint8_t* __ptrauth_scan_results_lsd lsd_ptr_t;
typedef const uint8_t* __ptrauth_scan_results_action_record action_ptr_t;
typedef uintptr_t __ptrauth_scan_results_landingpad_intptr landing_pad_t;
typedef void* __ptrauth_scan_results_landingpad landing_pad_ptr_t;

struct scan_results
{
int64_t ttypeIndex; // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup
const uint8_t* actionRecord; // Currently unused. Retained to ease future maintenance.
const uint8_t* languageSpecificData; // Needed only for __cxa_call_unexpected
uintptr_t landingPad; // null -> nothing found, else something found
action_ptr_t actionRecord; // Currently unused. Retained to ease future maintenance.
lsd_ptr_t languageSpecificData; // Needed only for __cxa_call_unexpected
landing_pad_t landingPad; // null -> nothing found, else something found
void* adjustedPtr; // Used in cxa_exception.cpp
_Unwind_Reason_Code reason; // One of _URC_FATAL_PHASE1_ERROR,
// _URC_FATAL_PHASE2_ERROR,
Expand All @@ -541,7 +589,33 @@ struct scan_results
};

} // unnamed namespace
} // extern "C"

namespace {
// The logical model for casting authenticated function pointers makes
// it impossible to directly cast them without breaking the authentication,
// as a result we need this pair of helpers.
template <typename PtrType>
void set_landing_pad_as_ptr(scan_results& results, const PtrType& out) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PtrType seems to always be a ... pointer type :) So, probably, you can just pass by value instead of using const l-value reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kovdan01 ah yeah, unfortunately that's not sound, but for dumb reasons. The reason I've passed by reference is because the intent is for PtrType to be a ptrauth qualified type on arm64e, and we use a reference to ensure that it remains protected.

It might be possible to make this clearer once we have the schema queries upstreamed, because then we could make it explicit that this expects PtrType to be an address discriminated __ptrauth qualified pointer when compiling on arm64e (or whatever other platforms add ptrauth in future)

union {
landing_pad_t* as_landing_pad;
landing_pad_ptr_t* as_pointer;
} u;
u.as_landing_pad = &results.landingPad;
*u.as_pointer = out;
}

static const landing_pad_ptr_t& get_landing_pad_as_ptr(const scan_results& results) {
union {
const landing_pad_t* as_landing_pad;
const landing_pad_ptr_t* as_pointer;
} u;
u.as_landing_pad = &results.landingPad;
return *u.as_pointer;
}
} // unnamed namespace

extern "C" {
static
void
set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,
Expand All @@ -557,7 +631,21 @@ set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,
reinterpret_cast<uintptr_t>(unwind_exception));
_Unwind_SetGR(context, __builtin_eh_return_data_regno(1),
static_cast<uintptr_t>(results.ttypeIndex));
#if __has_feature(ptrauth_qualifier)
auto stackPointer = _Unwind_GetGR(context, UNW_REG_SP);
// We manually re-sign the IP as the __ptrauth qualifiers cannot
// express the required relationship with the destination address
const auto existingDiscriminator = ptrauth_blend_discriminator(
&results.landingPad, __ptrauth_scan_results_landingpad_disc);
unw_word_t newIP /* opaque __ptrauth(ptrauth_key_return_address, stackPointer, 0) */ =
(unw_word_t)ptrauth_auth_and_resign(*(void**)&results.landingPad,
__ptrauth_scan_results_landingpad_key,
existingDiscriminator,
ptrauth_key_return_address, stackPointer);
_Unwind_SetIP(context, newIP);
#else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as in compiler-rt/lib/builtins/gcc_personality_v0.c, do we need an implementation "in between" completely unprotected pointers and full hand-written hardening when only pac-ret is enabled?

_Unwind_SetIP(context, results.landingPad);
#endif
}

/*
Expand Down Expand Up @@ -691,12 +779,12 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
// The call sites are ordered in increasing value of start
uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);
uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
landing_pad_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
uintptr_t actionEntry = readULEB128(&callSitePtr);
if ((start <= ipOffset) && (ipOffset < (start + length)))
#else // __USING_SJLJ_EXCEPTIONS__ || __WASM_EXCEPTIONS__
// ip is 1-based index into this table
uintptr_t landingPad = readULEB128(&callSitePtr);
landing_pad_t landingPad = readULEB128(&callSitePtr);
uintptr_t actionEntry = readULEB128(&callSitePtr);
if (--ip == 0)
#endif // __USING_SJLJ_EXCEPTIONS__ || __WASM_EXCEPTIONS__
Expand Down Expand Up @@ -935,8 +1023,7 @@ __gxx_personality_v0
results.ttypeIndex = exception_header->handlerSwitchValue;
results.actionRecord = exception_header->actionRecord;
results.languageSpecificData = exception_header->languageSpecificData;
results.landingPad =
reinterpret_cast<uintptr_t>(exception_header->catchTemp);
set_landing_pad_as_ptr(results, exception_header->catchTemp);
results.adjustedPtr = exception_header->adjustedPtr;

// Jump to the handler.
Expand Down Expand Up @@ -970,7 +1057,7 @@ __gxx_personality_v0
exc->handlerSwitchValue = static_cast<int>(results.ttypeIndex);
exc->actionRecord = results.actionRecord;
exc->languageSpecificData = results.languageSpecificData;
exc->catchTemp = reinterpret_cast<void*>(results.landingPad);
exc->catchTemp = get_landing_pad_as_ptr(results);
exc->adjustedPtr = results.adjustedPtr;
#ifdef __WASM_EXCEPTIONS__
// Wasm only uses a single phase (_UA_SEARCH_PHASE), so save the
Expand Down
Loading
Loading