summaryrefslogtreecommitdiffstats
path: root/unwind.h
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-08-16 22:14:39 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-08-16 22:14:39 -0700
commit2399bf36c10ec9f7011008a76f96847be7255c9d (patch)
treec6b08adb149a32adf43e5f8062ca358f046bfd4d /unwind.h
parente31b1509ebb518548780aa2544459337854af48e (diff)
downloadtxr-2399bf36c10ec9f7011008a76f96847be7255c9d.tar.gz
txr-2399bf36c10ec9f7011008a76f96847be7255c9d.tar.bz2
txr-2399bf36c10ec9f7011008a76f96847be7255c9d.zip
Get continuations working on aarch64.
* unwind.c (UW_CONT_FRAME_BEFORE, UW_CONT_FRAME_AFTER): New preprocessor symbols. (revive_cont): The "frame slack" zero-filled padding logic is replaced by capturing an actual part of the real stack before the uw_stack unwind frame. On aarch64, there is content there we must actually capture. Experiment shows that exactly 128 bytes is enough, and that corresponds to the frame_slack value. (capture_cont): Capture UW_CONT_FRAME_BEFORE bytes before the uw_stack unwind frame location. Also, the "capture_extra" is replaced by UW_CONT_FRAME_AFTER constant, to harmonize. * unwind.h (UW_FRAME_ALIGN): New preprocessor symbol. (union uw_frame): On aarch64, we ask the compiler, via a GCC-specific attribute syntax, to align the address of frame objects to a 16 byte boundary. This solves a crash in the continuation code. Continuation capture is keyed to unwind frame addresses. When a captured continuation is revived onto the stack, the delta between its original address and the revive address must be a multiple of 16. The reason is that this preserves the stack and frame pointer alignment. Certain instructions on the aarch64, require the stack pointer to be 16 byte aligned. There are other ways we could achieve this, but the easiest is to align the original frames to 16 bytes.
Diffstat (limited to 'unwind.h')
-rw-r--r--unwind.h8
1 files changed, 7 insertions, 1 deletions
diff --git a/unwind.h b/unwind.h
index c887a423..a173e39d 100644
--- a/unwind.h
+++ b/unwind.h
@@ -98,6 +98,12 @@ struct uw_debug {
val chr;
};
+#if __aarch64__
+#define UW_FRAME_ALIGN __attribute__ ((aligned (16)))
+#else
+#define UW_FRAME_ALIGN
+#endif
+
union uw_frame {
struct uw_common uw;
struct uw_block bl;
@@ -107,7 +113,7 @@ union uw_frame {
struct uw_cont_copy cp;
struct uw_guard gu;
struct uw_debug db;
-};
+} UW_FRAME_ALIGN;
void uw_push_block(uw_frame_t *, val tag);
void uw_push_env(uw_frame_t *);