On Wed, Dec 02, 2020 at 05:15:21AM -0800, H.J. Lu via Gcc-patches wrote: > gcc/ > > PR middle-end/93195 > PR middle-end/93197 > * configure.ac (HAVE_GAS_SECTION_LINK_ORDER): New. Define 1 if > the assembler supports the section flag 'o' for specifying > section with link-order. > * output.h (SECTION_LINK_ORDER): New. Defined to 0x8000000. > (SECTION_MACH_DEP): Changed from 0x8000000 to 0x10000000. > * targhooks.c (default_print_patchable_function_entry): Pass > SECTION_LINK_ORDER to switch_to_section if the section flag 'o' > works. Pass current_function_decl to switch_to_section. > * varasm.c (default_elf_asm_named_section): Use 'o' flag for > SECTION_LINK_ORDER if assembler supports it. > * config.in: Regenerated. > * configure: Likewise.
Dunno if it is an assembler bug or gcc bug, but this SECTION_LINK_ORDER stuff doesn't seem to work properly. If I compile: static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((patchable_function_entry(0, 0))) int foo (int x) { return x + 1; } static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((patchable_function_entry(0, 0))) int bar (int x) { return x + 2; } int baz (int x) { return foo (x) + 1; } int qux (int x) { return bar (x) + 2; } (distilled from aarch64 Linux kernel) with -O2 -fpatchable-function-entry=2 on aarch64 compiler configured against latest binutils, I get: ... .section __patchable_function_entries,"awo",@progbits,baz ... .section __patchable_function_entries ... in the assembly, but when it is assembled, one gets: [ 4] __patchable_function_entries PROGBITS 0000000000000000 000060 000008 00 WAL 1 0 8 [ 5] .rela__patchable_function_entries RELA 0000000000000000 000280 000018 18 I 12 4 8 [ 6] __patchable_function_entries PROGBITS 0000000000000000 000068 000008 00 0 0 8 [ 7] .rela__patchable_function_entries RELA 0000000000000000 000298 000018 18 I 12 6 8 i.e. one writable allocated section with SHF_LINK_ORDER and another non-allocated non-writable without link order. In the kernel case there is always one entry in the WAL section and then dozens or more in the non-allocated one. The kernel then fails to link: WARNING: modpost: vmlinux.o (__patchable_function_entries): unexpected non-allocatable section. Did you forget to use "ax"/"aw" in a .S file? Note that for example <linux/init.h> contains section definitions for use in .S files. ld: .init.data has both ordered [`__patchable_function_entries' in init/main.o] and unordered [`.init.data' in ./drivers/firmware/efi/libstub/vsprintf.stub.o] sections ld: final link failed: bad value make: *** [Makefile:1175: vmlinux] Error 1 If it is correct that the assembler requires full section flags for the SECTION_LINK_ORDER .section directives in every case (like it does for comdat or for retain), then we should do something like the following untested change, but if it is gas bug, it should be fixed there. 2020-12-15 Jakub Jelinek <ja...@redhat.com> * varasm.c (default_elf_asm_named_section): Always force section flags even for sections with SECTION_LINK_ORDER flag. --- gcc/varasm.c.jj 2020-12-13 17:07:53.910477664 +0100 +++ gcc/varasm.c 2020-12-15 21:33:35.169314414 +0100 @@ -6781,10 +6781,10 @@ default_elf_asm_named_section (const cha /* If we have already declared this section, we can use an abbreviated form to switch back to it -- unless this section is - part of a COMDAT groups or with SHF_GNU_RETAIN, in which case GAS - requires the full declaration every time. */ + part of a COMDAT groups or with SHF_GNU_RETAIN or with SHF_LINK_ORDER, + in which case GAS requires the full declaration every time. */ if (!(HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE)) - && !(flags & SECTION_RETAIN) + && !(flags & (SECTION_RETAIN | SECTION_LINK_ORDER)) && (flags & SECTION_DECLARED)) { fprintf (asm_out_file, "\t.section\t%s\n", name); Jakub