[PATCH] gas: add --reloc-use-section-sym={all, temporary, none} option for ELF

mengqinggang mengqinggang@loongson.cn
Mon Feb 9 06:45:07 GMT 2026


Maybe need to change temporary to local-label in commit message?


在 2026/2/9 05:03, maskray@sourceware.org 写道:
> From: Fangrui Song <maskray@sourceware.org>
>
> When generating relocations for non-ifunc local symbols that satisfies
> several conditions, GAS converts them to reference the section symbol
> (STT_SECTION) instead, folding the original symbol's offset into the
> addend.  This allows the original local symbol to be omitted from
> .symtab, but the STT_SECTION symbol itself must be present, so the
> conversion saves .symtab entries only when a section has more than one
> local symbol referenced by relocations.
>
> Add --reloc-use-section-sym to control this conversion:
>
> - all (default): convert all eligible local symbols
> - temporary: only convert compiler-generated locals (.L prefix)
> - none: never convert; keep all symbols as-is in relocations
>
> This is useful for debugging and for tools that benefit from preserve
> symbol names.
>
> PR gas/33885
> ---
>   gas/NEWS                                      |  4 ++++
>   gas/as.c                                      | 20 +++++++++++++++-
>   gas/as.h                                      | 10 ++++++++
>   gas/doc/as.texi                               | 11 +++++++++
>   .../gas/i386/reloc-use-section-sym-all.d      | 23 +++++++++++++++++++
>   .../i386/reloc-use-section-sym-local-label.d  | 23 +++++++++++++++++++
>   .../gas/i386/reloc-use-section-sym-none.d     | 23 +++++++++++++++++++
>   .../gas/i386/reloc-use-section-sym.s          | 14 +++++++++++
>   gas/testsuite/gas/i386/x86-64.exp             |  4 ++++
>   gas/write.c                                   | 12 +++++++++-
>   10 files changed, 142 insertions(+), 2 deletions(-)
>   create mode 100644 gas/testsuite/gas/i386/reloc-use-section-sym-all.d
>   create mode 100644 gas/testsuite/gas/i386/reloc-use-section-sym-local-label.d
>   create mode 100644 gas/testsuite/gas/i386/reloc-use-section-sym-none.d
>   create mode 100644 gas/testsuite/gas/i386/reloc-use-section-sym.s
>
> diff --git a/gas/NEWS b/gas/NEWS
> index e384d1135c0..1d07f909b8f 100644
> --- a/gas/NEWS
> +++ b/gas/NEWS
> @@ -1,5 +1,9 @@
>   -*- text -*-
>   
> +* New command line option --reloc-use-section-sym=[all|local-label|none]
> +  controls whether relocations referencing local binding symbols are adjusted
> +  to use section symbols.
> +
>   Changes in 2.46:
>   
>   * Add support for AMD Zen6 processor.
> diff --git a/gas/as.c b/gas/as.c
> index f08c7c71d73..e8c29c13f0f 100644
> --- a/gas/as.c
> +++ b/gas/as.c
> @@ -326,6 +326,10 @@ Options:\n\
>   	   DEFAULT_SFRAME ? "yes" : "no");
>     fprintf (stream, _("\
>     --gsframe-<N>           generate SFrame version <N> information. 3 == <N>\n"));
> +  fprintf (stream, _("\
> +  --reloc-use-section-sym=[all|local-label|none]\n\
> +                          adjust eligible relocations to use section symbols\n\
> +                          (default: all)\n"));
>   # if defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN)
>     fprintf (stream, _("\
>     --scfi=experimental     Synthesize DWARF CFI for hand-written asm\n\
> @@ -523,7 +527,8 @@ parse_args (int * pargc, char *** pargv)
>         OPTION_SFRAME_3,
>         OPTION_SCFI,
>         OPTION_INFO,
> -      OPTION_NOINFO
> +      OPTION_NOINFO,
> +      OPTION_RELOC_USE_SECTION_SYM
>       /* When you add options here, check that they do
>          not collide with OPTION_MD_BASE.  See as.h.  */
>       };
> @@ -556,6 +561,7 @@ parse_args (int * pargc, char *** pargv)
>       ,{"generate-missing-build-notes", required_argument, NULL, OPTION_ELF_BUILD_NOTES}
>       ,{"gsframe", optional_argument, NULL, OPTION_SFRAME}
>       ,{"gsframe-3", no_argument, NULL, OPTION_SFRAME_3}
> +    ,{"reloc-use-section-sym", required_argument, NULL, OPTION_RELOC_USE_SECTION_SYM}
>   # if defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN)
>       ,{"scfi", required_argument, NULL, OPTION_SCFI}
>   # endif
> @@ -1043,6 +1049,18 @@ This program has absolutely no warranty.\n"));
>   	  flag_sectname_subst = 1;
>   	  break;
>   
> +	case OPTION_RELOC_USE_SECTION_SYM:
> +	  if (strcasecmp (optarg, "all") == 0)
> +	    flag_reloc_use_section_sym = reloc_use_section_sym_all;
> +	  else if (strcasecmp (optarg, "local-label") == 0)
> +	    flag_reloc_use_section_sym = reloc_use_section_sym_local_label;
> +	  else if (strcasecmp (optarg, "none") == 0)
> +	    flag_reloc_use_section_sym = reloc_use_section_sym_none;
> +	  else
> +	    as_fatal (_("Invalid --reloc-use-section-sym= option: `%s'"),
> +		      optarg);
> +	  break;
> +
>   	case OPTION_ELF_BUILD_NOTES:
>   	  if (strcasecmp (optarg, "no") == 0)
>   	    flag_generate_build_notes = false;
> diff --git a/gas/as.h b/gas/as.h
> index 1c96a69ea09..24a8e521469 100644
> --- a/gas/as.h
> +++ b/gas/as.h
> @@ -413,6 +413,16 @@ enum multibyte_input_handling
>   };
>   COMMON enum multibyte_input_handling multibyte_handling;
>   
> +/* Controls whether relocations referencing local symbols are converted
> +   to use section symbols.  */
> +enum reloc_use_section_sym_type
> +{
> +  reloc_use_section_sym_all = 0,
> +  reloc_use_section_sym_local_label,
> +  reloc_use_section_sym_none
> +};
> +COMMON enum reloc_use_section_sym_type flag_reloc_use_section_sym;
> +
>   /* TRUE if we should produce a listing.  */
>   extern int listing;
>   
> diff --git a/gas/doc/as.texi b/gas/doc/as.texi
> index 6114a178a0d..f2a8953504b 100644
> --- a/gas/doc/as.texi
> +++ b/gas/doc/as.texi
> @@ -257,6 +257,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
>    [@b{--multibyte-handling=[allow|warn|warn-sym-only]}]
>    [@b{--no-pad-sections}]
>    [@b{-o} @var{objfile}] [@b{-R}]
> + [@b{--reloc-use-section-sym=[all|local-label|none]}]
>    [@b{--scfi=experimental}]
>    [@b{--sectname-subst}]
>    [@b{--size-check=[error|warning]}]
> @@ -956,6 +957,16 @@ Ignored.  Supported for compatibility with tools that pass the same option to
>   both the assembler and the linker.
>   
>   @ifset ELF
> +@item --reloc-use-section-sym=all
> +@itemx --reloc-use-section-sym=local-label
> +@itemx --reloc-use-section-sym=none
> +Control whether relocations referencing local binding symbols are adjusted to
> +use section symbols instead.  With @code{all} (the default), relocations
> +against all eligible local binding symbols are converted.  With
> +@code{local-label}, only relocations against local labels (symbols matching the
> +@code{.L} prefix) are converted.  With @code{none}, no conversions are
> +performed and all relocations retain their original symbols.
> +
>   @item --scfi=experimental
>   This option controls whether the assembler should synthesize CFI for
>   hand-written input.  If the input already contains some synthesizable CFI
> diff --git a/gas/testsuite/gas/i386/reloc-use-section-sym-all.d b/gas/testsuite/gas/i386/reloc-use-section-sym-all.d
> new file mode 100644
> index 00000000000..4ff6bd86aea
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/reloc-use-section-sym-all.d
> @@ -0,0 +1,23 @@
> +#source: reloc-use-section-sym.s
> +#as: --reloc-use-section-sym=all
> +#objdump: -rsj .data -j .text1
> +#name: reloc-use-section-sym=all
> +
> +.*:     file format .*
> +
> +RELOCATION RECORDS FOR \[\.data\]:
> +OFFSET +TYPE +VALUE
> +0+0 R_X86_64_64 +\.text\+0x0+11
> +0+8 R_X86_64_64 +\.text\+0x0+12
> +
> +
> +RELOCATION RECORDS FOR \[\.text1\]:
> +OFFSET +TYPE +VALUE
> +0+1 R_X86_64_PC32 +\.text-0x0+3
> +0+6 R_X86_64_PC32 +\.text-0x0+2
> +
> +
> +Contents of section \.data:
> + 0000 00000000 00000000 00000000 00000000  \.+
> +Contents of section \.text1:
> + 0000 e8000000 00e80000 0000 +.*
> diff --git a/gas/testsuite/gas/i386/reloc-use-section-sym-local-label.d b/gas/testsuite/gas/i386/reloc-use-section-sym-local-label.d
> new file mode 100644
> index 00000000000..2c56894fc63
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/reloc-use-section-sym-local-label.d
> @@ -0,0 +1,23 @@
> +#source: reloc-use-section-sym.s
> +#as: --reloc-use-section-sym=local-label
> +#objdump: -rsj .data -j .text1
> +#name: reloc-use-section-sym=local-label
> +
> +.*:     file format .*
> +
> +RELOCATION RECORDS FOR \[\.data\]:
> +OFFSET +TYPE +VALUE
> +0+0 R_X86_64_64 +named_local\+0x0+10
> +0+8 R_X86_64_64 +\.text\+0x0+12
> +
> +
> +RELOCATION RECORDS FOR \[\.text1\]:
> +OFFSET +TYPE +VALUE
> +0+1 R_X86_64_PC32 +named_local-0x0+4
> +0+6 R_X86_64_PC32 +\.text-0x0+2
> +
> +
> +Contents of section \.data:
> + 0000 00000000 00000000 00000000 00000000  \.+
> +Contents of section \.text1:
> + 0000 e8000000 00e80000 0000 +.*
> diff --git a/gas/testsuite/gas/i386/reloc-use-section-sym-none.d b/gas/testsuite/gas/i386/reloc-use-section-sym-none.d
> new file mode 100644
> index 00000000000..1a3e290ef7b
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/reloc-use-section-sym-none.d
> @@ -0,0 +1,23 @@
> +#source: reloc-use-section-sym.s
> +#as: --reloc-use-section-sym=none
> +#objdump: -rsj .data -j .text1
> +#name: reloc-use-section-sym=none
> +
> +.*:     file format .*
> +
> +RELOCATION RECORDS FOR \[\.data\]:
> +OFFSET +TYPE +VALUE
> +0+0 R_X86_64_64 +named_local\+0x0+10
> +0+8 R_X86_64_64 +\.Ltemp\+0x0+10
> +
> +
> +RELOCATION RECORDS FOR \[\.text1\]:
> +OFFSET +TYPE +VALUE
> +0+1 R_X86_64_PC32 +named_local-0x0+4
> +0+6 R_X86_64_PC32 +\.Ltemp-0x0+4
> +
> +
> +Contents of section \.data:
> + 0000 00000000 00000000 00000000 00000000  \.+
> +Contents of section \.text1:
> + 0000 e8000000 00e80000 0000 +.*
> diff --git a/gas/testsuite/gas/i386/reloc-use-section-sym.s b/gas/testsuite/gas/i386/reloc-use-section-sym.s
> new file mode 100644
> index 00000000000..7663ef71ce8
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/reloc-use-section-sym.s
> @@ -0,0 +1,14 @@
> +.text
> +  nop
> +named_local:
> +  nop
> +.Ltemp:
> +  nop
> +
> +.section .text1,"ax"
> +  call named_local
> +  call .Ltemp
> +
> +.data
> +.quad named_local + 16
> +.quad .Ltemp + 16
> diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86-64.exp
> index 8ddf05481a5..1a3e16ef6e9 100644
> --- a/gas/testsuite/gas/i386/x86-64.exp
> +++ b/gas/testsuite/gas/i386/x86-64.exp
> @@ -775,6 +775,10 @@ if [is_elf_format] then {
>   	run_dump_test "x86-64-align-branch-3"
>       }
>       run_dump_test ehinterp
> +
> +    run_dump_test "reloc-use-section-sym-all"
> +    run_dump_test "reloc-use-section-sym-local-label"
> +    run_dump_test "reloc-use-section-sym-none"
>   }
>   run_dump_test pr27198
>   run_dump_test pr29483
> diff --git a/gas/write.c b/gas/write.c
> index 3494871270a..81dcae765f7 100644
> --- a/gas/write.c
> +++ b/gas/write.c
> @@ -804,6 +804,10 @@ adjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED,
>   
>     dump_section_relocs (abfd, sec, stderr);
>   
> +  /* Disable all conversion for --reloc-use-section-sym=none.  */
> +  if (flag_reloc_use_section_sym == reloc_use_section_sym_none)
> +    return;
> +
>     for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
>       if (fixp->fx_done)
>         /* Ignore it.  */
> @@ -909,6 +913,12 @@ adjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED,
>   	if ((symsec->flags & SEC_THREAD_LOCAL) != 0)
>   	  continue;
>   
> +	/* If --reloc-use-section-sym=local-label, don't adjust a reloc against
> +	   a local label.  */
> +        if (flag_reloc_use_section_sym == reloc_use_section_sym_local_label
> +	    && !bfd_is_local_label (stdoutput, symbol_get_bfdsym (sym)))
> +	  continue;
> +
>   	val = S_GET_VALUE (sym);
>   
>   #if defined(TC_AARCH64) && defined(OBJ_COFF)
> @@ -2043,7 +2053,7 @@ maybe_generate_build_notes (void)
>         else
>   	desc_reloc = BFD_RELOC_64;
>       }
> -
> +
>     /* We have to create a note for *each* code section.
>        Linker garbage collection might discard some.  */
>     total_size = 0;



More information about the Binutils mailing list