[v1,3/4] Enable arch-specific CFI directives and DWARF instructions only when required by the target

Message ID 20241211120553.1391850-4-matthieu.longo@arm.com
State New
Headers
Series Provide a target-specific definition to enable/disable section of code in others modules than gas |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_build--master-arm fail Patch failed to apply

Commit Message

Matthieu Longo Dec. 11, 2024, 12:05 p.m. UTC
  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).
---
 bfd/elf-eh-frame.c |  9 ++++++++-
 binutils/dwarf.c   | 21 ++++++++++++++-------
 gas/dw2gencfi.c    | 29 +++++++++++++++++++++++++----
 gas/gen-sframe.c   | 32 +++++++++++++++++++-------------
 include/dwarf2.def | 25 +++++++++++++++++++------
 include/dwarf2.h   |  1 +
 6 files changed, 86 insertions(+), 31 deletions(-)
  

Comments

Jens Remus Dec. 12, 2024, 9:26 a.m. UTC | #1
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
  

Patch

diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index e8244bc0444..8453c3dcf81 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -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;
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 582efafcf88..b5e6d2e50d1 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -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);
diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c
index 5071a161576..22263da808a 100644
--- a/gas/dw2gencfi.c
+++ b/gas/dw2gencfi.c
@@ -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:
       {
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 */
+
 /* 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;
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 538198b3026..1a38d7e0484 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -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.  */
diff --git a/include/dwarf2.h b/include/dwarf2.h
index 1f4dbaf0a1e..123dda26afb 100644
--- a/include/dwarf2.h
+++ b/include/dwarf2.h
@@ -87,6 +87,7 @@ 
   name = value
 #define DW_END_UT };
 
+#include "config.h"
 #include "dwarf2.def"
 
 #undef DW_FIRST_TAG