diff mbox series

efi/libstub: refactor Makefile to not use lib-y syntax

Message ID 20200603053313.3863761-1-masahiroy@kernel.org (mailing list archive)
State New, archived
Headers show
Series efi/libstub: refactor Makefile to not use lib-y syntax | expand

Commit Message

Masahiro Yamada June 3, 2020, 5:33 a.m. UTC
Documentation/kbuild/makefiles.rst says:

  Use of lib-y is normally restricted to `lib/` and `arch/*/lib`.

I want to disallow lib-y outside of them.

Add a custom rule to build lib.a, which is linked to the decompressor
for ARCH=x86, ARCH=arm.

For ARCH=arm64, use obj-y to link objects to vmlinux in the ordinary
way.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 arch/arm64/Makefile                   |  1 -
 drivers/firmware/efi/Makefile         |  2 +-
 drivers/firmware/efi/libstub/Makefile | 51 +++++++++++++++------------
 3 files changed, 30 insertions(+), 24 deletions(-)

Comments

Ard Biesheuvel June 3, 2020, 6:44 a.m. UTC | #1
On Wed, 3 Jun 2020 at 07:34, Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> Documentation/kbuild/makefiles.rst says:
>
>   Use of lib-y is normally restricted to `lib/` and `arch/*/lib`.
>
> I want to disallow lib-y outside of them.
>

Why?

> Add a custom rule to build lib.a, which is linked to the decompressor
> for ARCH=x86, ARCH=arm.
>
> For ARCH=arm64, use obj-y to link objects to vmlinux in the ordinary
> way.
>

The code works perfectly fine as is, and I don't see what is
fundamentally wrong with using static libraries outside of lib/ and
arch/*/lib.

Also, I would like this code to still be incorporated as a static
library into arm64 as well, so that only pieces that are actually
needed are incorporated into the final image.



> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
> ---
>
>  arch/arm64/Makefile                   |  1 -
>  drivers/firmware/efi/Makefile         |  2 +-
>  drivers/firmware/efi/libstub/Makefile | 51 +++++++++++++++------------
>  3 files changed, 30 insertions(+), 24 deletions(-)
>
> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index 650e1185c190..ab79b20efc8d 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -145,7 +145,6 @@ export      TEXT_OFFSET
>
>  core-y         += arch/arm64/
>  libs-y         := arch/arm64/lib/ $(libs-y)
> -core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
>
>  # Default target when executing plain make
>  boot           := arch/arm64/boot
> diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
> index 7a216984552b..317a05cd388b 100644
> --- a/drivers/firmware/efi/Makefile
> +++ b/drivers/firmware/efi/Makefile
> @@ -20,7 +20,7 @@ obj-$(CONFIG_EFI_VARS_PSTORE)         += efi-pstore.o
>  obj-$(CONFIG_UEFI_CPER)                        += cper.o
>  obj-$(CONFIG_EFI_RUNTIME_MAP)          += runtime-map.o
>  obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)     += runtime-wrappers.o
> -subdir-$(CONFIG_EFI_STUB)              += libstub
> +obj-$(CONFIG_EFI_STUB)                 += libstub/
>  obj-$(CONFIG_EFI_FAKE_MEMMAP)          += fake_map.o
>  obj-$(CONFIG_EFI_BOOTLOADER_CONTROL)   += efibc.o
>  obj-$(CONFIG_EFI_TEST)                 += test/
> diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
> index cce4a7436052..e4e9b17fa3b2 100644
> --- a/drivers/firmware/efi/libstub/Makefile
> +++ b/drivers/firmware/efi/libstub/Makefile
> @@ -44,7 +44,7 @@ OBJECT_FILES_NON_STANDARD     := y
>  # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
>  KCOV_INSTRUMENT                        := n
>
> -lib-y                          := efi-stub-helper.o gop.o secureboot.o tpm.o \
> +stub-obj-y                     := efi-stub-helper.o gop.o secureboot.o tpm.o \
>                                    file.o mem.o random.o randomalloc.o pci.o \
>                                    skip_spaces.o lib-cmdline.o lib-ctype.o \
>                                    alignedmem.o relocate.o vsprintf.o
> @@ -55,15 +55,19 @@ efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
>  $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
>         $(call if_changed_rule,cc_o_c)
>
> -lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o fdt.o string.o \
> +stub-obj-$(CONFIG_EFI_GENERIC_STUB)    += efi-stub.o fdt.o string.o \
>                                    $(patsubst %.c,lib-%.o,$(efi-deps-y))
>
> -lib-$(CONFIG_ARM)              += arm32-stub.o
> -lib-$(CONFIG_ARM64)            += arm64-stub.o
> -lib-$(CONFIG_X86)              += x86-stub.o
> +stub-obj-$(CONFIG_ARM)         += arm32-stub.o
> +stub-obj-$(CONFIG_ARM64)       += arm64-stub.o
> +stub-obj-$(CONFIG_X86)         += x86-stub.o
>  CFLAGS_arm32-stub.o            := -DTEXT_OFFSET=$(TEXT_OFFSET)
>  CFLAGS_arm64-stub.o            := -DTEXT_OFFSET=$(TEXT_OFFSET)
>
> +targets                                += $(stub-obj-y)
> +stub-obj-y                     := $(patsubst %.o,%.stub.o, $(stub-obj-y))
> +targets                                += $(stub-obj-y)
> +
>  #
>  # For x86, bootloaders like systemd-boot or grub-efi do not zero-initialize the
>  # .bss section, so the .bss section of the EFI stub needs to be included in the
> @@ -83,23 +87,6 @@ STUBCOPY_FLAGS-$(CONFIG_ARM) += --rename-section .data=.data.efistub \
>                                    --rename-section .bss=.bss.efistub,load,alloc
>  STUBCOPY_RELOC-$(CONFIG_ARM)   := R_ARM_ABS
>
> -#
> -# arm64 puts the stub in the kernel proper, which will unnecessarily retain all
> -# code indefinitely unless it is annotated as __init/__initdata/__initconst etc.
> -# So let's apply the __init annotations at the section level, by prefixing
> -# the section names directly. This will ensure that even all the inline string
> -# literals are covered.
> -# The fact that the stub and the kernel proper are essentially the same binary
> -# also means that we need to be extra careful to make sure that the stub does
> -# not rely on any absolute symbol references, considering that the virtual
> -# kernel mapping that the linker uses is not active yet when the stub is
> -# executing. So build all C dependencies of the EFI stub into libstub, and do
> -# a verification pass to see if any absolute relocations exist in any of the
> -# object files.
> -#
> -extra-y                                := $(lib-y)
> -lib-y                          := $(patsubst %.o,%.stub.o,$(lib-y))
> -
>  STUBCOPY_FLAGS-$(CONFIG_ARM64) += --prefix-alloc-sections=.init \
>                                    --prefix-symbols=__efistub_
>  STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS
> @@ -121,3 +108,23 @@ quiet_cmd_stubcopy = STUBCPY $@
>                 /bin/false;                                             \
>         fi;                                                             \
>         $(OBJCOPY) $(STUBCOPY_FLAGS-y) $< $@
> +
> +# arm64 puts the stub in the kernel proper, which will unnecessarily retain all
> +# code indefinitely unless it is annotated as __init/__initdata/__initconst etc.
> +# So let's apply the __init annotations at the section level, by prefixing
> +# the section names directly. This will ensure that even all the inline string
> +# literals are covered.
> +# The fact that the stub and the kernel proper are essentially the same binary
> +# also means that we need to be extra careful to make sure that the stub does
> +# not rely on any absolute symbol references, considering that the virtual
> +# kernel mapping that the linker uses is not active yet when the stub is
> +# executing. So build all C dependencies of the EFI stub into libstub, and do
> +# a verification pass to see if any absolute relocations exist in any of the
> +# object files.
> +#
> +obj-$(CONFIG_ARM64)            += $(stub-obj-y)
> +extra-$(CONFIG_ARM)            += lib.a
> +extra-$(CONFIG_X86)            += lib.a
> +
> +$(obj)/lib.a: $(addprefix $(obj)/, $(stub-obj-y)) FORCE
> +       $(call if_changed,ar)
> --
> 2.25.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Masahiro Yamada June 3, 2020, 8:35 a.m. UTC | #2
On Wed, Jun 3, 2020 at 3:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Wed, 3 Jun 2020 at 07:34, Masahiro Yamada <masahiroy@kernel.org> wrote:
> >
> > Documentation/kbuild/makefiles.rst says:
> >
> >   Use of lib-y is normally restricted to `lib/` and `arch/*/lib`.
> >
> > I want to disallow lib-y outside of them.
> >
>
> Why?


Because I plan to remove lib-y entirely at some point.

lib-y is not so useful to shrink the image size because:

  - An object in lib.a can be omitted only when no symbol
    in that object is referenced.  This rarely happens.

  -  lib-y objects are often exported by nature
     because lib-y is a collection of utility functions.
     Even if no in-tree user, we always need to keep them
     because EXPORT_SYMBOL() is the interface to modules.


When I worked on commit 7273ad2b08f8ac9563579d16a3cf528857b26f49,
I made some research.

The benefit of lib-y is just 362 byte for x86_64_defconfig.
( Before: 26578002, After: 26578364)

My hope is lib-y will be replaced by dead-code elimination or
ultimately by LTO.

drivers/firmware/efi/libstub/Makefile
is the only Makefile that breaks the rule:
"Use of lib-y is normally restricted to `lib/` and `arch/*/lib`"




>
> > Add a custom rule to build lib.a, which is linked to the decompressor
> > for ARCH=x86, ARCH=arm.
> >
> > For ARCH=arm64, use obj-y to link objects to vmlinux in the ordinary
> > way.
> >
>
> The code works perfectly fine as is, and I don't see what is
> fundamentally wrong with using static libraries outside of lib/ and
> arch/*/lib.

