ARM STM32L4XX erratum test failure

Message ID 20190515071357.GD6820@bubble.grove.modra.org
State New
Headers show
Series
  • ARM STM32L4XX erratum test failure
Related show

Commit Message

Alan Modra May 15, 2019, 7:13 a.m.
Fixes a failure seen with MALLOC_PERTURB_=1.  Applied.

	* elf32-arm.c (elf32_arm_write_section): Don't leave
	error case of STM32L4XX_ERRATUM_BRANCH_TO_VENEER with
	unitialised section contents.


-- 
Alan Modra
Australia Development Lab, IBM

Comments

Szabolcs Nagy May 16, 2019, 12:19 p.m. | #1
On 15/05/2019 08:13, Alan Modra wrote:
> Fixes a failure seen with MALLOC_PERTURB_=1.  Applied.

> 

> 	* elf32-arm.c (elf32_arm_write_section): Don't leave

> 	error case of STM32L4XX_ERRATUM_BRANCH_TO_VENEER with

> 	unitialised section contents.


since this commit on arm targets i see

FAIL: STM32L4XX erratum : LDM cannot be patched when LDM is too far from veneer section

the log has

/B/ld/../gas/as-new  -EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16  -o tmpdir/stm32l4xx-cannot-fix-far-ldm.o
/S/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-far-ldm.s
Executing on host: sh -c {/B/ld/../gas/as-new  -EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16  -o tmpdir/stm32l4xx-cannot-fix-far-ldm.o
/S/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-far-ldm.s 2>&1}  /dev/null dump.tmp (timeout = 300)
spawn [open ...]
./ld-new -z norelro  -L/S/ld/testsuite/ld-arm  -EL --fix-stm32l4xx-629360 -Ttext=0x80000 -o tmpdir/dump tmpdir/stm32l4xx-cannot-fix-far-ldm.o
Executing on host: sh -c {./ld-new -z norelro  -L/S/ld/testsuite/ld-arm  -EL --fix-stm32l4xx-629360 -Ttext=0x80000 -o tmpdir/dump
tmpdir/stm32l4xx-cannot-fix-far-ldm.o  2>&1}  /dev/null dump.tmp (timeout = 300)
spawn [open ...]
./ld-new: tmpdir/dump(0x1080024): error: cannot create STM32L4XX veneer; jump out of range by 24 bytes; cannot encode branch instruction
./ld-new: tmpdir/dump: error: cannot create STM32L4XX veneer
succeeded with: <./ld-new: tmpdir/dump(0x1080024): error: cannot create STM32L4XX veneer; jump out of range by 24 bytes; cannot encode branch
instruction
./ld-new: tmpdir/dump: error: cannot create STM32L4XX veneer>, expected: <.*cannot create STM32L4XX veneer; jump out of range by 24 bytes;
cannot encode branch instruction.*>
/B/ld/../binutils/objdump  -dr --prefix-addresses --show-raw-insn tmpdir/dump > tmpdir/dump.out
Executing on host: sh -c {/B/ld/../binutils/objdump  -dr --prefix-addresses --show-raw-insn tmpdir/dump > tmpdir/dump.out 2>dump.tmp}  /dev/null
 (timeout = 300)
spawn [open ...]
regexp_diff match failure
regexp "^01080024 <__stm32l4xx_veneer_0_r\+0x100> e899 03fe[[:space:]]+ldmia\.w[[:space:]]+r9, {r1, r2, r3, r4, r5, r6, r7, r8, r9}$"
line   "01080024 <__stm32l4xx_veneer_0_r+0x100> 0000            movs    r0, r0"
regexp_diff match failure
regexp "^01080028 <__stm32l4xx_veneer_1_r> bf00[[:space:]]+nop$"
line   "01080026 <__stm32l4xx_veneer_0_r+0x102> 03fe            lsls    r6, r7, #15"
extra lines in tmpdir/dump.out starting with "^01080028 <__stm32l4xx_veneer_1_r> bf00           nop$"
EOF from /B/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-far-ldm.d
FAIL: STM32L4XX erratum : LDM cannot be patched when LDM is too far from veneer section

> 

> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c

> index 337961d26e..a8d57019c8 100644

> --- a/bfd/elf32-arm.c

> +++ b/bfd/elf32-arm.c

