switcher: use two different (un)sealing caps

This shrinks the switcher section by 22 bytes in total and removes 10
instructions, 6 of which were in the swticher "core" (cross-call and
exception paths).
diff --git a/sdk/core/loader/boot.cc b/sdk/core/loader/boot.cc
index d9c6b9e..9aabbb0 100644
--- a/sdk/core/loader/boot.cc
+++ b/sdk/core/loader/boot.cc
@@ -460,7 +460,7 @@
 	 * The sealing key for the switcher, used to seal all jump targets in the
 	 * import tables.
 	 */
-	Capability<void> switcherKey;
+	Capability<void> exportSealingKey;
 
 	/**
 	 * The sealing key for sealing trusted stacks.
@@ -568,7 +568,7 @@
 			                 "Functions exported from compartments must have "
 			                 "an explicit interrupt posture");
 			return build(compartment.exportTable, entry.address)
-			  .seal(switcherKey);
+			  .seal(exportSealingKey);
 		};
 
 		// If the low bit is 1, then this is either an MMIO region or direct
@@ -1252,15 +1252,21 @@
 	  };
 
 	// Set up the sealing keys for the privileged components.
-	switcherKey =
-	  setSealingKey(imgHdr.switcher, Sentry, SealedTrustedStacks - Sentry + 1);
-	// We need only the rights to seal things with the switcher's data sealing
-	// types, so drop all others and store those two types separately.
-	trustedStackKey           = switcherKey;
-	trustedStackKey.address() = SealedTrustedStacks;
-	trustedStackKey.bounds()  = 1;
-	switcherKey.address()     = SealedImportTableEntries;
-	switcherKey.bounds()      = 1;
+	exportSealingKey = CHERI::Capability{
+	  build<void,
+	        Root::Type::Seal,
+	        PermissionSet{Permission::Global, Permission::Seal}>(
+	    SealedImportTableEntries, 1)};
+
+	// We and the switcher both seal (and the switcher unseals) trusted stacks
+	trustedStackKey = setSealingKey(imgHdr.switcher, SealedTrustedStacks, 1, 0);
+	// The switcher unseals import entries built with exportSealingKey above
+	setSealingKey(imgHdr.switcher,
+	              SealedImportTableEntries,
+	              1,
+	              sizeof(void *),
+	              PermissionSet{Permission::Global, Permission::Unseal});
+
 	setSealingKey(imgHdr.allocator(), Allocator);
 	setSealingKey(imgHdr.token_library(),
 	              Allocator,
diff --git a/sdk/core/switcher/entry.S b/sdk/core/switcher/entry.S
index e015141..b139892 100644
--- a/sdk/core/switcher/entry.S
+++ b/sdk/core/switcher/entry.S
@@ -97,6 +97,10 @@
 	.globl compartment_switcher_sealing_key
 	.p2align 3
 compartment_switcher_sealing_key:
+.Lsealing_key_trusted_stacks:
+	.long 0
+	.long 0
+.Lunsealing_key_import_tables:
 	.long 0
 	.long 0
 # Global for the scheduler's PCC.  Stored in the switcher's code section.
@@ -446,11 +450,8 @@
 	 */
 
 	// Fetch the sealing key, using gp as a scratch scalar
-	LoadCapPCC         cs0, compartment_switcher_sealing_key
+	LoadCapPCC         cs0, .Lunsealing_key_import_tables
 	// Atlas update: s0: switcher sealing key
-	li                 gp, SEAL_TYPE_SealedImportTableEntries
-	csetaddr           cs0, cs0, gp
-	// Atlas update: gp: dead (again)
 	/*
 	 * The caller's handle to the callee (the sealed capability to the export
 	 * table entry) is in t1, which has been kept live all this time.  Unseal
@@ -952,10 +953,8 @@
 	 * TrustedStack *exception_entry(TrustedStack *sealedTStack,
 	 *     size_t mcause, size_t mepc, size_t mtval)
 	 */
-	LoadCapPCC         ca5, compartment_switcher_sealing_key
-	li                 gp, SEAL_TYPE_SealedTrustedStacks
-	csetaddr           ca5, ca5, gp
-	cseal              ca0, csp, ca5 // sealed trusted stack
+	LoadCapPCC         ca0, .Lsealing_key_trusted_stacks
+	cseal              ca0, csp, ca0 // sealed trusted stack
 	mv                 a1, t1 // mcause
 	cgetaddr           a2, ct0 // mepcc address
 	csrr               a3, mtval
@@ -1009,9 +1008,7 @@
 	 */
 
 	// Switch onto the new thread's trusted stack, using gp as a scratch scalar
-	LoadCapPCC         csp, compartment_switcher_sealing_key
-	li                 gp, SEAL_TYPE_SealedTrustedStacks
-	csetaddr           csp, csp, gp
+	LoadCapPCC         csp, .Lsealing_key_trusted_stacks
 	cunseal            csp, ca0, csp
 	// Atlas update: sp: unsealed target thread trusted stack pointer
 
@@ -1845,9 +1842,7 @@
 __Z25switcher_interrupt_threadPv:
 	// Load the unsealing key into a register that we will clobber two
 	// instructions later.
-	LoadCapPCC         ca1, compartment_switcher_sealing_key
-	li                 a2, SEAL_TYPE_SealedTrustedStacks
-	csetaddr           ca1, ca1, a2
+	LoadCapPCC         ca1, .Lsealing_key_trusted_stacks
 	/*
 	 * The target capability is in ca0.  Unseal, check tag and load the entry
 	 * point offset.
@@ -1907,9 +1902,7 @@
 	.p2align 2
 	.type __Z23switcher_current_threadv,@function
 __Z23switcher_current_threadv:
-	LoadCapPCC         ca0, compartment_switcher_sealing_key
-	li                 a1, SEAL_TYPE_SealedTrustedStacks
-	csetaddr           ca0, ca0, a1
+	LoadCapPCC         ca0, .Lsealing_key_trusted_stacks
 	cspecialr          ca1, mtdc
 	cseal              ca0, ca1, ca0
 	li                 a1, 0
diff --git a/sdk/firmware.ldscript.in b/sdk/firmware.ldscript.in
index 36997dd..0730217 100644
--- a/sdk/firmware.ldscript.in
+++ b/sdk/firmware.ldscript.in
@@ -164,7 +164,7 @@
 		SHORT(.compartment_switcher_end - .compartment_switcher_start);
 		# Cross-compartment call return path
 		SHORT(switcher_after_compartment_call - .compartment_switcher_start);
-		# Compartment switcher sealing key
+		# Compartment switcher sealing keys
 		SHORT(compartment_switcher_sealing_key - .compartment_switcher_start);
 		# Switcher's copy of the scheduler's PCC.
 		SHORT(switcher_scheduler_entry_pcc - .compartment_switcher_start);