aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel King <dmking@adacore.com>2023-08-23 14:13:55 +0100
committerMarc Poulhiès <poulhies@adacore.com>2023-09-26 13:43:17 +0200
commit198e643b35df4743e3177fc3a77b50325ae44717 (patch)
treeb4ee5592659761e4ed51b83bf9f4842089030bf7
parent0787c56c48750156783bd5d3280579e9c68a8aa5 (diff)
downloadgcc-198e643b35df4743e3177fc3a77b50325ae44717.zip
gcc-198e643b35df4743e3177fc3a77b50325ae44717.tar.gz
gcc-198e643b35df4743e3177fc3a77b50325ae44717.tar.bz2
ada: Update personality function for CHERI purecap
This makes two changes to the GNAT personality function to reflect differences for pure capability CHERI/Morello. The first is to use __builtin_code_address_from_pointer to drop the LSB from Morello code pointers when searching through call-site tables (without this we would never find the right landing pad when unwinding). The second change is to reflect the change in the exception table format for pure-capability Morello where the landing pad is a capability indirected by an offset in the call-site table. gcc/ada/ * raise-gcc.c (get_ip_from_context): Adapt for CHERI purecap (get_call_site_action_for): Adapt for CHERI purecap
-rw-r--r--gcc/ada/raise-gcc.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/gcc/ada/raise-gcc.c b/gcc/ada/raise-gcc.c
index 56ddfc5..bdf1c26 100644
--- a/gcc/ada/raise-gcc.c
+++ b/gcc/ada/raise-gcc.c
@@ -50,10 +50,12 @@
#ifdef __cplusplus
# include <cstdarg>
+# include <cstddef>
# include <cstdlib>
#else
# include <stdarg.h>
# include <stdbool.h>
+# include <stddef.h>
# include <stdlib.h>
#endif
@@ -592,6 +594,11 @@ get_ip_from_context (_Unwind_Context *uw_context)
#else
_Unwind_Ptr ip = _Unwind_GetIP (uw_context);
#endif
+
+#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__CHERI__)
+ ip = __builtin_code_address_from_pointer ((void *)ip);
+#endif
+
/* Subtract 1 if necessary because GetIPInfo yields a call return address
in this case, while we are interested in information for the call point.
This does not always yield the exact call instruction address but always
@@ -850,7 +857,27 @@ get_call_site_action_for (_Unwind_Ptr ip,
/* Note that all call-site encodings are "absolute" displacements. */
p = read_encoded_value (0, region->call_site_encoding, p, &cs_start);
p = read_encoded_value (0, region->call_site_encoding, p, &cs_len);
+#ifdef __CHERI_PURE_CAPABILITY__
+ // Single uleb128 value as the capability marker.
+ _Unwind_Ptr marker = 0;
+ p = read_encoded_value (0, DW_EH_PE_uleb128, p, &marker);
+ if (marker == 0xd)
+ {
+ /* 8-byte offset to the (indirected) capability. */
+ p = read_encoded_value (0, DW_EH_PE_pcrel | DW_EH_PE_udata8, p,
+ &cs_lp);
+ }
+ else if (marker)
+ {
+ /* Unsupported landing pad marker value. */
+ abort ();
+ }
+ else
+ cs_lp = 0; // No landing pad.
+#else
p = read_encoded_value (0, region->call_site_encoding, p, &cs_lp);
+#endif
+
p = read_uleb128 (p, &cs_action);
db (DB_CSITE,
@@ -859,18 +886,24 @@ get_call_site_action_for (_Unwind_Ptr ip,
(char *)region->lp_base + cs_lp, (void *)cs_lp);
/* The table is sorted, so if we've passed the IP, stop. */
- if (ip < region->base + cs_start)
+ if (ip < region->base + (size_t)cs_start)
break;
/* If we have a match, fill the ACTION fields accordingly. */
- else if (ip < region->base + cs_start + cs_len)
+ else if (ip < region->base + (size_t)cs_start + (size_t)cs_len)
{
/* Let the caller know there may be an action to take, but let it
determine the kind. */
action->kind = unknown;
if (cs_lp)
- action->landing_pad = region->lp_base + cs_lp;
+ {
+#ifdef __CHERI_PURE_CAPABILITY__
+ action->landing_pad = *(_Unwind_Ptr *)cs_lp;
+#else
+ action->landing_pad = region->lp_base + cs_lp;
+#endif
+ }
else
action->landing_pad = 0;