unwind: export and use symbolic names in assembler
While here, expand some documentation
diff --git a/sdk/include/unwind-assembly.h b/sdk/include/unwind-assembly.h
new file mode 100644
index 0000000..377d97f
--- /dev/null
+++ b/sdk/include/unwind-assembly.h
@@ -0,0 +1,12 @@
+// Copyright CHERIoT Contributors.
+// SPDX-License-Identifier: MIT
+
+#pragma once
+
+#include <assembly-helpers.h>
+#include <setjmp-assembly.h>
+
+#define INVOCATION_LOCAL_UNWIND_LIST_OFFSET 8
+
+EXPORT_ASSEMBLY_OFFSET(CleanupList, next, 0)
+EXPORT_ASSEMBLY_OFFSET(CleanupList, env, 8)
diff --git a/sdk/include/unwind.h b/sdk/include/unwind.h
index 3f55c81..ce6a25a 100644
--- a/sdk/include/unwind.h
+++ b/sdk/include/unwind.h
@@ -14,6 +14,8 @@
struct __jmp_buf env;
};
+#include <unwind-assembly.h>
+
/**
* Head of the cleanup list.
*
@@ -25,7 +27,8 @@
{
void *csp = __builtin_cheri_stack_get();
ptraddr_t top = __builtin_cheri_top_get(csp);
- csp = __builtin_cheri_address_set(csp, top - 8);
+ csp = __builtin_cheri_address_set(
+ csp, top - INVOCATION_LOCAL_UNWIND_LIST_OFFSET);
return (struct CleanupList **)csp;
}
diff --git a/sdk/lib/unwind_error_handler/unwind.S b/sdk/lib/unwind_error_handler/unwind.S
index 6e56a98..6c74c06 100644
--- a/sdk/lib/unwind_error_handler/unwind.S
+++ b/sdk/lib/unwind_error_handler/unwind.S
@@ -1,16 +1,29 @@
+#include <unwind-assembly.h>
+
+/**
+ * A direct re-implementation of unwind.h's cleanup_unwind() as a stackless
+ * error handler.
+ *
+ * If there is no registered CleanupList structure (equivalently, there's no
+ * CHERIOT_DURING block active at the time of the fault), then this requests
+ * unwnding out of the compartment. Otherwise, we will longjmp() out to the
+ * indicated handler (that is, the CHERIOT_HANDLER block associated with the
+ * current CHERIOT_DURING block), having reset the compartment error handler
+ * invocation counter to zero.
+ */
.section .compartment_error_handler_stackless,"aw",@progbits
.globl compartment_error_handler_stackless
.p2align 2
.type compartment_error_handler_stackless,@function
compartment_error_handler_stackless:
-// Get the head of the error list.
+// Get the head of the error list (see cleanup_list_head)
cgettop t0, csp
csetaddr csp, csp, t0
- clc cs0, -8(csp)
+ clc cs0, -INVOCATION_LOCAL_UNWIND_LIST_OFFSET(csp)
beqz s0, .Lforce_unwind
-// Pop the top error from the list. */
- clc ct0, 0(cs0)
- csc ct0, -8(csp)
+// Pop the top error from the list
+ clc ct0, CleanupList_offset_next(cs0)
+ csc ct0, -INVOCATION_LOCAL_UNWIND_LIST_OFFSET(csp)
// Mark this error handler as having finished. We may still trap again
// and reenter this, but now that we've popped the top element from the
// stack we will run some different cleanup code next time. */
@@ -19,11 +32,12 @@
clc ct2, %cheriot_compartment_lo_i(.Llookup_reset)(ct2)
cjalr ct2
// longjmp to the error handler.
- clc cs1, 16(cs0)
- clc csp, 24(cs0)
- clc cra, 32(cs0)
- clc cs0, 8(cs0)
+ clc cs1, (CleanupList_offset_env + __jmp_buf_offset___cs1)(cs0)
+ clc csp, (CleanupList_offset_env + __jmp_buf_offset___csp)(cs0)
+ clc cra, (CleanupList_offset_env + __jmp_buf_offset___cra)(cs0)
+ clc cs0, (CleanupList_offset_env + __jmp_buf_offset___cs0)(cs0)
cjr cra
+
.Lforce_unwind:
li a0, 1
cret