[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