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