The intended usage of lib-y is to hook lib.a
to scripts/vmlinux.sh via KBUILD_VMLINUX_LIBS.

This Makefile is just what you found to work.


>
> Also, I would like this code to still be incorporated as a static
> library into arm64 as well, so that only pieces that are actually
> needed are incorporated into the final image.

No.
It is not working like that because you set
lib.a to core-y.

All objects in core-y are always linked to vmlinux.




Thanks.





>
>
>
> > Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
> > ---
> >
> >  arch/arm64/Makefile                   |  1 -
> >  drivers/firmware/efi/Makefile         |  2 +-
> >  drivers/firmware/efi/libstub/Makefile | 51 +++++++++++++++------------
> >  3 files changed, 30 insertions(+), 24 deletions(-)
> >
> > diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> > index 650e1185c190..ab79b20efc8d 100644
> > --- a/arch/arm64/Makefile
> > +++ b/arch/arm64/Makefile
> > @@ -145,7 +145,6 @@ export      TEXT_OFFSET
> >
> >  core-y         += arch/arm64/
> >  libs-y         := arch/arm64/lib/ $(libs-y)
> > -core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
> >
> >  # Default target when executing plain make
> >  boot           := arch/arm64/boot
> > diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
> > index 7a216984552b..317a05cd388b 100644
> > --- a/drivers/firmware/efi/Makefile
> > +++ b/drivers/firmware/efi/Makefile
> > @@ -20,7 +20,7 @@ obj-$(CONFIG_EFI_VARS_PSTORE)         += efi-pstore.o
> >  obj-$(CONFIG_UEFI_CPER)                        += cper.o
> >  obj-$(CONFIG_EFI_RUNTIME_MAP)          += runtime-map.o
> >  obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)     += runtime-wrappers.o
> > -subdir-$(CONFIG_EFI_STUB)              += libstub
> > +obj-$(CONFIG_EFI_STUB)                 += libstub/
> >  obj-$(CONFIG_EFI_FAKE_MEMMAP)          += fake_map.o
> >  obj-$(CONFIG_EFI_BOOTLOADER_CONTROL)   += efibc.o
> >  obj-$(CONFIG_EFI_TEST)                 += test/
> > diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
> > index cce4a7436052..e4e9b17fa3b2 100644
> > --- a/drivers/firmware/efi/libstub/Makefile
> > +++ b/drivers/firmware/efi/libstub/Makefile
> > @@ -44,7 +44,7 @@ OBJECT_FILES_NON_STANDARD     := y
> >  # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
> >  KCOV_INSTRUMENT                        := n
> >
> > -lib-y                          := efi-stub-helper.o gop.o secureboot.o tpm.o \
> > +stub-obj-y                     := efi-stub-helper.o gop.o secureboot.o tpm.o \
> >                                    file.o mem.o random.o randomalloc.o pci.o \
> >                                    skip_spaces.o lib-cmdline.o lib-ctype.o \
> >                                    alignedmem.o relocate.o vsprintf.o
> > @@ -55,15 +55,19 @@ efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
> >  $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
> >         $(call if_changed_rule,cc_o_c)
> >
> > -lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o fdt.o string.o \
> > +stub-obj-$(CONFIG_EFI_GENERIC_STUB)    += efi-stub.o fdt.o string.o \
> >                                    $(patsubst %.c,lib-%.o,$(efi-deps-y))
> >
> > -lib-$(CONFIG_ARM)              += arm32-stub.o
> > -lib-$(CONFIG_ARM64)            += arm64-stub.o
> > -lib-$(CONFIG_X86)              += x86-stub.o
> > +stub-obj-$(CONFIG_ARM)         += arm32-stub.o
> > +stub-obj-$(CONFIG_ARM64)       += arm64-stub.o
> > +stub-obj-$(CONFIG_X86)         += x86-stub.o
> >  CFLAGS_arm32-stub.o            := -DTEXT_OFFSET=$(TEXT_OFFSET)
> >  CFLAGS_arm64-stub.o            := -DTEXT_OFFSET=$(TEXT_OFFSET)
> >
> > +targets                                += $(stub-obj-y)
> > +stub-obj-y                     := $(patsubst %.o,%.stub.o, $(stub-obj-y))
> > +targets                                += $(stub-obj-y)
> > +
> >  #
> >  # For x86, bootloaders like systemd-boot or grub-efi do not zero-initialize the
> >  # .bss section, so the .bss section of the EFI stub needs to be included in the
> > @@ -83,23 +87,6 @@ STUBCOPY_FLAGS-$(CONFIG_ARM) += --rename-section .data=.data.efistub \
> >                                    --rename-section .bss=.bss.efistub,load,alloc
> >  STUBCOPY_RELOC-$(CONFIG_ARM)   := R_ARM_ABS
> >
> > -#
> > -# arm64 puts the stub in the kernel proper, which will unnecessarily retain all
> > -# code indefinitely unless it is annotated as __init/__initdata/__initconst etc.
> > -# So let's apply the __init annotations at the section level, by prefixing
> > -# the section names directly. This will ensure that even all the inline string
> > -# literals are covered.
> > -# The fact that the stub and the kernel proper are essentially the same binary
> > -# also means that we need to be extra careful to make sure that the stub does
> > -# not rely on any absolute symbol references, considering that the virtual
> > -# kernel mapping that the linker uses is not active yet when the stub is
> > -# executing. So build all C dependencies of the EFI stub into libstub, and do
> > -# a verification pass to see if any absolute relocations exist in any of the
> > -# object files.
> > -#
> > -extra-y                                := $(lib-y)
> > -lib-y                          := $(patsubst %.o,%.stub.o,$(lib-y))
> > -
> >  STUBCOPY_FLAGS-$(CONFIG_ARM64) += --prefix-alloc-sections=.init \
> >                                    --prefix-symbols=__efistub_
> >  STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS
> > @@ -121,3 +108,23 @@ quiet_cmd_stubcopy = STUBCPY $@
> >                 /bin/false;                                             \
> >         fi;                                                             \
> >         $(OBJCOPY) $(STUBCOPY_FLAGS-y) $< $@
> > +
> > +# arm64 puts the stub in the kernel proper, which will unnecessarily retain all
> > +# code indefinitely unless it is annotated as __init/__initdata/__initconst etc.
> > +# So let's apply the __init annotations at the section level, by prefixing
> > +# the section names directly. This will ensure that even all the inline string
> > +# literals are covered.
> > +# The fact that the stub and the kernel proper are essentially the same binary
> > +# also means that we need to be extra careful to make sure that the stub does
> > +# not rely on any absolute symbol references, considering that the virtual
> > +# kernel mapping that the linker uses is not active yet when the stub is
> > +# executing. So build all C dependencies of the EFI stub into libstub, and do
> > +# a verification pass to see if any absolute relocations exist in any of the
> > +# object files.
> > +#
> > +obj-$(CONFIG_ARM64)            += $(stub-obj-y)
> > +extra-$(CONFIG_ARM)            += lib.a
> > +extra-$(CONFIG_X86)            += lib.a
> > +
> > +$(obj)/lib.a: $(addprefix $(obj)/, $(stub-obj-y)) FORCE
> > +       $(call if_changed,ar)
> > --
> > 2.25.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Ard Biesheuvel June 3, 2020, 8:45 a.m. UTC | #3
On Wed, 3 Jun 2020 at 10:36, Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> On Wed, Jun 3, 2020 at 3:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Wed, 3 Jun 2020 at 07:34, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > >
> > > Documentation/kbuild/makefiles.rst says:
> > >
> > >   Use of lib-y is normally restricted to `lib/` and `arch/*/lib`.
> > >
> > > I want to disallow lib-y outside of them.
> > >
> >
> > Why?
>
>
> Because I plan to remove lib-y entirely at some point.
>
> lib-y is not so useful to shrink the image size because:
>
>   - An object in lib.a can be omitted only when no symbol
>     in that object is referenced.  This rarely happens.
>
>   -  lib-y objects are often exported by nature
>      because lib-y is a collection of utility functions.
>      Even if no in-tree user, we always need to keep them
>      because EXPORT_SYMBOL() is the interface to modules.
>
>
> When I worked on commit 7273ad2b08f8ac9563579d16a3cf528857b26f49,
> I made some research.
>
> The benefit of lib-y is just 362 byte for x86_64_defconfig.
> ( Before: 26578002, After: 26578364)
>
> My hope is lib-y will be replaced by dead-code elimination or
> ultimately by LTO.
>
> drivers/firmware/efi/libstub/Makefile
> is the only Makefile that breaks the rule:
> "Use of lib-y is normally restricted to `lib/` and `arch/*/lib`"
>
>
>
>
> >
> > > Add a custom rule to build lib.a, which is linked to the decompressor
> > > for ARCH=x86, ARCH=arm.
> > >
> > > For ARCH=arm64, use obj-y to link objects to vmlinux in the ordinary
> > > way.
> > >
> >
> > The code works perfectly fine as is, and I don't see what is
> > fundamentally wrong with using static libraries outside of lib/ and
> > arch/*/lib.
>
> The intended usage of lib-y is to hook lib.a
> to scripts/vmlinux.sh via KBUILD_VMLINUX_LIBS.
>
> This Makefile is just what you found to work.
>
>
> >
> > Also, I would like this code to still be incorporated as a static
> > library into arm64 as well, so that only pieces that are actually
> > needed are incorporated into the final image.
>
> No.
> It is not working like that because you set
> lib.a to core-y.
>
> All objects in core-y are always linked to vmlinux.
>

The lib.a file is passed to the linker as a static library, so it will
only grab what it needs.

For instance, if you build arm64 from mainline today, the
efi_relocate_kernel will not be in the final image, even though it is
built as part of libstub
Masahiro Yamada June 3, 2020, 8:59 a.m. UTC | #4
On Wed, Jun 3, 2020 at 5:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Wed, 3 Jun 2020 at 10:36, Masahiro Yamada <masahiroy@kernel.org> wrote:
> >
> > On Wed, Jun 3, 2020 at 3:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Wed, 3 Jun 2020 at 07:34, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > >
> > > > Documentation/kbuild/makefiles.rst says:
> > > >
> > > >   Use of lib-y is normally restricted to `lib/` and `arch/*/lib`.
> > > >
> > > > I want to disallow lib-y outside of them.
> > > >
> > >
> > > Why?
> >
> >
> > Because I plan to remove lib-y entirely at some point.
> >
> > lib-y is not so useful to shrink the image size because:
> >
> >   - An object in lib.a can be omitted only when no symbol
> >     in that object is referenced.  This rarely happens.
> >
> >   -  lib-y objects are often exported by nature
> >      because lib-y is a collection of utility functions.
> >      Even if no in-tree user, we always need to keep them
> >      because EXPORT_SYMBOL() is the interface to modules.
> >
> >
> > When I worked on commit 7273ad2b08f8ac9563579d16a3cf528857b26f49,
> > I made some research.
> >
> > The benefit of lib-y is just 362 byte for x86_64_defconfig.
> > ( Before: 26578002, After: 26578364)
> >
> > My hope is lib-y will be replaced by dead-code elimination or
> > ultimately by LTO.
> >
> > drivers/firmware/efi/libstub/Makefile
> > is the only Makefile that breaks the rule:
> > "Use of lib-y is normally restricted to `lib/` and `arch/*/lib`"
> >
> >
> >
> >
> > >
> > > > Add a custom rule to build lib.a, which is linked to the decompressor
> > > > for ARCH=x86, ARCH=arm.
> > > >
> > > > For ARCH=arm64, use obj-y to link objects to vmlinux in the ordinary
> > > > way.
> > > >
> > >
> > > The code works perfectly fine as is, and I don't see what is
> > > fundamentally wrong with using static libraries outside of lib/ and
> > > arch/*/lib.
> >
> > The intended usage of lib-y is to hook lib.a
> > to scripts/vmlinux.sh via KBUILD_VMLINUX_LIBS.
> >
> > This Makefile is just what you found to work.
> >
> >
> > >
> > > Also, I would like this code to still be incorporated as a static
> > > library into arm64 as well, so that only pieces that are actually
> > > needed are incorporated into the final image.
> >
> > No.
> > It is not working like that because you set
> > lib.a to core-y.
> >
> > All objects in core-y are always linked to vmlinux.
> >
>
> The lib.a file is passed to the linker as a static library, so it will
> only grab what it needs.
>
> For instance, if you build arm64 from mainline today, the
> efi_relocate_kernel will not be in the final image, even though it is
> built as part of libstub


