[v3,13/13] RISC-V/bfd: warn about non-power-of-2 stack-align attribute

Message ID 2fcf62ca-0e51-48fc-a9cf-7a48a40dc82e@suse.com
State New
Headers
Series RISC-V: assorted fixes and (hopefully) improvements |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Jan Beulich June 19, 2026, 11:53 a.m. UTC
  Only power-of-2 values are sensible for alignment. Reject other values.

While there also drop a redundant part of a related conditional.
---
v3: New.
  

Comments

Jiawei June 22, 2026, 9:35 a.m. UTC | #1
On 2026/6/19 19:53, Jan Beulich wrote:
> Only power-of-2 values are sensible for alignment. Reject other values.
>
> While there also drop a redundant part of a related conditional.
> ---
> v3: New.
>
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -3791,6 +3791,17 @@ riscv_merge_attributes (bfd *ibfd, struc
>   		 ibfd);
>   	      out_attr[i].i = 1;
>   	      break;
> +
> +	    case Tag_RISCV_stack_align:
> +	      if (!(out_attr[i].i & (out_attr[i].i - 1)))
> +		break;
> +
> +	      _bfd_error_handler
> +		(_("warning: %pB uses non-power-of-2 `stack align' attribute; "
> +		   "ignoring"), + ibfd); + out_attr[i].i = 0; + break; } } @@ -3891,10 +3902,14 @@ 
> riscv_merge_attributes (bfd *ibfd, struc break; case 
> Tag_RISCV_stack_align: - if (out_attr[i].i == 0) + if ((in_attr[i].i & 
> (in_attr[i].i - 1)) != 0) + _bfd_error_handler + (_("warning: %pB uses non-power-of-2 `stack align' attribute; "
> +	       "ignoring"),
> +	     ibfd);
> +	else if (out_attr[i].i == 0)
>   	  out_attr[i].i = in_attr[i].i;
>   	else if (in_attr[i].i != 0
> -		 && out_attr[i].i != 0
>   		 && out_attr[i].i != in_attr[i].i)
>   	  {
>   	    _bfd_error_handler

I tested the first-object path specifically. With the patch behavior
reproduced, an input object containing a non-power-of-2 stack_align value,

for example
.attribute stack_align, 0x4444

emits the warning, and the ld -r output omits Tag_RISCV_stack_align 
entirely.

The readelf shows this as Tag_RISCV_stack_align: 17476-bytes,
It does not emit an explicit 0-byte stack alignment attribute. So setting

out_attr[Tag_RISCV_stack_align].i = 0

appears to be sufficient to ignore the invalid value.

I also checked the merge cases. invalid + valid16 and valid16 + invalid both
emit the warning for the invalid object and keep the valid 16-byte stack
alignment in the output. An explicit input

.attribute stack_align, 0

is also omitted from the object, so zero behaves consistently as "unset" 
from
the BFD merge point of view.

The existing valid non-zero mismatch behavior is unchanged: linking 16-byte
and 32-byte stack alignment objects still errors as before.

Reviewed-by: Jiawei jiawei@iscas.ac.cn
  

Patch

--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -3791,6 +3791,17 @@  riscv_merge_attributes (bfd *ibfd, struc
 		 ibfd);
 	      out_attr[i].i = 1;
 	      break;
+
+	    case Tag_RISCV_stack_align:
+	      if (!(out_attr[i].i & (out_attr[i].i - 1)))
+		break;
+
+	      _bfd_error_handler
+		(_("warning: %pB uses non-power-of-2 `stack align' attribute; "
+		   "ignoring"),
+		 ibfd);
+	      out_attr[i].i = 0;
+	      break;
 	    }
 	}
 
@@ -3891,10 +3902,14 @@  riscv_merge_attributes (bfd *ibfd, struc
 	break;
 
       case Tag_RISCV_stack_align:
-	if (out_attr[i].i == 0)
+	if ((in_attr[i].i & (in_attr[i].i - 1)) != 0)
+	  _bfd_error_handler
+	    (_("warning: %pB uses non-power-of-2 `stack align' attribute; "
+	       "ignoring"),
+	     ibfd);
+	else if (out_attr[i].i == 0)
 	  out_attr[i].i = in_attr[i].i;
 	else if (in_attr[i].i != 0
-		 && out_attr[i].i != 0
 		 && out_attr[i].i != in_attr[i].i)
 	  {
 	    _bfd_error_handler