[PATCH] ld: Don't define section symbols for excluded sections
Alan Modra
amodra@gmail.com
Thu Jul 30 10:34:14 GMT 2026
On Thu, Jul 30, 2026 at 03:17:45PM +0800, H.J. Lu wrote:
> When the SEC_EXCLUDE bit is set on a section, the contents of the section
> are excluded by the linker for non-relocatable output. Define __start,
> __stop, .startof. and .sizeof. symbols for relocatable link or if the
> SEC_EXCLUDE bit on the section is cleared.
Looks good to me. You might like to mention the ELF SHF_EXCLUDE flag
in the description too, since it was that flag being set that
triggered the segfault in bug_4.o from the pr. bug_4.o didn't even
need --gc-sections to fail.
> PR ld/34448
> * ldlang.c (lang_init_start_stop): Call lang_define_start_stop
> for relocatable link or if the SEC_EXCLUDE bit on the section
> is cleared.
>
> Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
> ---
> ld/ldlang.c | 39 +++++++++++++++++++++------------------
> 1 file changed, 21 insertions(+), 18 deletions(-)
>
> diff --git a/ld/ldlang.c b/ld/ldlang.c
> index 354fa635ba8..7dc331c04cd 100644
> --- a/ld/ldlang.c
> +++ b/ld/ldlang.c
> @@ -7283,28 +7283,31 @@ lang_init_start_stop (void)
>
> for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
> for (s = abfd->sections; s != NULL; s = s->next)
> - {
> - const char *ps;
> - const char *secname = s->name;
> + if (bfd_link_relocatable (&link_info)
> + || (s->flags & SEC_EXCLUDE) == 0)
> + {
> + const char *ps;
> + const char *secname = s->name;
>
> - for (ps = secname; *ps != '\0'; ps++)
> - if (!ISALNUM ((unsigned char) *ps) && *ps != '_')
> - break;
> - if (*ps == '\0')
> - {
> - char *symbol = (char *) xmalloc (10 + strlen (secname));
> + for (ps = secname; *ps != '\0'; ps++)
> + if (!ISALNUM ((unsigned char) *ps) && *ps != '_')
> + break;
> + if (*ps == '\0')
> + {
> + char *symbol = (char *) xmalloc (10 + strlen (secname));
>
> - symbol[0] = leading_char;
> - sprintf (symbol + (leading_char != 0), "__start_%s", secname);
> - lang_define_start_stop (symbol, s);
> + symbol[0] = leading_char;
> + sprintf (symbol + (leading_char != 0), "__start_%s",
> + secname);
> + lang_define_start_stop (symbol, s);
>
> - symbol[1] = leading_char;
> - memcpy (symbol + 1 + (leading_char != 0), "__stop", 6);
> - lang_define_start_stop (symbol + 1, s);
> + symbol[1] = leading_char;
> + memcpy (symbol + 1 + (leading_char != 0), "__stop", 6);
> + lang_define_start_stop (symbol + 1, s);
>
> - free (symbol);
> - }
> - }
> + free (symbol);
> + }
> + }
> }
>
> /* Iterate over start_stop_syms. */
> --
> 2.55.0
>
--
Alan Modra
More information about the Binutils
mailing list