I built today's mainline kernel
(d6f9469a03d832dcd17041ed67774ffb5f3e73b3).


I see it in vmlinux.


$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  defconfig
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  -j24
    ...
$ aarch64-linux-gnu-nm  -n  vmlinux | grep  efi_relocate_kernel
ffff8000114afb90 t __efistub_efi_relocate_kernel
Ard Biesheuvel June 3, 2020, 9:01 a.m. UTC | #5
On Wed, 3 Jun 2020 at 10:59, Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> On Wed, Jun 3, 2020 at 5:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Wed, 3 Jun 2020 at 10:36, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > >
> > > On Wed, Jun 3, 2020 at 3:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > On Wed, 3 Jun 2020 at 07:34, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > > >
> > > > > Documentation/kbuild/makefiles.rst says:
> > > > >
> > > > >   Use of lib-y is normally restricted to `lib/` and `arch/*/lib`.
> > > > >
> > > > > I want to disallow lib-y outside of them.
> > > > >
> > > >
> > > > Why?
> > >
> > >
> > > Because I plan to remove lib-y entirely at some point.
> > >
> > > lib-y is not so useful to shrink the image size because:
> > >
> > >   - An object in lib.a can be omitted only when no symbol
> > >     in that object is referenced.  This rarely happens.
> > >
> > >   -  lib-y objects are often exported by nature
> > >      because lib-y is a collection of utility functions.
> > >      Even if no in-tree user, we always need to keep them
> > >      because EXPORT_SYMBOL() is the interface to modules.
> > >
> > >
> > > When I worked on commit 7273ad2b08f8ac9563579d16a3cf528857b26f49,
> > > I made some research.
> > >
> > > The benefit of lib-y is just 362 byte for x86_64_defconfig.
> > > ( Before: 26578002, After: 26578364)
> > >
> > > My hope is lib-y will be replaced by dead-code elimination or
> > > ultimately by LTO.
> > >
> > > drivers/firmware/efi/libstub/Makefile
> > > is the only Makefile that breaks the rule:
> > > "Use of lib-y is normally restricted to `lib/` and `arch/*/lib`"
> > >
> > >
> > >
> > >
> > > >
> > > > > Add a custom rule to build lib.a, which is linked to the decompressor
> > > > > for ARCH=x86, ARCH=arm.
> > > > >
> > > > > For ARCH=arm64, use obj-y to link objects to vmlinux in the ordinary
> > > > > way.
> > > > >
> > > >
> > > > The code works perfectly fine as is, and I don't see what is
> > > > fundamentally wrong with using static libraries outside of lib/ and
> > > > arch/*/lib.
> > >
> > > The intended usage of lib-y is to hook lib.a
> > > to scripts/vmlinux.sh via KBUILD_VMLINUX_LIBS.
> > >
> > > This Makefile is just what you found to work.
> > >
> > >
> > > >
> > > > Also, I would like this code to still be incorporated as a static
> > > > library into arm64 as well, so that only pieces that are actually
> > > > needed are incorporated into the final image.
> > >
> > > No.
> > > It is not working like that because you set
> > > lib.a to core-y.
> > >
> > > All objects in core-y are always linked to vmlinux.
> > >
> >
> > The lib.a file is passed to the linker as a static library, so it will
> > only grab what it needs.
> >
> > For instance, if you build arm64 from mainline today, the
> > efi_relocate_kernel will not be in the final image, even though it is
> > built as part of libstub
>
>
> I built today's mainline kernel
> (d6f9469a03d832dcd17041ed67774ffb5f3e73b3).
>
>
> I see it in vmlinux.
>
>
> $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  defconfig
> $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  -j24
>     ...
> $ aarch64-linux-gnu-nm  -n  vmlinux | grep  efi_relocate_kernel
> ffff8000114afb90 t __efistub_efi_relocate_kernel
>

That is strange. I tested this before, and it worked.

Did anything change recently in the way the linker is invoked?
Masahiro Yamada June 3, 2020, 9:14 a.m. UTC | #6
On Wed, Jun 3, 2020 at 6:02 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Wed, 3 Jun 2020 at 10:59, Masahiro Yamada <masahiroy@kernel.org> wrote:
> >
> > On Wed, Jun 3, 2020 at 5:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Wed, 3 Jun 2020 at 10:36, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > >
> > > > On Wed, Jun 3, 2020 at 3:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > >
> > > > > On Wed, 3 Jun 2020 at 07:34, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > > > >
> > > > > > Documentation/kbuild/makefiles.rst says:
> > > > > >
> > > > > >   Use of lib-y is normally restricted to `lib/` and `arch/*/lib`.
> > > > > >
> > > > > > I want to disallow lib-y outside of them.
> > > > > >
> > > > >
> > > > > Why?
> > > >
> > > >
> > > > Because I plan to remove lib-y entirely at some point.
> > > >
> > > > lib-y is not so useful to shrink the image size because:
> > > >
> > > >   - An object in lib.a can be omitted only when no symbol
> > > >     in that object is referenced.  This rarely happens.
> > > >
> > > >   -  lib-y objects are often exported by nature
> > > >      because lib-y is a collection of utility functions.
> > > >      Even if no in-tree user, we always need to keep them
> > > >      because EXPORT_SYMBOL() is the interface to modules.
> > > >
> > > >
> > > > When I worked on commit 7273ad2b08f8ac9563579d16a3cf528857b26f49,
> > > > I made some research.
> > > >
> > > > The benefit of lib-y is just 362 byte for x86_64_defconfig.
> > > > ( Before: 26578002, After: 26578364)
> > > >
> > > > My hope is lib-y will be replaced by dead-code elimination or
> > > > ultimately by LTO.
> > > >
> > > > drivers/firmware/efi/libstub/Makefile
> > > > is the only Makefile that breaks the rule:
> > > > "Use of lib-y is normally restricted to `lib/` and `arch/*/lib`"
> > > >
> > > >
> > > >
> > > >
> > > > >
> > > > > > Add a custom rule to build lib.a, which is linked to the decompressor
> > > > > > for ARCH=x86, ARCH=arm.
> > > > > >
> > > > > > For ARCH=arm64, use obj-y to link objects to vmlinux in the ordinary
> > > > > > way.
> > > > > >
> > > > >
> > > > > The code works perfectly fine as is, and I don't see what is
> > > > > fundamentally wrong with using static libraries outside of lib/ and
> > > > > arch/*/lib.
> > > >
> > > > The intended usage of lib-y is to hook lib.a
> > > > to scripts/vmlinux.sh via KBUILD_VMLINUX_LIBS.
> > > >
> > > > This Makefile is just what you found to work.
> > > >
> > > >
> > > > >
> > > > > Also, I would like this code to still be incorporated as a static
> > > > > library into arm64 as well, so that only pieces that are actually
> > > > > needed are incorporated into the final image.
> > > >
> > > > No.
> > > > It is not working like that because you set
> > > > lib.a to core-y.
> > > >
> > > > All objects in core-y are always linked to vmlinux.
> > > >
> > >
> > > The lib.a file is passed to the linker as a static library, so it will
> > > only grab what it needs.
> > >
> > > For instance, if you build arm64 from mainline today, the
> > > efi_relocate_kernel will not be in the final image, even though it is
> > > built as part of libstub
> >
> >
> > I built today's mainline kernel
> > (d6f9469a03d832dcd17041ed67774ffb5f3e73b3).
> >
> >
> > I see it in vmlinux.
> >
> >
> > $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  defconfig
> > $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  -j24
> >     ...
> > $ aarch64-linux-gnu-nm  -n  vmlinux | grep  efi_relocate_kernel
> > ffff8000114afb90 t __efistub_efi_relocate_kernel
> >
>
> That is strange. I tested this before, and it worked.
>
> Did anything change recently in the way the linker is invoked?