> @@ -19693,6 +19693,9 @@ elf32_arm_write_section (bfd *output_bfd,

>  		bfd_vma branch_to_veneer =

>  		  stm32l4xx_errnode->u.b.veneer->vma - stm32l4xx_errnode->vma;

>  

> +		/* The instruction is before the label.  */

> +		target -= 4;

> +

>  		if ((signed) branch_to_veneer < -(1 << 24)

>  		    || (signed) branch_to_veneer >= (1 << 24))

>  		  {

> @@ -19710,15 +19713,15 @@ elf32_arm_write_section (bfd *output_bfd,

>  		       output_bfd,

>  		       (uint64_t) (stm32l4xx_errnode->vma - 4),

>  		       (int64_t) out_of_range);

> +

> +		    /* Don't leave contents uninitialised.  */

> +		    bfd_put_16 (output_bfd, 0, contents + target);

>  		    continue;

>  		  }

>  

>  		insn = create_instruction_branch_absolute

>  		  (stm32l4xx_errnode->u.b.veneer->vma - stm32l4xx_errnode->vma);

>  

> -		/* The instruction is before the label.  */

> -		target -= 4;

> -

>  		put_thumb2_insn (globals, output_bfd,

>  				 (bfd_vma) insn, contents + target);

>  	      }

>
Alan Modra May 16, 2019, 1:04 p.m. | #2
On Thu, May 16, 2019 at 12:19:31PM +0000, Szabolcs Nagy wrote:
> On 15/05/2019 08:13, Alan Modra wrote:

> > Fixes a failure seen with MALLOC_PERTURB_=1.  Applied.

> > 

> > 	* elf32-arm.c (elf32_arm_write_section): Don't leave

> > 	error case of STM32L4XX_ERRATUM_BRANCH_TO_VENEER with

> > 	unitialised section contents.

> 

> since this commit on arm targets i see

> 

> FAIL: STM32L4XX erratum : LDM cannot be patched when LDM is too far from veneer section


Oh wow, looks like I didn't test the "fix" at all.  Reverting.

-- 
Alan Modra
Australia Development Lab, IBM
Alan Modra May 16, 2019, 1:43 p.m. | #3
On Thu, May 16, 2019 at 10:34:35PM +0930, Alan Modra wrote:
> On Thu, May 16, 2019 at 12:19:31PM +0000, Szabolcs Nagy wrote:

> > On 15/05/2019 08:13, Alan Modra wrote:

> > > Fixes a failure seen with MALLOC_PERTURB_=1.  Applied.

> > > 

> > > 	* elf32-arm.c (elf32_arm_write_section): Don't leave

> > > 	error case of STM32L4XX_ERRATUM_BRANCH_TO_VENEER with

> > > 	unitialised section contents.

> > 

> > since this commit on arm targets i see

> > 

> > FAIL: STM32L4XX erratum : LDM cannot be patched when LDM is too far from veneer section

> 

> Oh wow, looks like I didn't test the "fix" at all.  Reverting.


The fix of course needs to be on the STM32L4XX_ERRATUM_VENEER case
below the one I patched, or simply init the entire contents.

We use this approach in most backend size_dynamic_sections (including
ARM).  I'll hold off committing this in case the ARM maintainers might
like to implement a more elegant solution.

	* elf32-arm.c (arm_allocate_glue_section_space): Initialise
	section contents.

diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 337961d26e..d459561a9d 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -7222,7 +7222,7 @@ arm_allocate_glue_section_space (bfd * abfd, bfd_size_type size, const char * na
   s = bfd_get_linker_section (abfd, name);
   BFD_ASSERT (s != NULL);
 
-  contents = (bfd_byte *) bfd_alloc (abfd, size);
+  contents = (bfd_byte *) bfd_zalloc (abfd, size);
 
   BFD_ASSERT (s->size == size);
   s->contents = contents;

-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 337961d26e..a8d57019c8 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -19693,6 +19693,9 @@  elf32_arm_write_section (bfd *output_bfd,
 		bfd_vma branch_to_veneer =
 		  stm32l4xx_errnode->u.b.veneer->vma - stm32l4xx_errnode->vma;
 
+		/* The instruction is before the label.  */
+		target -= 4;
+
 		if ((signed) branch_to_veneer < -(1 << 24)
 		    || (signed) branch_to_veneer >= (1 << 24))
 		  {
@@ -19710,15 +19713,15 @@  elf32_arm_write_section (bfd *output_bfd,
 		       output_bfd,
 		       (uint64_t) (stm32l4xx_errnode->vma - 4),
 		       (int64_t) out_of_range);
+
+		    /* Don't leave contents uninitialised.  */
+		    bfd_put_16 (output_bfd, 0, contents + target);
 		    continue;
 		  }
 
 		insn = create_instruction_branch_absolute
 		  (stm32l4xx_errnode->u.b.veneer->vma - stm32l4xx_errnode->vma);
 
-		/* The instruction is before the label.  */
-		target -= 4;
-
 		put_thumb2_insn (globals, output_bfd,
 				 (bfd_vma) insn, contents + target);
 	      }