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