Nothing recently.

This is obvious result because
drivers/firmware/efi/libstub/lib.a
is passed after ----whole-archive flag.


I guess the following commit is it,
but it is already 3 years ago.



commit 799c43415442414b1032580c47684cb709dfed6d (HEAD)
Author: Nicholas Piggin <npiggin@gmail.com>
Date:   Fri Jun 9 15:24:17 2017 +1000

    kbuild: thin archives make default for all archs

    Make thin archives build the default, but keep the config option
    to allow exemptions if any breakage can't be quickly solved.

    Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
    Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Ard Biesheuvel June 3, 2020, 9:16 a.m. UTC | #7
On Wed, 3 Jun 2020 at 11:15, Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> On Wed, Jun 3, 2020 at 6:02 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Wed, 3 Jun 2020 at 10:59, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > >
> > > On Wed, Jun 3, 2020 at 5:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > On Wed, 3 Jun 2020 at 10:36, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > > >
> > > > > On Wed, Jun 3, 2020 at 3:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > >
> > > > > > On Wed, 3 Jun 2020 at 07:34, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > > > > >
> > > > > > > Documentation/kbuild/makefiles.rst says:
> > > > > > >
> > > > > > >   Use of lib-y is normally restricted to `lib/` and `arch/*/lib`.
> > > > > > >
> > > > > > > I want to disallow lib-y outside of them.
> > > > > > >
> > > > > >
> > > > > > Why?
> > > > >
> > > > >
> > > > > Because I plan to remove lib-y entirely at some point.
> > > > >
> > > > > lib-y is not so useful to shrink the image size because:
> > > > >
> > > > >   - An object in lib.a can be omitted only when no symbol
> > > > >     in that object is referenced.  This rarely happens.
> > > > >
> > > > >   -  lib-y objects are often exported by nature
> > > > >      because lib-y is a collection of utility functions.
> > > > >      Even if no in-tree user, we always need to keep them
> > > > >      because EXPORT_SYMBOL() is the interface to modules.
> > > > >
> > > > >
> > > > > When I worked on commit 7273ad2b08f8ac9563579d16a3cf528857b26f49,
> > > > > I made some research.
> > > > >
> > > > > The benefit of lib-y is just 362 byte for x86_64_defconfig.
> > > > > ( Before: 26578002, After: 26578364)
> > > > >
> > > > > My hope is lib-y will be replaced by dead-code elimination or
> > > > > ultimately by LTO.
> > > > >
> > > > > drivers/firmware/efi/libstub/Makefile
> > > > > is the only Makefile that breaks the rule:
> > > > > "Use of lib-y is normally restricted to `lib/` and `arch/*/lib`"
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > >
> > > > > > > Add a custom rule to build lib.a, which is linked to the decompressor
> > > > > > > for ARCH=x86, ARCH=arm.
> > > > > > >
> > > > > > > For ARCH=arm64, use obj-y to link objects to vmlinux in the ordinary
> > > > > > > way.
> > > > > > >
> > > > > >
> > > > > > The code works perfectly fine as is, and I don't see what is
> > > > > > fundamentally wrong with using static libraries outside of lib/ and
> > > > > > arch/*/lib.
> > > > >
> > > > > The intended usage of lib-y is to hook lib.a
> > > > > to scripts/vmlinux.sh via KBUILD_VMLINUX_LIBS.
> > > > >
> > > > > This Makefile is just what you found to work.
> > > > >
> > > > >
> > > > > >
> > > > > > Also, I would like this code to still be incorporated as a static
> > > > > > library into arm64 as well, so that only pieces that are actually
> > > > > > needed are incorporated into the final image.
> > > > >
> > > > > No.
> > > > > It is not working like that because you set
> > > > > lib.a to core-y.
> > > > >
> > > > > All objects in core-y are always linked to vmlinux.
> > > > >
> > > >
> > > > The lib.a file is passed to the linker as a static library, so it will
> > > > only grab what it needs.
> > > >
> > > > For instance, if you build arm64 from mainline today, the
> > > > efi_relocate_kernel will not be in the final image, even though it is
> > > > built as part of libstub
> > >
> > >
> > > I built today's mainline kernel
> > > (d6f9469a03d832dcd17041ed67774ffb5f3e73b3).
> > >
> > >
> > > I see it in vmlinux.
> > >
> > >
> > > $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  defconfig
> > > $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  -j24
> > >     ...
> > > $ aarch64-linux-gnu-nm  -n  vmlinux | grep  efi_relocate_kernel
> > > ffff8000114afb90 t __efistub_efi_relocate_kernel
> > >
> >
> > That is strange. I tested this before, and it worked.
> >
> > Did anything change recently in the way the linker is invoked?
>
>
> Nothing recently.
>
> This is obvious result because
> drivers/firmware/efi/libstub/lib.a
> is passed after ----whole-archive flag.
>
>
> I guess the following commit is it,
> but it is already 3 years ago.
>

Right.

So that means there is no point at all in using static libraries, no?
Or does --whole-archive still allow duplicate definitions like static
libraries do usually?
Masahiro Yamada June 3, 2020, 11:22 a.m. UTC | #8
On Wed, Jun 3, 2020 at 6:16 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Wed, 3 Jun 2020 at 11:15, Masahiro Yamada <masahiroy@kernel.org> wrote:
> >
> > On Wed, Jun 3, 2020 at 6:02 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Wed, 3 Jun 2020 at 10:59, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > >
> > > > On Wed, Jun 3, 2020 at 5:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > >
> > > > > On Wed, 3 Jun 2020 at 10:36, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > > > >
> > > > > > On Wed, Jun 3, 2020 at 3:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > >
> > > > > > > On Wed, 3 Jun 2020 at 07:34, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > > > > > >
> > > > > > > > Documentation/kbuild/makefiles.rst says:
> > > > > > > >
> > > > > > > >   Use of lib-y is normally restricted to `lib/` and `arch/*/lib`.
> > > > > > > >
> > > > > > > > I want to disallow lib-y outside of them.
> > > > > > > >
> > > > > > >
> > > > > > > Why?
> > > > > >
> > > > > >
> > > > > > Because I plan to remove lib-y entirely at some point.
> > > > > >
> > > > > > lib-y is not so useful to shrink the image size because:
> > > > > >
> > > > > >   - An object in lib.a can be omitted only when no symbol
> > > > > >     in that object is referenced.  This rarely happens.
> > > > > >
> > > > > >   -  lib-y objects are often exported by nature
> > > > > >      because lib-y is a collection of utility functions.
> > > > > >      Even if no in-tree user, we always need to keep them
> > > > > >      because EXPORT_SYMBOL() is the interface to modules.
> > > > > >
> > > > > >
> > > > > > When I worked on commit 7273ad2b08f8ac9563579d16a3cf528857b26f49,
> > > > > > I made some research.
> > > > > >
> > > > > > The benefit of lib-y is just 362 byte for x86_64_defconfig.
> > > > > > ( Before: 26578002, After: 26578364)
> > > > > >
> > > > > > My hope is lib-y will be replaced by dead-code elimination or
> > > > > > ultimately by LTO.
> > > > > >
> > > > > > drivers/firmware/efi/libstub/Makefile
> > > > > > is the only Makefile that breaks the rule:
> > > > > > "Use of lib-y is normally restricted to `lib/` and `arch/*/lib`"
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > >
> > > > > > > > Add a custom rule to build lib.a, which is linked to the decompressor
> > > > > > > > for ARCH=x86, ARCH=arm.
> > > > > > > >
> > > > > > > > For ARCH=arm64, use obj-y to link objects to vmlinux in the ordinary
> > > > > > > > way.
> > > > > > > >
> > > > > > >
> > > > > > > The code works perfectly fine as is, and I don't see what is
> > > > > > > fundamentally wrong with using static libraries outside of lib/ and
> > > > > > > arch/*/lib.
> > > > > >
> > > > > > The intended usage of lib-y is to hook lib.a
> > > > > > to scripts/vmlinux.sh via KBUILD_VMLINUX_LIBS.
> > > > > >
> > > > > > This Makefile is just what you found to work.
> > > > > >
> > > > > >
> > > > > > >
> > > > > > > Also, I would like this code to still be incorporated as a static
> > > > > > > library into arm64 as well, so that only pieces that are actually
> > > > > > > needed are incorporated into the final image.
> > > > > >
> > > > > > No.
> > > > > > It is not working like that because you set
> > > > > > lib.a to core-y.
> > > > > >
> > > > > > All objects in core-y are always linked to vmlinux.
> > > > > >
> > > > >
> > > > > The lib.a file is passed to the linker as a static library, so it will
> > > > > only grab what it needs.
> > > > >
> > > > > For instance, if you build arm64 from mainline today, the
> > > > > efi_relocate_kernel will not be in the final image, even though it is
> > > > > built as part of libstub
> > > >
> > > >
> > > > I built today's mainline kernel
> > > > (d6f9469a03d832dcd17041ed67774ffb5f3e73b3).
> > > >
> > > >
> > > > I see it in vmlinux.
> > > >
> > > >
> > > > $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  defconfig
> > > > $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  -j24
> > > >     ...
> > > > $ aarch64-linux-gnu-nm  -n  vmlinux | grep  efi_relocate_kernel
> > > > ffff8000114afb90 t __efistub_efi_relocate_kernel
> > > >
> > >
> > > That is strange. I tested this before, and it worked.
> > >
> > > Did anything change recently in the way the linker is invoked?
> >
> >
> > Nothing recently.
> >
> > This is obvious result because
> > drivers/firmware/efi/libstub/lib.a
> > is passed after ----whole-archive flag.
> >
> >
> > I guess the following commit is it,
> > but it is already 3 years ago.
> >
>
> Right.
>
> So that means there is no point at all in using static libraries, no?
> Or does --whole-archive still allow duplicate definitions like static
> libraries do usually?


