All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yann E. MORIN <yann.morin.1998@free.fr>
To: buildroot@busybox.net
Subject: [Buildroot] [PATCH] package/binutils: fix XTENSA_NDIFF handling for PR ld/25861
Date: Fri, 1 May 2020 22:17:06 +0200	[thread overview]
Message-ID: <20200501201706.GG3687@scaer> (raw)
In-Reply-To: <20200430050822.32017-1-jcmvbkbc@gmail.com>

Max, All,

On 2020-04-29 22:08 -0700, Max Filippov spake thusly:
> Fix for xtensa PR ld/25861 introduced a regression in handling negative
> symbol differences resulting in linker performing incorrect relaxation
> or failing to link. Fix XTENSA_NDIFF relocation handling.
> 
> Backported from:
> https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=d548f47df4d2e3d117d504a4c9977982c78a0556
> 
> Fixes: f0291ef4aba0 ("package/binutils: fix xtensa PR ld/25861")
> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
> ---
>  ...TENSA_NDIFF-handling-for-PR-ld-25861.patch | 128 ++++++++++++++++++
>  ...TENSA_NDIFF-handling-for-PR-ld-25861.patch | 128 ++++++++++++++++++
>  ...TENSA_NDIFF-handling-for-PR-ld-25861.patch | 128 ++++++++++++++++++
>  3 files changed, 384 insertions(+)
>  create mode 100644 package/binutils/2.31.1/0020-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch
>  create mode 100644 package/binutils/2.32/0009-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch
>  create mode 100644 package/binutils/2.33.1/0006-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch
> 
> diff --git a/package/binutils/2.31.1/0020-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch b/package/binutils/2.31.1/0020-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch
> new file mode 100644
> index 000000000000..ebb08fd7dffe
> --- /dev/null
> +++ b/package/binutils/2.31.1/0020-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch
> @@ -0,0 +1,128 @@
> +From 735321812435ae278d3766a3371f55937dc776d6 Mon Sep 17 00:00:00 2001
> +From: Max Filippov <jcmvbkbc@gmail.com>
> +Date: Sat, 25 Apr 2020 00:40:25 -0700
> +Subject: [PATCH] xtensa: fix XTENSA_NDIFF handling for PR ld/25861
> +
> +Fields marked with XTENSA_NDIFF relocations are not negated, they only
> +have sign bits removed. Don't negate their values when relaxation is
> +performed. Don't add sign bits when the value is zero. Report overflow
> +when the result has negative sign but all significant bits are zero.
> +
> +2020-04-29  Max Filippov  <jcmvbkbc@gmail.com>
> +bfd/
> +	* elf32-xtensa.c (relax_section): Don't negate diff_value for
> +	XTENSA_NDIFF relocations. Don't add sign bits whe diff_value
> +	equals 0. Report overflow when the result has negative sign but
> +	all significant bits are zero.
> +
> +Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
> +---
> +Backported from: d548f47df4d2e3d117d504a4c9977982c78a0556

I thnk the "Backported from" info is important, and so should belong to
the commit log, so I moved in just before the --- line, in all three
patches.

Applied to master, thanks.

Regards,
Yann E. MORIN.

