[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