to drop reliance on ld's default linker script .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) PROVIDE_HIDDEN (__init_array_end = .); } The input section description is quite close but does not sort .init_array.* and .ctors.* with the same priority together.
The comment in morestack.S might be just wrong. # Make __stack_split_initialize a high priority constructor. FIXME: # This is ELF specific. .section .ctors.65535,"aw",@progbits So I read the manual and even read the details on the linker script. The comment is incorrect really. The higher number the later it will be. In this case it is 64k-1. So looking at the linker script: KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) this means the ctors.65535 will come last. I don't see any issue here really in the end because GCC will produce init_array most of the time.
> this means the ctors.65535 will come last. Nope, it will come first. And since DT_INIT_ARRAY pointers are executed in the order they appear in the array, it will be one of the first to run. .init_array and .ctors sorting is complicated. ld.bfd will sort .init_array.0 (highest priority .init_array section) and .ctors.65535 (highest priority .ctors section) together. I assume this comment: > The input section description is quite close but does not sort .init_array.* and .ctors.* with the same priority together. is referring to lld. > I don't see any issue here really in the end because GCC will produce init_array most of the time. So the issue really is that lld doesn't support mixing of .ctors.* and .init_array.*. It might be nice for libgcc to use .init_array.0 here instead of .ctors.65536 whenever gcc will use .init_array in compiled code.
(In reply to Alan Modra from comment #2) > > this means the ctors.65535 will come last. > Nope, it will come first. And since DT_INIT_ARRAY pointers are executed in > the order they appear in the array, it will be one of the first to run. > .init_array and .ctors sorting is complicated. ld.bfd will sort > .init_array.0 (highest priority .init_array section) and .ctors.65535 > (highest priority .ctors section) together. > > I assume this comment: > > The input section description is quite close but does not sort .init_array.* and .ctors.* with the same priority together. > is referring to lld. `KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))` The syntax is ambiguous. I can read it this way: place .init_array.* before .ctors.* , but the behavior is (the ideal way): .init_array 0x0000000000402ff9 0x7 [!provide] PROVIDE (__init_array_start = .) *(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)) .init_array.5 0x0000000000402ff9 0x1 a.o .ctors.65529 0x0000000000402ffa 0x1 a.o .init_array.7 0x0000000000402ffb 0x1 a.o .ctors.65435 0x0000000000402ffc 0x1 a.o .init_array.100 0x0000000000402ffd 0x1 a.o *(.init_array EXCLUDE_FILE(*crtend?.o *crtend.o *crtbegin?.o *crtbegin.o) .ctors) .init_array 0x0000000000402ffe 0x1 a.o .ctors 0x0000000000402fff 0x1 a.o [!provide] PROVIDE (__init_array_end = .) It is unclear that contiguous SORT_BY_INIT_PRIORITY are sorted as a unit. > > I don't see any issue here really in the end because GCC will produce init_array most of the time. > So the issue really is that lld doesn't support mixing of .ctors.* and > .init_array.*. Yes. > It might be nice for libgcc to use .init_array.0 here instead of > .ctors.65536 whenever gcc will use .init_array in compiled code. Yes. This is the only place I know where modern Linux distrubtions is still using .ctors* in .o files.
Fixed by f49e3d28be44179f07b8a06159139ce77096dda7 ("libgcc: use .init_stack for constructors if available"). Thanks, Ian!