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.hu...@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/

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to