> + bfd/elf32-xtensa.c                   | 26 +++++++++++++++-----------
> + 1 file changed, 15 insertions(+), 11 deletions(-)
> +
> +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
> +index fded42d52a9a..4327b027911f 100644
> +--- a/bfd/elf32-xtensa.c
> ++++ b/bfd/elf32-xtensa.c
> +@@ -9670,37 +9670,44 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
> + 		  switch (r_type)
> + 		    {
> + 		    case R_XTENSA_DIFF8:
> ++		      diff_mask = 0x7f;
> + 		      diff_value =
> + 			bfd_get_signed_8 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF16:
> ++		      diff_mask = 0x7fff;
> + 		      diff_value =
> + 			bfd_get_signed_16 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF32:
> ++		      diff_mask = 0x7fffffff;
> + 		      diff_value =
> + 			bfd_get_signed_32 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF8:
> + 		    case R_XTENSA_NDIFF8:
> ++		      diff_mask = 0xff;
> + 		      diff_value =
> + 			bfd_get_8 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF16:
> + 		    case R_XTENSA_NDIFF16:
> ++		      diff_mask = 0xffff;
> + 		      diff_value =
> + 			bfd_get_16 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF32:
> + 		    case R_XTENSA_NDIFF32:
> ++		      diff_mask = 0xffffffff;
> + 		      diff_value =
> + 			bfd_get_32 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    }
> + 
> + 		  if (r_type >= R_XTENSA_NDIFF8
> +-		      && r_type <= R_XTENSA_NDIFF32)
> +-		    diff_value = -diff_value;
> ++		      && r_type <= R_XTENSA_NDIFF32
> ++		      && diff_value)
> ++		    diff_value |= ~diff_mask;
> + 
> + 		  new_end_offset = offset_with_removed_text_map
> + 		    (&target_relax_info->action_list,
> +@@ -9710,43 +9717,40 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
> + 		  switch (r_type)
> + 		    {
> + 		    case R_XTENSA_DIFF8:
> +-		      diff_mask = 0x7f;
> + 		      bfd_put_signed_8 (abfd, diff_value,
> + 				 &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF16:
> +-		      diff_mask = 0x7fff;
> + 		      bfd_put_signed_16 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF32:
> +-		      diff_mask = 0x7fffffff;
> + 		      bfd_put_signed_32 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF8:
> + 		    case R_XTENSA_NDIFF8:
> +-		      diff_mask = 0xff;
> + 		      bfd_put_8 (abfd, diff_value,
> + 				 &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF16:
> + 		    case R_XTENSA_NDIFF16:
> +-		      diff_mask = 0xffff;
> + 		      bfd_put_16 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF32:
> + 		    case R_XTENSA_NDIFF32:
> +-		      diff_mask = 0xffffffff;
> + 		      bfd_put_32 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    }
> + 
> +-		  /* Check for overflow. Sign bits must be all zeroes or all ones */
> +-		  if ((diff_value & ~diff_mask) != 0 &&
> +-		      (diff_value & ~diff_mask) != (-1 & ~diff_mask))
> ++		  /* Check for overflow. Sign bits must be all zeroes or
> ++		     all ones.  When sign bits are all ones diff_value
> ++		     may not be zero.  */
> ++		  if (((diff_value & ~diff_mask) != 0
> ++		       && (diff_value & ~diff_mask) != ~diff_mask)
> ++		      || (diff_value && (bfd_vma) diff_value == ~diff_mask))
> + 		    {
> + 		      (*link_info->callbacks->reloc_dangerous)
> + 			(link_info, _("overflow after relaxation"),
> +-- 
> +2.20.1
> +
> diff --git a/package/binutils/2.32/0009-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch b/package/binutils/2.32/0009-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch
> new file mode 100644
> index 000000000000..ebb08fd7dffe
> --- /dev/null
> +++ b/package/binutils/2.32/0009-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch
> @@ -0,0 +1,128 @@
> +From 735321812435ae278d3766a3371f55937dc776d6 Mon Sep 17 00:00:00 2001
> +From: Max Filippov <jcmvbkbc@gmail.com>
> +Date: Sat, 25 Apr 2020 00:40:25 -0700
> +Subject: [PATCH] xtensa: fix XTENSA_NDIFF handling for PR ld/25861
> +
> +Fields marked with XTENSA_NDIFF relocations are not negated, they only
> +have sign bits removed. Don't negate their values when relaxation is
> +performed. Don't add sign bits when the value is zero. Report overflow
> +when the result has negative sign but all significant bits are zero.
> +
> +2020-04-29  Max Filippov  <jcmvbkbc@gmail.com>
> +bfd/
> +	* elf32-xtensa.c (relax_section): Don't negate diff_value for
> +	XTENSA_NDIFF relocations. Don't add sign bits whe diff_value
> +	equals 0. Report overflow when the result has negative sign but
> +	all significant bits are zero.
> +
> +Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
> +---
> +Backported from: d548f47df4d2e3d117d504a4c9977982c78a0556
> +
> + bfd/elf32-xtensa.c                   | 26 +++++++++++++++-----------
> + 1 file changed, 15 insertions(+), 11 deletions(-)
> +
> +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
> +index fded42d52a9a..4327b027911f 100644
> +--- a/bfd/elf32-xtensa.c
> ++++ b/bfd/elf32-xtensa.c
> +@@ -9670,37 +9670,44 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
> + 		  switch (r_type)
> + 		    {
> + 		    case R_XTENSA_DIFF8:
> ++		      diff_mask = 0x7f;
> + 		      diff_value =
> + 			bfd_get_signed_8 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF16:
> ++		      diff_mask = 0x7fff;
> + 		      diff_value =
> + 			bfd_get_signed_16 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF32:
> ++		      diff_mask = 0x7fffffff;
> + 		      diff_value =
> + 			bfd_get_signed_32 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF8:
> + 		    case R_XTENSA_NDIFF8:
> ++		      diff_mask = 0xff;
> + 		      diff_value =
> + 			bfd_get_8 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF16:
> + 		    case R_XTENSA_NDIFF16:
> ++		      diff_mask = 0xffff;
> + 		      diff_value =
> + 			bfd_get_16 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF32:
> + 		    case R_XTENSA_NDIFF32:
> ++		      diff_mask = 0xffffffff;
> + 		      diff_value =
> + 			bfd_get_32 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    }
> + 
> + 		  if (r_type >= R_XTENSA_NDIFF8
> +-		      && r_type <= R_XTENSA_NDIFF32)
> +-		    diff_value = -diff_value;
> ++		      && r_type <= R_XTENSA_NDIFF32
> ++		      && diff_value)
> ++		    diff_value |= ~diff_mask;
> + 
> + 		  new_end_offset = offset_with_removed_text_map
> + 		    (&target_relax_info->action_list,
> +@@ -9710,43 +9717,40 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
> + 		  switch (r_type)
> + 		    {
> + 		    case R_XTENSA_DIFF8:
> +-		      diff_mask = 0x7f;
> + 		      bfd_put_signed_8 (abfd, diff_value,
> + 				 &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF16:
> +-		      diff_mask = 0x7fff;
> + 		      bfd_put_signed_16 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF32:
> +-		      diff_mask = 0x7fffffff;
> + 		      bfd_put_signed_32 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF8:
> + 		    case R_XTENSA_NDIFF8:
> +-		      diff_mask = 0xff;
> + 		      bfd_put_8 (abfd, diff_value,
> + 				 &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF16:
> + 		    case R_XTENSA_NDIFF16:
> +-		      diff_mask = 0xffff;
> + 		      bfd_put_16 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF32:
> + 		    case R_XTENSA_NDIFF32:
> +-		      diff_mask = 0xffffffff;
> + 		      bfd_put_32 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    }
> + 
> +-		  /* Check for overflow. Sign bits must be all zeroes or all ones */
> +-		  if ((diff_value & ~diff_mask) != 0 &&
> +-		      (diff_value & ~diff_mask) != (-1 & ~diff_mask))
> ++		  /* Check for overflow. Sign bits must be all zeroes or
> ++		     all ones.  When sign bits are all ones diff_value
> ++		     may not be zero.  */
> ++		  if (((diff_value & ~diff_mask) != 0
> ++		       && (diff_value & ~diff_mask) != ~diff_mask)
> ++		      || (diff_value && (bfd_vma) diff_value == ~diff_mask))
> + 		    {
> + 		      (*link_info->callbacks->reloc_dangerous)
> + 			(link_info, _("overflow after relaxation"),
> +-- 
> +2.20.1
> +
> diff --git a/package/binutils/2.33.1/0006-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch b/package/binutils/2.33.1/0006-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch
> new file mode 100644
> index 000000000000..ebb08fd7dffe
> --- /dev/null
> +++ b/package/binutils/2.33.1/0006-xtensa-fix-XTENSA_NDIFF-handling-for-PR-ld-25861.patch
> @@ -0,0 +1,128 @@
> +From 735321812435ae278d3766a3371f55937dc776d6 Mon Sep 17 00:00:00 2001
> +From: Max Filippov <jcmvbkbc@gmail.com>
> +Date: Sat, 25 Apr 2020 00:40:25 -0700
> +Subject: [PATCH] xtensa: fix XTENSA_NDIFF handling for PR ld/25861
> +
> +Fields marked with XTENSA_NDIFF relocations are not negated, they only
> +have sign bits removed. Don't negate their values when relaxation is
> +performed. Don't add sign bits when the value is zero. Report overflow
> +when the result has negative sign but all significant bits are zero.
> +
> +2020-04-29  Max Filippov  <jcmvbkbc@gmail.com>
> +bfd/
> +	* elf32-xtensa.c (relax_section): Don't negate diff_value for
> +	XTENSA_NDIFF relocations. Don't add sign bits whe diff_value
> +	equals 0. Report overflow when the result has negative sign but
> +	all significant bits are zero.
> +
> +Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
> +---
> +Backported from: d548f47df4d2e3d117d504a4c9977982c78a0556
> +
> + bfd/elf32-xtensa.c                   | 26 +++++++++++++++-----------
> + 1 file changed, 15 insertions(+), 11 deletions(-)
> +
> +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
> +index fded42d52a9a..4327b027911f 100644
> +--- a/bfd/elf32-xtensa.c
> ++++ b/bfd/elf32-xtensa.c
> +@@ -9670,37 +9670,44 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
> + 		  switch (r_type)
> + 		    {
> + 		    case R_XTENSA_DIFF8:
> ++		      diff_mask = 0x7f;
> + 		      diff_value =
> + 			bfd_get_signed_8 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF16:
> ++		      diff_mask = 0x7fff;
> + 		      diff_value =
> + 			bfd_get_signed_16 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF32:
> ++		      diff_mask = 0x7fffffff;
> + 		      diff_value =
> + 			bfd_get_signed_32 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF8:
> + 		    case R_XTENSA_NDIFF8:
> ++		      diff_mask = 0xff;
> + 		      diff_value =
> + 			bfd_get_8 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF16:
> + 		    case R_XTENSA_NDIFF16:
> ++		      diff_mask = 0xffff;
> + 		      diff_value =
> + 			bfd_get_16 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF32:
> + 		    case R_XTENSA_NDIFF32:
> ++		      diff_mask = 0xffffffff;
> + 		      diff_value =
> + 			bfd_get_32 (abfd, &contents[old_source_offset]);
> + 		      break;
> + 		    }
> + 
> + 		  if (r_type >= R_XTENSA_NDIFF8
> +-		      && r_type <= R_XTENSA_NDIFF32)
> +-		    diff_value = -diff_value;
> ++		      && r_type <= R_XTENSA_NDIFF32
> ++		      && diff_value)
> ++		    diff_value |= ~diff_mask;
> + 
> + 		  new_end_offset = offset_with_removed_text_map
> + 		    (&target_relax_info->action_list,
> +@@ -9710,43 +9717,40 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
> + 		  switch (r_type)
> + 		    {
> + 		    case R_XTENSA_DIFF8:
> +-		      diff_mask = 0x7f;
> + 		      bfd_put_signed_8 (abfd, diff_value,
> + 				 &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF16:
> +-		      diff_mask = 0x7fff;
> + 		      bfd_put_signed_16 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_DIFF32:
> +-		      diff_mask = 0x7fffffff;
> + 		      bfd_put_signed_32 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF8:
> + 		    case R_XTENSA_NDIFF8:
> +-		      diff_mask = 0xff;
> + 		      bfd_put_8 (abfd, diff_value,
> + 				 &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF16:
> + 		    case R_XTENSA_NDIFF16:
> +-		      diff_mask = 0xffff;
> + 		      bfd_put_16 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    case R_XTENSA_PDIFF32:
> + 		    case R_XTENSA_NDIFF32:
> +-		      diff_mask = 0xffffffff;
> + 		      bfd_put_32 (abfd, diff_value,
> + 				  &contents[old_source_offset]);
> + 		      break;
> + 		    }
> + 
> +-		  /* Check for overflow. Sign bits must be all zeroes or all ones */
> +-		  if ((diff_value & ~diff_mask) != 0 &&
> +-		      (diff_value & ~diff_mask) != (-1 & ~diff_mask))
> ++		  /* Check for overflow. Sign bits must be all zeroes or
> ++		     all ones.  When sign bits are all ones diff_value
> ++		     may not be zero.  */
> ++		  if (((diff_value & ~diff_mask) != 0
> ++		       && (diff_value & ~diff_mask) != ~diff_mask)
> ++		      || (diff_value && (bfd_vma) diff_value == ~diff_mask))
> + 		    {
> + 		      (*link_info->callbacks->reloc_dangerous)
> + 			(link_info, _("overflow after relaxation"),
> +-- 
> +2.20.1
> +
> -- 
> 2.20.1
> 
> _______________________________________________
> buildroot mailing list
> buildroot at busybox.net
> http://lists.busybox.net/mailman/listinfo/buildroot

-- 
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 561 099 427 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'

  parent reply	other threads:[~2020-05-01 20:17 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-30  5:08 [Buildroot] [PATCH] package/binutils: fix XTENSA_NDIFF handling for PR ld/25861 Max Filippov
2020-05-01 19:25 ` Romain Naour
2020-05-07 21:10   ` Romain Naour
2020-05-08  8:31     ` Max Filippov
2020-05-01 20:17 ` Yann E. MORIN [this message]
2020-05-08  9:38 ` Peter Korsgaard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200501201706.GG3687@scaer \
    --to=yann.morin.1998@free.fr \
    --cc=buildroot@busybox.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.