Kbuild puts the objects listed in head-y at the head of vmlinux.
Conventionally, we do this for head*.S, which contains the kernel entry
point.
A counter approach is to control the section order by the linker script.
Actually, the code marked as __HEAD goes into the ".head.text" section,
which is placed before the normal ".text" section.
I do not know if both of them are needed. From the build system
perspective, head-y is not mandatory. If you can achieve the proper code
placement by the linker script only, it would be cleaner.
I collected the current head-y objects into head-object-list.txt. It is
a whitelist. My hope is it will be reduced in the long run.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
    - The values of the above variables are expanded in arch/$(SRCARCH)/Makefile.
 5) All object files are then linked and the resulting file vmlinux is
    located at the root of the obj tree.
-   The very first objects linked are listed in head-y, assigned by
-   arch/$(SRCARCH)/Makefile.
+   The very first objects linked are listed in scripts/head-object-list.txt.
 6) Finally, the architecture-specific part does any required post processing
    and builds the final bootimage.
    - This includes building boot records
        All object files for vmlinux. They are linked to vmlinux in the same
        order as listed in KBUILD_VMLINUX_OBJS.
 
+       The objects listed in scripts/head-object-list.txt are exceptions;
+       they are placed before the other objects.
+
     KBUILD_VMLINUX_LIBS
 
        All .a "lib" files for vmlinux. KBUILD_VMLINUX_OBJS and
        machinery is all architecture-independent.
 
 
-       head-y, core-y, libs-y, drivers-y
-           $(head-y) lists objects to be linked first in vmlinux.
+       core-y, libs-y, drivers-y
 
            $(libs-y) lists directories where a lib.a archive can be located.
 
 
       cmd_ar_vmlinux.a = \
        rm -f $@; \
        $(AR) cDPrST $@ $(KBUILD_VMLINUX_OBJS); \
-       $(AR) mPiT $$($(AR) t $@ | head -n1) $@ $(head-y)
+       $(AR) mPiT $$($(AR) t $@ | head -n1) $@ $$($(AR) t $@ | grep -F --file=$(srctree)/scripts/head-object-list.txt)
 
 targets += vmlinux.a
-vmlinux.a: $(KBUILD_VMLINUX_OBJS) autoksyms_recursive FORCE
+vmlinux.a: $(KBUILD_VMLINUX_OBJS) scripts/head-object-list.txt autoksyms_recursive FORCE
        $(call if_changed,ar_vmlinux.a)
 
 vmlinux.o: vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE
 
 # BWX is most important, but we don't really want any emulation ever.
 KBUILD_CFLAGS += $(cflags-y) -Wa,-mev6
 
-head-y := arch/alpha/kernel/head.o
-
 libs-y                         += arch/alpha/lib/
 
 # export what is needed by arch/alpha/boot/Makefile
 
 KBUILD_AFLAGS  += $(KBUILD_CFLAGS)
 KBUILD_LDFLAGS += $(ldflags-y)
 
-head-y         := arch/arc/kernel/head.o
-
 # w/o this dtb won't embed into kernel binary
 core-y         += arch/arc/boot/dts/
 
 
 
 CHECKFLAGS     += -D__arm__
 
-#Default value
-head-y         := arch/arm/kernel/head$(MMUEXT).o
-
 # Text offset. This list is sorted numerically by address in order to
 # provide a means to avoid/resolve conflicts in multi-arch kernels.
 # Note: the 32kB below this value is reserved for use by the kernel
 
   CC_FLAGS_FTRACE := -fpatchable-function-entry=2
 endif
 
-# Default value
-head-y         := arch/arm64/kernel/head.o
-
 ifeq ($(CONFIG_KASAN_SW_TAGS), y)
 KASAN_SHADOW_SCALE_SHIFT := 4
 else ifeq ($(CONFIG_KASAN_GENERIC), y)
 
 
 KBUILD_AFLAGS += $(KBUILD_CFLAGS)
 
