[PATCH v1 1/5] ld: fix segfault caused by untagged stub sections

Jan Beulich jbeulich@suse.com
Fri Sep 26 13:13:51 GMT 2025


On 18.09.2025 17:06, Matthieu Longo wrote:
> In the case of non-contiguous memory regions, a far-call stub section
> must be assigned to the memory of the section it was originally emitted
> for. If the stub section does not fit, the section is marked as dropped,
> and removed later. To emit a useful message to the user, however, a stub
> section needs to be discernible from sections originating from input
> objects.
> 
> Previously [1], this distinction was made using the SEC_LINKER_CREATED
> flag only the AArch32 backend handler <arch>_add_stub_section. Other
> backends that didn't set this flag on their stub sections skipped required
> checks in ld/ldlang.c:size_input_section(). On AArch64, this caused the
> linker to proceed into code paths that assumed output sections were set,
> instead of reporting fatal errors, and ultimately led to a segmentation
> fault.
> 
> However, the SEC_LINKER_CREATED flag does not solely indicate that a
> section was created by the linker. Its original meaning also meant that
> the section should not be handled by the generic relocation code. Reusing
> this flag to identify stub sections, while it appeared to fix the issue,
> introduced unintended side effects. On PowerPC, for instance, it skipped
> relocations present in the stubs and interpreted them as absolute
> addresses.
> 
> This patch proposes a new approach: a new boolean attribute 'veneer' added
> to 'asection'. The attribute is set on AArch64 and PowerPC immediately
> after the creation of the stub section. Others architectures are left
> unchanged, as they do not appear to support non-contiguous memory regions
> (no tests were found to verify the fix). Additionally, the diagnostic
> message was improved when a stub cannot be placed in the same memory
> region as its referencing code.
> 
> [1]: abf874a, Add support for non-contiguous memory regions.
> ---
>  bfd/bfd-in2.h                                      |  6 ++++++
>  bfd/libbfd.h                                       |  4 ++--
>  bfd/section.c                                      | 10 ++++++++--
>  ld/emultempl/aarch64elf.em                         |  2 ++
>  ld/emultempl/armelf.em                             |  5 +++--
>  ld/emultempl/ppc64elf.em                           |  2 ++
>  ld/ldlang.c                                        | 13 +++++++------
>  ld/testsuite/ld-arm/non-contiguous-arm4.d          |  2 +-
>  ld/testsuite/ld-powerpc/non-contiguous-powerpc64.d |  2 +-
>  9 files changed, 32 insertions(+), 14 deletions(-)

I'm okay with the approach, yet there is a largely mechanical issue:

> --- a/bfd/bfd-in2.h
> +++ b/bfd/bfd-in2.h
> @@ -834,6 +834,12 @@ typedef struct bfd_section
>      const char *linked_to_symbol_name;
>    } map_head, map_tail;
>  
> +  /* Indicate that the section contains branch veneers.  This is used when
> +     support for non-contiguous memory regions is enabled.  The veneers have
> +     to be allocated to the same memory region as the code they are refered
> +     by, i.e. they cannot be moved to a subsequent memory region.  */
> +  bool veneer;

Why would you put a bool between two pointer-sized fields, thus introducing
yet more padding, when in fact existing padding could be used. There's a set
of bitfields further up from here, and you could simply add a single-bit
field there, for example. Generic code changes are okay with that change,
but arch-specific ones will need arch maintainer approval.

Jan


More information about the Binutils mailing list