[v1,4/7] Add aarch64-specific SEH commands
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_binutils_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_binutils_check--master-arm |
success
|
Test passed
|
Commit Message
Implementation for aarch64 contains SEH commands that are not present for
x64 architecture, such as .seh_startepilogue/.seh_endepilogue,
.seh_save_reg*, .seh_save_freg*, and others.
gas/ChangeLog:
* config/obj-coff-seh.c (obj_coff_seh_startepilogue): New.
(obj_coff_seh_endepilogue): New.
(obj_coff_seh_endfunclet): New.
(obj_coff_seh_save_reg): New.
---
gas/config/obj-coff-seh.c | 134 ++++++++++++++++++++++++++++++++++++++
1 file changed, 134 insertions(+)
Comments
On 09.04.2025 16:08, Evgeny Karpov wrote:
> Implementation for aarch64 contains SEH commands that are not present for
> x64 architecture, such as .seh_startepilogue/.seh_endepilogue,
> .seh_save_reg*, .seh_save_freg*, and others.
>
> gas/ChangeLog:
>
> * config/obj-coff-seh.c (obj_coff_seh_startepilogue): New.
> (obj_coff_seh_endepilogue): New.
> (obj_coff_seh_endfunclet): New.
> (obj_coff_seh_save_reg): New.
> ---
> gas/config/obj-coff-seh.c | 134 ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 134 insertions(+)
This adds a number of static functions with no caller. Aiui that'll break
the build, until whatever subsequent patch introduces uses of these
functions.
Jan
Wednesday, April 9, 2025
Jan Beulich <jbeulich@suse.com> wrote:
> This adds a number of static functions with no caller. Aiui that'll break
> the build, until whatever subsequent patch introduces uses of these
> functions.
Yes, it makes sense to guard these functions with COFFAARCH64
and merge this patch with
https://sourceware.org/pipermail/binutils/2025-April/140502.html
to avoid unused function warnings.
Regards,
Evgeny
@@ -667,6 +667,84 @@ obj_coff_seh_endprologue (int what ATTRIBUTE_UNUSED)
}
}
+static void
+obj_coff_seh_startepilogue (int what ATTRIBUTE_UNUSED)
+{
+ symbolS *epilogue_start_addr;
+ expressionS exp;
+
+ if (!verify_context (".seh_startepilogue")
+ || !seh_validate_seg (".seh_startepilogue"))
+ return;
+ demand_empty_rest_of_line ();
+
+ if (seh_get_target_kind () != seh_kind_arm64)
+ return;
+
+ epilogue_start_addr = symbol_temp_new_now ();
+ exp.X_op = O_subtract;
+ exp.X_add_symbol = epilogue_start_addr;
+ exp.X_op_symbol = seh_ctx_cur->start_addr;
+ exp.X_add_number = 0;
+
+ if (!resolve_expression (&exp) || exp.X_op != O_constant
+ || exp.X_add_number < 0)
+ as_bad (_(".seh_startepilog offset expression for %s "
+ "does not evaluate to a non-negative constant"),
+ S_GET_NAME (epilogue_start_addr));
+
+ seh_arm64_epilogue_scope *epilogue_scope;
+ epilogue_scope = seh_ctx_cur->arm64_ctx.epilogue_scopes
+ + seh_ctx_cur->arm64_ctx.epilogue_scopes_count;
+ epilogue_scope->epilogue_start_offset = exp.X_add_number / 4;
+ epilogue_scope->reserved = 0;
+ epilogue_scope->epilogue_start_index
+ = seh_ctx_cur->arm64_ctx.unwind_codes_byte_count;
+ seh_ctx_cur->arm64_ctx.epilogue_scopes_count++;
+}
+
+static void
+obj_coff_seh_endepilogue (int what ATTRIBUTE_UNUSED)
+{
+ if (!verify_context (".seh_endepilogue")
+ || !seh_validate_seg (".seh_endepilogue"))
+ return;
+
+ demand_empty_rest_of_line ();
+
+ expressionS exp;
+ symbolS* epilogue_end_addr = symbol_temp_new_now ();
+ exp.X_op = O_subtract;
+ exp.X_add_symbol = epilogue_end_addr;
+ exp.X_op_symbol = seh_ctx_cur->start_addr;
+ exp.X_add_number = 0;
+
+ if (!resolve_expression (&exp) || exp.X_op != O_constant
+ || exp.X_add_number < 0)
+ as_bad (_(".seh_endepilogue offset expression for %s "
+ "does not evaluate to a non-negative constant"),
+ S_GET_NAME (epilogue_end_addr));
+
+ seh_arm64_epilogue_scope *epilogue_scope;
+ epilogue_scope = seh_ctx_cur->arm64_ctx.epilogue_scopes
+ + seh_ctx_cur->arm64_ctx.epilogue_scopes_count - 1;
+
+ epilogue_scope->epilogue_end_offset = exp.X_add_number;
+
+ /* End code. */
+ seh_arm64_add_unwind_element (end, 0, 0);
+}
+
+static void
+obj_coff_seh_endfunclet (int what ATTRIBUTE_UNUSED)
+{
+ if (!verify_context (".seh_endfunclet")
+ || !seh_validate_seg (".seh_endfunclet"))
+ return;
+
+ demand_empty_rest_of_line ();
+}
+
/* End-of-file hook. */
void
@@ -850,6 +928,62 @@ obj_coff_seh_save (int what)
seh_x64_make_prologue_element (code, reg, off);
}
+static void
+obj_coff_seh_save_reg (int type)
+{
+ if (type < 0 || type > unwind_last_type)
+ {
+ as_bad (_("invalid pseudo operation."));
+ return;
+ }
+
+ const struct unwind_code_pack_info *unwind_code_pack_info;
+ unwind_code_pack_info = unwind_code_pack_infos + type;
+
+ if (!unwind_code_pack_info->directive
+ || !verify_context_and_target (unwind_code_pack_info->directive,
+ seh_kind_arm64)
+ || !seh_validate_seg (unwind_code_pack_info->directive))
+ return;
+
+ SKIP_WHITESPACE ();
+
+ char *symbol_name = NULL;
+ int reg = -1;
+
+ if (unwind_code_pack_info->reg_bits)
+ {
+ char name_end = get_symbol_name (&symbol_name);
+ reg = atoi (symbol_name + 1);
+ (void) restore_line_pointer (name_end);
+
+ if (!skip_whitespace_and_comma (1))
+ return;
+
+ if (reg < 0)
+ {
+ as_bad (_("register is negative"));
+ return;
+ }
+ }
+
+ offsetT off = -1;
+ if (unwind_code_pack_info->offset_bits)
+ {
+ off = get_absolute_expression ();
+
+ if (off < 0)
+ {
+ as_bad (_("offset is negative"));
+ return;
+ }
+ }
+
+ demand_empty_rest_of_line ();
+
+ seh_arm64_add_unwind_element (type, off, reg);
+}
+
/* Add a stack-allocation token to current context. */
static void