splinkersets01 test assumptions

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Feb 17 06:15:13 UTC 2021


On 16/02/2021 22:26, Kinsey Moore wrote:

> In verifying AArch64/ILP32 on hardware I ran across quite a few 
> alignment issues,
>
> some of which were caused by the use of SUBALIGN() in the linker 
> scripts mentioned here:
>
> https://devel.rtems.org/ticket/4178 <https://devel.rtems.org/ticket/4178>
>
> SUBALIGN() was necessary for two reasons:
>
>   * libc sysinit linker sets (this can be fixed in the sysinit handler
>     struct)
>   * splinkersets01 could not be made to pass on ILP32 as-is without
>     SUBALIGN
>
In the ld documentation we have:

https://sourceware.org/binutils/docs/ld/Forced-Input-Alignment.html#index-SUBALIGN_0028subsection_005falign_0029

"You can force input section alignment within an output section by using 
SUBALIGN. The value specified overrides any alignment given by input 
sections, whether larger or smaller."

I think the use of SUBALIGN() is a bug and should be removed. Why do you 
want to override the alignment of the input sections?

> It seems that splinkersets01 makes the assumption that linker sets are 
> aligned to no more
>
> than the size of a pointer. For ILP32, this is not the case since 
> AArch64 hardware is very
>
> sensitive to misaligned accesses and many structs in linker sections 
> need to be aligned to
>
> 8-byte boundaries to avoid throwing exceptions. Some may even need to 
> be aligned to
>
> 16-byte boundaries depending on the structure, but this doesn’t apply 
> to splinkersets01.
>
> The resultant alignment padding causes many assertions in 
> splinkersets01 to fail.
>
The linker sets should use the alignment of the item type. This is done 
by defining zero length arrays:

#define RTEMS_LINKER_ROSET( set, type ) \
   type const RTEMS_LINKER_SET_BEGIN( set )[ 0 ] \
   RTEMS_SECTION( ".rtemsroset." #set ".begin" ) RTEMS_USED; \
   type const RTEMS_LINKER_SET_END( set )[ 0 ] \
   RTEMS_SECTION( ".rtemsroset." #set ".end" ) RTEMS_USED

In standard C such arrays are not defined, but GCC does the right thing:

cat test-linkersets.c
#define RTEMS_USED __attribute__(( __used__ ))

#define RTEMS_SECTION( _section ) __attribute__(( __section__( _section ) ))

#define RTEMS_LINKER_SET_BEGIN( set ) \
   _Linker_set_##set##_begin

#define RTEMS_LINKER_SET_END( set ) \
   _Linker_set_##set##_end

#define RTEMS_LINKER_ROSET( set, type ) \
   type const RTEMS_LINKER_SET_BEGIN( set )[ 0 ] \
   RTEMS_SECTION( ".rtemsroset." #set ".begin" ) RTEMS_USED; \
   type const RTEMS_LINKER_SET_END( set )[ 0 ] \
   RTEMS_SECTION( ".rtemsroset." #set ".end" ) RTEMS_USED

struct s { __attribute__((__aligned__(256))) int i; };

RTEMS_LINKER_ROSET( i, int );
RTEMS_LINKER_ROSET( ll, long long );
RTEMS_LINKER_ROSET( s, struct s );

aarch64-rtems6-gcc -O2 -S -o - test-linkersets.c
         .arch armv8-a
         .file   "test-linkersets.c"
         .text
         .global _Linker_set_s_end
         .global _Linker_set_s_begin
         .global _Linker_set_ll_end
         .global _Linker_set_ll_begin
         .global _Linker_set_i_end
         .global _Linker_set_i_begin
         .section        .rtemsroset.i.begin,"a"
         .align  3
         .type   _Linker_set_i_begin, %object
         .size   _Linker_set_i_begin, 0
_Linker_set_i_begin:
         .section        .rtemsroset.i.end,"a"
         .align  3
         .type   _Linker_set_i_end, %object
         .size   _Linker_set_i_end, 0
_Linker_set_i_end:
         .section        .rtemsroset.ll.begin,"a"
         .align  3
         .type   _Linker_set_ll_begin, %object
         .size   _Linker_set_ll_begin, 0
_Linker_set_ll_begin:
         .section        .rtemsroset.ll.end,"a"
         .align  3
         .type   _Linker_set_ll_end, %object
         .size   _Linker_set_ll_end, 0
_Linker_set_ll_end:
         .section        .rtemsroset.s.begin,"a"
         .align  8
         .type   _Linker_set_s_begin, %object
         .size   _Linker_set_s_begin, 0
_Linker_set_s_begin:
         .section        .rtemsroset.s.end,"a"
         .align  8
         .type   _Linker_set_s_end, %object
         .size   _Linker_set_s_end, 0
_Linker_set_s_end:
         .ident  "GCC: (GNU) 10.2.1 20210205 (RTEMS 6, RSB 
61dcadee0825867ebe51f9f367430ef75b8fe9c0, Newlib d4a756f)"

aarch64-rtems6-gcc -O2 -S -o - test-linkersets.c -mabi=ilp32
         .arch armv8-a
         .file   "test-linkersets.c"
         .text
         .global _Linker_set_s_end
         .global _Linker_set_s_begin
         .global _Linker_set_ll_end
         .global _Linker_set_ll_begin
         .global _Linker_set_i_end
         .global _Linker_set_i_begin
         .section        .rtemsroset.i.begin,"a"
         .align  3
         .type   _Linker_set_i_begin, %object
         .size   _Linker_set_i_begin, 0
_Linker_set_i_begin:
         .section        .rtemsroset.i.end,"a"
         .align  3
         .type   _Linker_set_i_end, %object
         .size   _Linker_set_i_end, 0
_Linker_set_i_end:
         .section        .rtemsroset.ll.begin,"a"
         .align  3
         .type   _Linker_set_ll_begin, %object
         .size   _Linker_set_ll_begin, 0
_Linker_set_ll_begin:
         .section        .rtemsroset.ll.end,"a"
         .align  3
         .type   _Linker_set_ll_end, %object
         .size   _Linker_set_ll_end, 0
_Linker_set_ll_end:
         .section        .rtemsroset.s.begin,"a"
         .align  8
         .type   _Linker_set_s_begin, %object
         .size   _Linker_set_s_begin, 0
_Linker_set_s_begin:
         .section        .rtemsroset.s.end,"a"
         .align  8
         .type   _Linker_set_s_end, %object
         .size   _Linker_set_s_end, 0
_Linker_set_s_end:
         .ident  "GCC: (GNU) 10.2.1 20210205 (RTEMS 6, RSB 
61dcadee0825867ebe51f9f367430ef75b8fe9c0, Newlib d4a756f)"

> I’m trying to find a way to make everything work together, but I’d 
> like some input.
>
> The highlights with ILP32/LibBSD/hardware:
>
>   * current codebase: stuffs a struct into a linker section with bad
>     alignment and throws an exception
>   * drop SUBALIGN and fix the sysinit issue: splinkersets01 fails, all
>     other tests pass, code runs
>
> Paths forward:
>
>   * disable splinkersets01 for AArch64/ILP32 BSPs
>   * attempt to detect section alignment and adjust splinkersets01 as
>     necessary
>   * splitting the section up for different alignments would require
>     touching every linker script
>   * ?
>
> Hopefully I’m just missing something.
>
I would remove the SUBALIGN() from the linker script. You can also add a 
new test case for splinkersets01 similar to struct s from above. Then we 
should check if the test fails on aarch64 and why it fails.

-- 
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber at embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/



More information about the devel mailing list