On 11.12.2024 13:05, Matthieu Longo wrote:
> This patch is a follow-up on the patch adding a TC_<arch> definition in
> the different modules of binutils interacting with DWARF in one way or
> another. It surrounds the architecture-specific code for DWARF instructions
> and CFI directives with the corresponding TC_<arch> definition to enable
> or disable it according to the selected target in configure (via --target).
...
> diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
> index 0e100ef231c..12c92774a7d 100644
> --- a/gas/gen-sframe.c
> +++ b/gas/gen-sframe.c
> @@ -1265,6 +1265,8 @@ sframe_xlate_do_restore (struct sframe_xlate_ctx *xlate_ctx,
> return SFRAME_XLATE_OK;
> }
>
> +#if TC_AARCH64
> +
> /* Translate DW_CFA_AARCH64_negate_ra_state into SFrame context.
> Return SFRAME_XLATE_OK if success. */
>
> @@ -1295,6 +1297,10 @@ sframe_xlate_do_aarch64_negate_ra_state_with_pc (struct sframe_xlate_ctx *xlate_
> return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
> }
>
> +#endif /* TC_AARCH64 */
> +
> +#if TC_SPARC
> +
> /* Translate DW_CFA_GNU_window_save into SFrame context.
> DW_CFA_GNU_window_save is a DWARF Sparc extension, but is multiplexed with a
> directive of DWARF AArch64 extension: DW_CFA_AARCH64_negate_ra_state.
> @@ -1306,20 +1312,15 @@ sframe_xlate_do_aarch64_negate_ra_state_with_pc (struct sframe_xlate_ctx *xlate_
> Return SFRAME_XLATE_OK if success. */
>
> static int
> -sframe_xlate_do_gnu_window_save (struct sframe_xlate_ctx *xlate_ctx,
> - struct cfi_insn_data *cfi_insn)
> +sframe_xlate_do_gnu_window_save (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
> + struct cfi_insn_data *cfi_insn ATTRIBUTE_UNUSED)
> {
> - unsigned char abi_arch = sframe_get_abi_arch ();
> -
> - /* Translate DW_CFA_AARCH64_negate_ra_state into SFrame context. */
> - if (abi_arch == SFRAME_ABI_AARCH64_ENDIAN_BIG
> - || abi_arch == SFRAME_ABI_AARCH64_ENDIAN_LITTLE)
> - return sframe_xlate_do_aarch64_negate_ra_state (xlate_ctx, cfi_insn);
> -
> as_warn (_("skipping SFrame FDE; .cfi_window_save"));
> return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
> }
>
> +#endif /* TC_SPARC */
> +
Both TC_SPARC blocks can be omitted. The purpose of
sframe_xlate_do_gnu_window_save() was to actually handle the
multiplexed DW_CFA_AARCH64_negate_ra_state on AArch64 and
otherwise skip generation of the SFrame FDE with a warning
message. See my next comment.
> /* Returns the DWARF call frame instruction name or fake CFI name for the
> specified CFI opcode, or NULL if the value is not recognized. */
>
> @@ -1405,14 +1406,19 @@ sframe_do_cfi_insn (struct sframe_xlate_ctx *xlate_ctx,
> case DW_CFA_restore:
> err = sframe_xlate_do_restore (xlate_ctx, cfi_insn);
> break;
> - /* DW_CFA_AARCH64_negate_ra_state is multiplexed with
> - DW_CFA_GNU_window_save. */
> - case DW_CFA_GNU_window_save:
> - err = sframe_xlate_do_gnu_window_save (xlate_ctx, cfi_insn);
> +#if TC_AARCH64
> + case DW_CFA_AARCH64_negate_ra_state:
> + err = sframe_xlate_do_aarch64_negate_ra_state (xlate_ctx, cfi_insn);
> break;
> case DW_CFA_AARCH64_negate_ra_state_with_pc:
> err = sframe_xlate_do_aarch64_negate_ra_state_with_pc (xlate_ctx, cfi_insn);
> break;
> +#endif /* TC_AARCH64 */
> +#if TC_SPARC
> + case DW_CFA_GNU_window_save:
> + err = sframe_xlate_do_gnu_window_save (xlate_ctx, cfi_insn);
> + break;
> +#endif /* TC_SPARC */
Omitting the TC_SPARC block will trigger skipping of the SFrame FDE
with a warning message in the default case for all architectures,
except AArch64, which handles DW_CFA_AARCH64_negate_ra_state above.
> case DW_CFA_register:
> err = sframe_xlate_do_register (xlate_ctx, cfi_insn);
> break;
...
Regards,
Jens
@@ -358,8 +358,13 @@ skip_cfa_op (bfd_byte **iter, bfd_byte *end, unsigned int encoded_ptr_width)
case DW_CFA_restore:
case DW_CFA_remember_state:
case DW_CFA_restore_state:
- case DW_CFA_GNU_window_save:
+#if TC_AARCH64
+ case DW_CFA_AARCH64_negate_ra_state:
case DW_CFA_AARCH64_negate_ra_state_with_pc:
+#endif /* TC_AARCH64 */
+#if TC_SPARC
+ case DW_CFA_GNU_window_save:
+#endif /* TC_SPARC */
/* No arguments. */
return true;
@@ -410,8 +415,10 @@ skip_cfa_op (bfd_byte **iter, bfd_byte *end, unsigned int encoded_ptr_width)
case DW_CFA_advance_loc4:
return skip_bytes (iter, end, 4);
+#if TC_MIPS
case DW_CFA_MIPS_advance_loc8:
return skip_bytes (iter, end, 8);
+#endif /* TC_MIPS */
default:
return false;
@@ -8629,12 +8629,6 @@ init_dwarf_regnames_iamcu (void)
dwarf_regnames_lookup_func = regname_internal_by_table_only;
}
-static const char *const DW_CFA_GNU_window_save_name[] =
-{
- "DW_CFA_GNU_window_save",
- "DW_CFA_AARCH64_negate_ra_state"
-};
-
static const char *const dwarf_regnames_x86_64[] =
{
"rax", "rdx", "rcx", "rbx",
@@ -9868,12 +9862,14 @@ display_debug_frames (struct dwarf_section *section,
case DW_CFA_def_cfa_offset_sf:
SKIP_SLEB (start, block_end);
break;
+#if TC_MIPS
case DW_CFA_MIPS_advance_loc8:
if ((size_t) (block_end - start) < 8)
start = block_end;
else
start += 8;
break;
+#endif /* TC_MIPS */
case DW_CFA_GNU_args_size:
SKIP_ULEB (start, block_end);
break;
@@ -10340,6 +10336,7 @@ display_debug_frames (struct dwarf_section *section,
printf (" DW_CFA_def_cfa_offset_sf: %" PRId64 "\n", ofs);
break;
+#if TC_MIPS
case DW_CFA_MIPS_advance_loc8:
SAFE_BYTE_GET_AND_INC (ofs, start, 8, block_end);
ofs *= fc->code_factor;
@@ -10353,16 +10350,26 @@ display_debug_frames (struct dwarf_section *section,
}
fc->pc_begin += ofs;
break;
+#endif /* TC_MIPS */
+
+#if TC_AARCH64
+ case DW_CFA_AARCH64_negate_ra_state:
+ if (! do_debug_frames_interp)
+ printf (" DW_CFA_AARCH64_negate_ra_state\n");
+ break;
case DW_CFA_AARCH64_negate_ra_state_with_pc:
if (! do_debug_frames_interp)
printf (" DW_CFA_AARCH64_negate_ra_state_with_pc\n");
break;
+#endif /* TC_AARCH64 */
+#if TC_SPARC
case DW_CFA_GNU_window_save:
if (! do_debug_frames_interp)
- printf (" %s\n", DW_CFA_GNU_window_save_name[is_aarch64]);
+ printf (" DW_CFA_GNU_window_save\n");
break;
+#endif /* TC_SPARC */
case DW_CFA_GNU_args_size:
READ_ULEB (ofs, start, block_end);
@@ -716,9 +716,14 @@ const pseudo_typeS cfi_pseudo_table[] =
{ "cfi_same_value", dot_cfi, DW_CFA_same_value },
{ "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
{ "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
+#if TC_AARCH64
{ "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
{ "cfi_negate_ra_state", dot_cfi, DW_CFA_AARCH64_negate_ra_state },
{ "cfi_negate_ra_state_with_pc", dot_cfi, DW_CFA_AARCH64_negate_ra_state_with_pc },
+#endif /* TC_AARCH64 */
+#if TC_SPARC
+ { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
+#endif /* TC_SPARC */
{ "cfi_escape", dot_cfi_escape, 0 },
{ "cfi_signal_frame", dot_cfi, CFI_signal_frame },
{ "cfi_personality", dot_cfi_personality, 0 },
@@ -915,13 +920,21 @@ dot_cfi (int arg)
cfi_add_CFA_restore_state ();
break;
- case DW_CFA_GNU_window_save:
- cfi_add_CFA_insn (DW_CFA_GNU_window_save);
+#if TC_AARCH64
+ case DW_CFA_AARCH64_negate_ra_state:
+ cfi_add_CFA_insn (DW_CFA_AARCH64_negate_ra_state);
break;
case DW_CFA_AARCH64_negate_ra_state_with_pc:
cfi_add_CFA_insn (DW_CFA_AARCH64_negate_ra_state_with_pc);
break;
+#endif /* TC_AARCH64 */
+
+#if TC_SPARC
+ case DW_CFA_GNU_window_save:
+ cfi_add_CFA_insn (DW_CFA_GNU_window_save);
+ break;
+#endif /* TC_SPARC */
case CFI_signal_frame:
frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1;
@@ -1759,13 +1772,21 @@ output_cfi_insn (struct cfi_insn_data *insn)
out_one (insn->insn);
break;
- case DW_CFA_GNU_window_save:
- out_one (DW_CFA_GNU_window_save);
+#if TC_AARCH64
+ case DW_CFA_AARCH64_negate_ra_state:
+ out_one (DW_CFA_AARCH64_negate_ra_state);
break;
case DW_CFA_AARCH64_negate_ra_state_with_pc:
out_one (DW_CFA_AARCH64_negate_ra_state_with_pc);
break;
+#endif /* TC_AARCH64 */
+
+#if TC_SPARC
+ case DW_CFA_GNU_window_save:
+ out_one (DW_CFA_GNU_window_save);
+ break;
+#endif /* TC_SPARC */
case CFI_escape:
{
@@ -1265,6 +1265,8 @@ sframe_xlate_do_restore (struct sframe_xlate_ctx *xlate_ctx,
return SFRAME_XLATE_OK;
}
+#if TC_AARCH64
+
/* Translate DW_CFA_AARCH64_negate_ra_state into SFrame context.
Return SFRAME_XLATE_OK if success. */
@@ -1295,6 +1297,10 @@ sframe_xlate_do_aarch64_negate_ra_state_with_pc (struct sframe_xlate_ctx *xlate_
return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
}
+#endif /* TC_AARCH64 */
+
+#if TC_SPARC
+
/* Translate DW_CFA_GNU_window_save into SFrame context.
DW_CFA_GNU_window_save is a DWARF Sparc extension, but is multiplexed with a
directive of DWARF AArch64 extension: DW_CFA_AARCH64_negate_ra_state.
@@ -1306,20 +1312,15 @@ sframe_xlate_do_aarch64_negate_ra_state_with_pc (struct sframe_xlate_ctx *xlate_
Return SFRAME_XLATE_OK if success. */
static int
-sframe_xlate_do_gnu_window_save (struct sframe_xlate_ctx *xlate_ctx,
- struct cfi_insn_data *cfi_insn)
+sframe_xlate_do_gnu_window_save (struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED,
+ struct cfi_insn_data *cfi_insn ATTRIBUTE_UNUSED)
{
- unsigned char abi_arch = sframe_get_abi_arch ();
-
- /* Translate DW_CFA_AARCH64_negate_ra_state into SFrame context. */
- if (abi_arch == SFRAME_ABI_AARCH64_ENDIAN_BIG
- || abi_arch == SFRAME_ABI_AARCH64_ENDIAN_LITTLE)
- return sframe_xlate_do_aarch64_negate_ra_state (xlate_ctx, cfi_insn);
-
as_warn (_("skipping SFrame FDE; .cfi_window_save"));
return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */
}
+#endif /* TC_SPARC */
+
/* Returns the DWARF call frame instruction name or fake CFI name for the
specified CFI opcode, or NULL if the value is not recognized. */
@@ -1405,14 +1406,19 @@ sframe_do_cfi_insn (struct sframe_xlate_ctx *xlate_ctx,
case DW_CFA_restore:
err = sframe_xlate_do_restore (xlate_ctx, cfi_insn);
break;
- /* DW_CFA_AARCH64_negate_ra_state is multiplexed with
- DW_CFA_GNU_window_save. */
- case DW_CFA_GNU_window_save:
- err = sframe_xlate_do_gnu_window_save (xlate_ctx, cfi_insn);
+#if TC_AARCH64
+ case DW_CFA_AARCH64_negate_ra_state:
+ err = sframe_xlate_do_aarch64_negate_ra_state (xlate_ctx, cfi_insn);
break;
case DW_CFA_AARCH64_negate_ra_state_with_pc:
err = sframe_xlate_do_aarch64_negate_ra_state_with_pc (xlate_ctx, cfi_insn);
break;
+#endif /* TC_AARCH64 */
+#if TC_SPARC
+ case DW_CFA_GNU_window_save:
+ err = sframe_xlate_do_gnu_window_save (xlate_ctx, cfi_insn);
+ break;
+#endif /* TC_SPARC */
case DW_CFA_register:
err = sframe_xlate_do_register (xlate_ctx, cfi_insn);
break;
@@ -780,20 +780,33 @@ DW_CFA (DW_CFA_val_offset, 0x14)
DW_CFA (DW_CFA_val_offset_sf, 0x15)
DW_CFA (DW_CFA_val_expression, 0x16)
+/* Users extensions. */
DW_CFA (DW_CFA_lo_user, 0x1c)
-DW_CFA (DW_CFA_hi_user, 0x3f)
-/* SGI/MIPS specific. */
+/* SGI/MIPS specific extensions. */
+#if TC_MIPS
DW_CFA (DW_CFA_MIPS_advance_loc8, 0x1d)
-/* AArch64 extensions. */
+#endif /* TC_MIPS */
+
+/* AArch64 specific extensions. */
+#if TC_AARCH64
DW_CFA (DW_CFA_AARCH64_negate_ra_state_with_pc, 0x2c)
-/* GNU extensions.
- NOTE: DW_CFA_GNU_window_save is multiplexed on Sparc and AArch64. */
+DW_CFA (DW_CFA_AARCH64_negate_ra_state, 0x2d)
+/* NOTE: DW_CFA_GNU_window_save is multiplexed on Sparc and AArch64. */
+DW_CFA_DUP (DW_CFA_GNU_window_save, 0x2d)
+#endif /* TC_AARCH64 */
+
+/* Sparc specific extensions. */
+#if TC_SPARC
DW_CFA (DW_CFA_GNU_window_save, 0x2d)
-DW_CFA_DUP (DW_CFA_AARCH64_negate_ra_state, 0x2d)
+#endif /* TC_SPARC */
+
+/* GNU extensions. */
DW_CFA (DW_CFA_GNU_args_size, 0x2e)
DW_CFA (DW_CFA_GNU_negative_offset_extended, 0x2f)
+DW_CFA (DW_CFA_hi_user, 0x3f)
+
DW_END_CFA
/* Index attributes in the Abbreviations Table. */
@@ -87,6 +87,7 @@
name = value
#define DW_END_UT };
+#include "config.h"
#include "dwarf2.def"
#undef DW_FIRST_TAG