@@ -39,6 +39,7 @@ extern "C" {
3939#define CHERI_INIT_GLOBALS_VERSION 5
4040#define CHERI_INIT_GLOBALS_NUM_ARGS 7
4141#define CHERI_INIT_GLOBALS_SUPPORTS_CONSTANT_FLAG 1
42+ #define CHERI_INIT_GLOBALS_SUPPORTS_INDIRECT_FLAG 1
4243
4344struct capreloc {
4445 __SIZE_TYPE__ capability_location ;
@@ -64,6 +65,8 @@ static const __SIZE_TYPE__ constant_pointer_permissions_mask =
6465static const __SIZE_TYPE__ global_pointer_permissions_mask =
6566 ~(__SIZE_TYPE__ )(__CHERI_CAP_PERMISSION_PERMIT_SEAL__ |
6667 __CHERI_CAP_PERMISSION_PERMIT_EXECUTE__ );
68+ static const __SIZE_TYPE__ indirect_reloc_flag = (__SIZE_TYPE__ )1
69+ << (__SIZE_WIDTH__ - 3 );
6770
6871__attribute__((weak )) extern struct capreloc __start___cap_relocs [];
6972__attribute__((weak )) extern struct capreloc __stop___cap_relocs [];
@@ -171,6 +174,18 @@ cheri_init_globals_impl(const struct capreloc *start_relocs,
171174 data_cap , reloc -> capability_location + base_addr );
172175 const void * __capability base_cap ;
173176 bool can_set_bounds = true;
177+ if (reloc -> permissions == (function_reloc_flag | indirect_reloc_flag )) {
178+ /*
179+ * IRELATIVE-like caprelocs require deferred processing, with a
180+ * target-specific set of parameters. Trap if the caller doesn't
181+ * support that, as we can't do anything here, otherwise skip.
182+ */
183+ #ifdef CHERI_INIT_GLOBALS_ALLOW_IFUNCS
184+ continue ;
185+ #else
186+ __builtin_trap ();
187+ #endif
188+ }
174189 if (reloc -> permissions == function_reloc_flag ) {
175190 base_cap = code_cap ; /* code pointer */
176191 /* Do not set tight bounds for functions (unless we are in the plt ABI) */
0 commit comments