--whole-archive literally links the whole of the archive.
If there are duplicate definitions, the linking fails
due to multiple definition.
So, --whole-archive is similar to linking .o files
in this regard.


There is a point for arm and x86 because
the decompressor link does not use --whole-archive.

As for arm64, there is no point,
but you can pass lib.a after --no-whole-archive
by the following patch.

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 650e1185c190..48a6afa774fc 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -145,7 +145,7 @@ export      TEXT_OFFSET

 core-y         += arch/arm64/
 libs-y         := arch/arm64/lib/ $(libs-y)
-core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
+libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a

 # Default target when executing plain make
 boot           := arch/arm64/boot



Then, _efistub_efi_low_alloc_above
and __efistub_efi_relocate_kernel will be dropped.


If you like the static library
do you want me to send v2?
Ard Biesheuvel June 3, 2020, 12:42 p.m. UTC | #9
On Wed, 3 Jun 2020 at 13:23, Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> On Wed, Jun 3, 2020 at 6:16 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Wed, 3 Jun 2020 at 11:15, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > >
> > > On Wed, Jun 3, 2020 at 6:02 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > On Wed, 3 Jun 2020 at 10:59, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > > >
> > > > > On Wed, Jun 3, 2020 at 5:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > >
> > > > > > On Wed, 3 Jun 2020 at 10:36, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > > > > >
> > > > > > > On Wed, Jun 3, 2020 at 3:45 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Wed, 3 Jun 2020 at 07:34, Masahiro Yamada <masahiroy@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > Documentation/kbuild/makefiles.rst says:
> > > > > > > > >
> > > > > > > > >   Use of lib-y is normally restricted to `lib/` and `arch/*/lib`.
> > > > > > > > >
> > > > > > > > > I want to disallow lib-y outside of them.
> > > > > > > > >
> > > > > > > >
> > > > > > > > Why?
> > > > > > >
> > > > > > >
> > > > > > > Because I plan to remove lib-y entirely at some point.
> > > > > > >
> > > > > > > lib-y is not so useful to shrink the image size because:
> > > > > > >
> > > > > > >   - An object in lib.a can be omitted only when no symbol
> > > > > > >     in that object is referenced.  This rarely happens.
> > > > > > >
> > > > > > >   -  lib-y objects are often exported by nature
> > > > > > >      because lib-y is a collection of utility functions.
> > > > > > >      Even if no in-tree user, we always need to keep them
> > > > > > >      because EXPORT_SYMBOL() is the interface to modules.
> > > > > > >
> > > > > > >
> > > > > > > When I worked on commit 7273ad2b08f8ac9563579d16a3cf528857b26f49,
> > > > > > > I made some research.
> > > > > > >
> > > > > > > The benefit of lib-y is just 362 byte for x86_64_defconfig.
> > > > > > > ( Before: 26578002, After: 26578364)
> > > > > > >
> > > > > > > My hope is lib-y will be replaced by dead-code elimination or
> > > > > > > ultimately by LTO.
> > > > > > >
> > > > > > > drivers/firmware/efi/libstub/Makefile
> > > > > > > is the only Makefile that breaks the rule:
> > > > > > > "Use of lib-y is normally restricted to `lib/` and `arch/*/lib`"
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > >
> > > > > > > > > Add a custom rule to build lib.a, which is linked to the decompressor
> > > > > > > > > for ARCH=x86, ARCH=arm.
> > > > > > > > >
> > > > > > > > > For ARCH=arm64, use obj-y to link objects to vmlinux in the ordinary
> > > > > > > > > way.
> > > > > > > > >
> > > > > > > >
> > > > > > > > The code works perfectly fine as is, and I don't see what is
> > > > > > > > fundamentally wrong with using static libraries outside of lib/ and
> > > > > > > > arch/*/lib.
> > > > > > >
> > > > > > > The intended usage of lib-y is to hook lib.a
> > > > > > > to scripts/vmlinux.sh via KBUILD_VMLINUX_LIBS.
> > > > > > >
> > > > > > > This Makefile is just what you found to work.
> > > > > > >
> > > > > > >
> > > > > > > >
> > > > > > > > Also, I would like this code to still be incorporated as a static
> > > > > > > > library into arm64 as well, so that only pieces that are actually
> > > > > > > > needed are incorporated into the final image.
> > > > > > >
> > > > > > > No.
> > > > > > > It is not working like that because you set
> > > > > > > lib.a to core-y.
> > > > > > >
> > > > > > > All objects in core-y are always linked to vmlinux.
> > > > > > >
> > > > > >
> > > > > > The lib.a file is passed to the linker as a static library, so it will
> > > > > > only grab what it needs.
> > > > > >
> > > > > > For instance, if you build arm64 from mainline today, the
> > > > > > efi_relocate_kernel will not be in the final image, even though it is
> > > > > > built as part of libstub
> > > > >
> > > > >
> > > > > I built today's mainline kernel
> > > > > (d6f9469a03d832dcd17041ed67774ffb5f3e73b3).
> > > > >
> > > > >
> > > > > I see it in vmlinux.
> > > > >
> > > > >
> > > > > $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  defconfig
> > > > > $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-  -j24
> > > > >     ...
> > > > > $ aarch64-linux-gnu-nm  -n  vmlinux | grep  efi_relocate_kernel
> > > > > ffff8000114afb90 t __efistub_efi_relocate_kernel
> > > > >
> > > >
> > > > That is strange. I tested this before, and it worked.
> > > >
> > > > Did anything change recently in the way the linker is invoked?
> > >
> > >
> > > Nothing recently.
> > >
> > > This is obvious result because
> > > drivers/firmware/efi/libstub/lib.a
> > > is passed after ----whole-archive flag.
> > >
> > >
> > > I guess the following commit is it,
> > > but it is already 3 years ago.
> > >
> >
> > Right.
> >
> > So that means there is no point at all in using static libraries, no?
> > Or does --whole-archive still allow duplicate definitions like static
> > libraries do usually?
>
>
> --whole-archive literally links the whole of the archive.
> If there are duplicate definitions, the linking fails
> due to multiple definition.
> So, --whole-archive is similar to linking .o files
> in this regard.
>
>
> There is a point for arm and x86 because
> the decompressor link does not use --whole-archive.
>
> As for arm64, there is no point,
> but you can pass lib.a after --no-whole-archive
> by the following patch.
>
> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index 650e1185c190..48a6afa774fc 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -145,7 +145,7 @@ export      TEXT_OFFSET
>
>  core-y         += arch/arm64/
>  libs-y         := arch/arm64/lib/ $(libs-y)
> -core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
> +libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
>
>  # Default target when executing plain make
>  boot           := arch/arm64/boot
>
>
>
> Then, _efistub_efi_low_alloc_above
> and __efistub_efi_relocate_kernel will be dropped.
>
>
> If you like the static library
> do you want me to send v2?
>

Yes please
diff mbox series

Patch

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 650e1185c190..ab79b20efc8d 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -145,7 +145,6 @@  export	TEXT_OFFSET
 
 core-y		+= arch/arm64/
 libs-y		:= arch/arm64/lib/ $(libs-y)
-core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 
 # Default target when executing plain make
 boot		:= arch/arm64/boot
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 7a216984552b..317a05cd388b 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -20,7 +20,7 @@  obj-$(CONFIG_EFI_VARS_PSTORE)		+= efi-pstore.o
 obj-$(CONFIG_UEFI_CPER)			+= cper.o
 obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
 obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)	+= runtime-wrappers.o
-subdir-$(CONFIG_EFI_STUB)		+= libstub
+obj-$(CONFIG_EFI_STUB)			+= libstub/
 obj-$(CONFIG_EFI_FAKE_MEMMAP)		+= fake_map.o
 obj-$(CONFIG_EFI_BOOTLOADER_CONTROL)	+= efibc.o
 obj-$(CONFIG_EFI_TEST)			+= test/
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index cce4a7436052..e4e9b17fa3b2 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -44,7 +44,7 @@  OBJECT_FILES_NON_STANDARD	:= y
 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
 KCOV_INSTRUMENT			:= n
 
-lib-y				:= efi-stub-helper.o gop.o secureboot.o tpm.o \
+stub-obj-y			:= efi-stub-helper.o gop.o secureboot.o tpm.o \
 				   file.o mem.o random.o randomalloc.o pci.o \
 				   skip_spaces.o lib-cmdline.o lib-ctype.o \
 				   alignedmem.o relocate.o vsprintf.o
@@ -55,15 +55,19 @@  efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
 	$(call if_changed_rule,cc_o_c)
 
-lib-$(CONFIG_EFI_GENERIC_STUB)	+= efi-stub.o fdt.o string.o \
+stub-obj-$(CONFIG_EFI_GENERIC_STUB)	+= efi-stub.o fdt.o string.o \
 				   $(patsubst %.c,lib-%.o,$(efi-deps-y))
 
-lib-$(CONFIG_ARM)		+= arm32-stub.o
-lib-$(CONFIG_ARM64)		+= arm64-stub.o
-lib-$(CONFIG_X86)		+= x86-stub.o
+stub-obj-$(CONFIG_ARM)		+= arm32-stub.o
+stub-obj-$(CONFIG_ARM64)	+= arm64-stub.o
+stub-obj-$(CONFIG_X86)		+= x86-stub.o
 CFLAGS_arm32-stub.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 CFLAGS_arm64-stub.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 
+targets				+= $(stub-obj-y)
+stub-obj-y			:= $(patsubst %.o,%.stub.o, $(stub-obj-y))
+targets				+= $(stub-obj-y)
+
 #
 # For x86, bootloaders like systemd-boot or grub-efi do not zero-initialize the
 # .bss section, so the .bss section of the EFI stub needs to be included in the
@@ -83,23 +87,6 @@  STUBCOPY_FLAGS-$(CONFIG_ARM)	+= --rename-section .data=.data.efistub	\
 				   --rename-section .bss=.bss.efistub,load,alloc
 STUBCOPY_RELOC-$(CONFIG_ARM)	:= R_ARM_ABS
 
-#
-# arm64 puts the stub in the kernel proper, which will unnecessarily retain all
-# code indefinitely unless it is annotated as __init/__initdata/__initconst etc.
-# So let's apply the __init annotations at the section level, by prefixing
-# the section names directly. This will ensure that even all the inline string
-# literals are covered.
-# The fact that the stub and the kernel proper are essentially the same binary
-# also means that we need to be extra careful to make sure that the stub does
-# not rely on any absolute symbol references, considering that the virtual
-# kernel mapping that the linker uses is not active yet when the stub is
-# executing. So build all C dependencies of the EFI stub into libstub, and do
-# a verification pass to see if any absolute relocations exist in any of the
-# object files.
-#
-extra-y				:= $(lib-y)
-lib-y				:= $(patsubst %.o,%.stub.o,$(lib-y))
-
 STUBCOPY_FLAGS-$(CONFIG_ARM64)	+= --prefix-alloc-sections=.init \
 				   --prefix-symbols=__efistub_
 STUBCOPY_RELOC-$(CONFIG_ARM64)	:= R_AARCH64_ABS
@@ -121,3 +108,23 @@  quiet_cmd_stubcopy = STUBCPY $@
 		/bin/false;						\
 	fi;								\
 	$(OBJCOPY) $(STUBCOPY_FLAGS-y) $< $@
+
+# arm64 puts the stub in the kernel proper, which will unnecessarily retain all
+# code indefinitely unless it is annotated as __init/__initdata/__initconst etc.
+# So let's apply the __init annotations at the section level, by prefixing
+# the section names directly. This will ensure that even all the inline string
+# literals are covered.
+# The fact that the stub and the kernel proper are essentially the same binary
+# also means that we need to be extra careful to make sure that the stub does
+# not rely on any absolute symbol references, considering that the virtual
+# kernel mapping that the linker uses is not active yet when the stub is
+# executing. So build all C dependencies of the EFI stub into libstub, and do
+# a verification pass to see if any absolute relocations exist in any of the
+# object files.
+#
+obj-$(CONFIG_ARM64)		+= $(stub-obj-y)
+extra-$(CONFIG_ARM)		+= lib.a
+extra-$(CONFIG_X86)		+= lib.a
+
+$(obj)/lib.a: $(addprefix $(obj)/, $(stub-obj-y)) FORCE
+	$(call if_changed,ar)