-head-y := arch/csky/kernel/head.o
-
 core-y += arch/csky/$(CSKYABI)/
 
 libs-y += arch/csky/lib/ \
 
 TIR_NAME := r19
 KBUILD_CFLAGS += -ffixed-$(TIR_NAME) -DTHREADINFO_REG=$(TIR_NAME) -D__linux__
 KBUILD_AFLAGS += -DTHREADINFO_REG=$(TIR_NAME)
-
-head-y := arch/hexagon/kernel/head.o
 
 cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
 
 KBUILD_CFLAGS += $(cflags-y)
-head-y := arch/ia64/kernel/head.o
 
 libs-y                         += arch/ia64/lib/
 
 
        sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g')
 endif
 
-head-y := arch/loongarch/kernel/head.o
-
 libs-y += arch/loongarch/lib/
 
 ifeq ($(KBUILD_EXTMOD),)
 
 KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g
 endif
 
-#
-# Select the assembler head startup code. Order is important. The default
-# head code is first, processor specific selections can override it after.
-#
-head-y                         := arch/m68k/kernel/head.o
-head-$(CONFIG_SUN3)            := arch/m68k/kernel/sun3-head.o
-head-$(CONFIG_M68000)          := arch/m68k/68000/head.o
-head-$(CONFIG_COLDFIRE)                := arch/m68k/coldfire/head.o
-
 libs-y                         += arch/m68k/lib/
 
 
 
 # r31 holds current when in kernel mode
 KBUILD_CFLAGS += -ffixed-r31 $(CPUFLAGS-y) $(CPUFLAGS-1) $(CPUFLAGS-2)
 
-head-y := arch/microblaze/kernel/head.o
 libs-y += arch/microblaze/lib/
 
 boot := arch/microblaze/boot
 
 
 OBJCOPYFLAGS           += --remove-section=.reginfo
 
-head-y := arch/mips/kernel/head.o
-
 libs-y                 += arch/mips/lib/
 libs-$(CONFIG_MIPS_FP_SUPPORT) += arch/mips/math-emu/
 
 
 KBUILD_CFLAGS += -fno-builtin
 KBUILD_CFLAGS += -G 0
 
-head-y         := arch/nios2/kernel/head.o
 libs-y         += arch/nios2/lib/ $(LIBGCC)
 
 INSTALL_PATH ?= /tftpboot
 
        KBUILD_CFLAGS += $(call cc-option,-msext)
 endif
 
-head-y                 := arch/openrisc/kernel/head.o
-
 libs-y         += $(LIBGCC)
 
 PHONY += vmlinux.bin
 
 cflags-$(CONFIG_PA7300LC)      += -march=1.1 -mschedule=7300
 cflags-$(CONFIG_PA8X00)                += -march=2.0 -mschedule=8000
 
-head-y                 := arch/parisc/kernel/head.o 
-
 KBUILD_CFLAGS  += $(cflags-y)
 LIBGCC         := $(shell $(CC) -print-libgcc-file-name)
 export LIBGCC
 
 KBUILD_AFLAGS += $(aflags-y)
 KBUILD_CFLAGS += $(cflags-y)
 
-head-$(CONFIG_PPC64)           := arch/powerpc/kernel/head_64.o
-head-$(CONFIG_PPC_BOOK3S_32)   := arch/powerpc/kernel/head_book3s_32.o
-head-$(CONFIG_PPC_8xx)         := arch/powerpc/kernel/head_8xx.o
-head-$(CONFIG_40x)             := arch/powerpc/kernel/head_40x.o
-head-$(CONFIG_44x)             := arch/powerpc/kernel/head_44x.o
-head-$(CONFIG_FSL_BOOKE)       := arch/powerpc/kernel/head_fsl_booke.o
-
-head-$(CONFIG_PPC64)           += arch/powerpc/kernel/entry_64.o
-head-$(CONFIG_PPC_FPU)         += arch/powerpc/kernel/fpu.o
-head-$(CONFIG_ALTIVEC)         += arch/powerpc/kernel/vector.o
-head-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE)  += arch/powerpc/kernel/prom_init.o
-
 # Default to zImage, override when needed
 all: zImage
 
 
 KBUILD_IMAGE   := $(boot)/Image.gz
 endif
 
