[PATCH v2] arm: Handle undefweak with ST_BRANCH_UNKNOWN
Richard Earnshaw (lists)
Richard.Earnshaw@arm.com
Wed Sep 11 15:26:18 GMT 2024
On 11/09/2024 09:40, Christophe Lyon wrote:
> A previous patch made ld fail early on Thumb-only where branch_type is
> ST_BRANCH_UNKNOWN.
>
> However, this fails erroneously when the target is undefweak: in that
> case the branch should be replaced by a branch to the next instruction
> (or nop.w on thumb2). This patch accepts this case and restores the
> previous behaviour in such cases.
>
> This was reported by failures in the GCC testsuite, where we fail to
> link executables because __deregister_frame_info is undefweak:
>
> (__deregister_frame_info): Unknown destination type (ARM/Thumb) in ...crtbegin.o
> crtbegin.o: in function `__do_global_dtors_aux':
> crtstuff.c:(.text+0x52): dangerous relocation: unsupported relocation
> ---
> bfd/elf32-arm.c | 7 ++++++-
> ld/testsuite/ld-arm/arm-elf.exp | 1 +
> .../ld-arm/farcall-missing-type-main-undefweak.s | 10 ++++++++++
> ld/testsuite/ld-arm/farcall-missing-type-undefweak.d | 11 +++++++++++
> 4 files changed, 28 insertions(+), 1 deletion(-)
> create mode 100644 ld/testsuite/ld-arm/farcall-missing-type-main-undefweak.s
> create mode 100644 ld/testsuite/ld-arm/farcall-missing-type-undefweak.d
>
> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
> index 7441ee2cc38..17df8b30eb6 100644
> --- a/bfd/elf32-arm.c
> +++ b/bfd/elf32-arm.c
> @@ -10512,7 +10512,12 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
> if (using_thumb_only (globals)
> && (r_type == R_ARM_THM_CALL
> || r_type == R_ARM_THM_JUMP24)
> - && branch_type == ST_BRANCH_UNKNOWN)
> + && branch_type == ST_BRANCH_UNKNOWN
> + /* Exception to the rule above: a branch to an undefined weak
> + symbol is turned into a jump to the next instruction unless a
> + PLT entry will be created (see below). */
> + && !(h && h->root.type == bfd_link_hash_undefweak
> + && plt_offset == (bfd_vma) -1))
> {
> if (sym_sec != NULL
> && sym_sec->owner != NULL)
> diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
> index 5f380e383d0..7fa4520fb15 100644
> --- a/ld/testsuite/ld-arm/arm-elf.exp
> +++ b/ld/testsuite/ld-arm/arm-elf.exp
> @@ -1208,6 +1208,7 @@ run_dump_test "attr-merge-wchar-42-nowarn"
> run_dump_test "attr-merge-wchar-44-nowarn"
> run_dump_test "farcall-section"
> run_dump_test "farcall-missing-type"
> +run_dump_test "farcall-missing-type-undefweak"
> run_dump_test "attr-merge-unknown-1"
> run_dump_test "attr-merge-unknown-2"
> run_dump_test "attr-merge-unknown-2r"
> diff --git a/ld/testsuite/ld-arm/farcall-missing-type-main-undefweak.s b/ld/testsuite/ld-arm/farcall-missing-type-main-undefweak.s
> new file mode 100644
> index 00000000000..cf72722144b
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/farcall-missing-type-main-undefweak.s
> @@ -0,0 +1,10 @@
> + .thumb
> + .cpu cortex-m33
> + .syntax unified
> + .global __start
> + .weak bad
> + .type __start, function
> +__start:
> + push {r4, lr}
> + bl bad
> + pop {r4, pc}
> diff --git a/ld/testsuite/ld-arm/farcall-missing-type-undefweak.d b/ld/testsuite/ld-arm/farcall-missing-type-undefweak.d
> new file mode 100644
> index 00000000000..b6e123fe1ab
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/farcall-missing-type-undefweak.d
> @@ -0,0 +1,11 @@
> +#source: farcall-missing-type-main-undefweak.s
> +#as:
> +#ld:-T farcall-missing-type.ld
> +#objdump: -dr
> +#...
> +Disassembly of section .text:
> +
> +.* <__start>:
> + +[0-9a-f]+: .... .... push {r4, lr}
> + +[0-9a-f]+: .... .... nop.w
> + +[0-9a-f]+: .... .... pop {r4, pc}
OK
R.
More information about the Binutils
mailing list