-head-y := arch/riscv/kernel/head.o
-
 libs-y += arch/riscv/lib/
 libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 
 
 
 OBJCOPYFLAGS   := -O binary
 
-head-y         := arch/s390/kernel/head64.o
-
 libs-y         += arch/s390/lib/
 drivers-y      += drivers/s390/
 
 
 
 export ld-bfd
 
-head-y := arch/sh/kernel/head_32.o
-
 # Mach groups
 machdir-$(CONFIG_SOLUTION_ENGINE)              += mach-se
 machdir-$(CONFIG_SH_HP6XX)                     += mach-hp6xx
 
 
 endif
 
-head-y                 := arch/sparc/kernel/head_$(BITS).o
-
 libs-y                 += arch/sparc/prom/
 libs-y                 += arch/sparc/lib/
 
 
 ###
 # Kernel objects
 
-head-y := arch/x86/kernel/head_$(BITS).o
-head-y += arch/x86/kernel/head$(BITS).o
-head-y += arch/x86/kernel/ebda.o
-head-y += arch/x86/kernel/platform-quirks.o
-
 libs-y  += arch/x86/lib/
 
 # drivers-y are linked after core-y
 
 
 KBUILD_DEFCONFIG := iss_defconfig
 
-head-y         := arch/xtensa/kernel/head.o
-
 libs-y         += arch/xtensa/lib/
 
 boot           := arch/xtensa/boot
 
--- /dev/null
+# Head objects
+#
+# The objects listed here are placed at the head of vmlinux. A typical use-case
+# is an object that contains the entry point. This is kept for compatibility
+# with head-y, which Kbuild used to support.
+#
+# A counter approach is to control the section placement by the linker script.
+# The code marked as __HEAD goes into the ".head.text" section, which is placed
+# before the normal ".text" section.
+#
+# If you can achieve the correct code ordering by linker script, please delete
+# the entry from this file.
+#
+arch/alpha/kernel/head.o
+arch/arc/kernel/head.o
+arch/arm/kernel/head-nommu.o
+arch/arm/kernel/head.o
+arch/arm64/kernel/head.o
+arch/csky/kernel/head.o
+arch/hexagon/kernel/head.o
+arch/ia64/kernel/head.o
+arch/loongarch/kernel/head.o
+arch/m68k/68000/head.o
+arch/m68k/coldfire/head.o
+arch/m68k/kernel/head.o
+arch/m68k/kernel/sun3-head.o
+arch/microblaze/kernel/head.o
+arch/mips/kernel/head.o
+arch/nios2/kernel/head.o
+arch/openrisc/kernel/head.o
+arch/parisc/kernel/head.o
+arch/powerpc/kernel/head_40x.o
+arch/powerpc/kernel/head_44x.o
+arch/powerpc/kernel/head_64.o
+arch/powerpc/kernel/head_8xx.o
+arch/powerpc/kernel/head_book3s_32.o
+arch/powerpc/kernel/head_fsl_booke.o
+arch/powerpc/kernel/entry_64.o
+arch/powerpc/kernel/fpu.o
+arch/powerpc/kernel/vector.o
+arch/powerpc/kernel/prom_init.o
+arch/riscv/kernel/head.o
+arch/s390/kernel/head64.o
+arch/sh/kernel/head_32.o
+arch/sparc/kernel/head_32.o
+arch/sparc/kernel/head_64.o
+arch/x86/kernel/head_32.o
+arch/x86/kernel/head_64.o
+arch/x86/kernel/head32.o
+arch/x86/kernel/head64.o
+arch/x86/kernel/ebda.o
+arch/x86/kernel/platform-quirks.o
+arch/xtensa/kernel/head.o