Skip to content
  • Masahiro Yamada's avatar
    kbuild: link lib-y objects to vmlinux forcibly when CONFIG_MODULES=y · 7273ad2b
    Masahiro Yamada authored
    Kbuild supports not only obj-y but also lib-y to list objects linked to
    vmlinux.
    
    The difference between them is that all the objects from obj-y are
    forcibly linked to vmlinux, whereas the objects from lib-y are linked
    as needed; if there is no user of a lib-y object, it is not linked.
    
    lib-y is intended to list utility functions that may be called from all
    over the place (and may be unused at all), but it is a problem for
    EXPORT_SYMBOL(). Even if there is no call-site in the vmlinux, we need
    to keep exported symbols for the use from loadable modules.
    
    Commit 7f2084fa ("[kbuild] handle exports in lib-y objects reliably")
    worked around it by linking a dummy object, lib-ksyms.o, which contains
    references to all the symbols exported from lib.a in that directory.
    It uses the linker script command, EXTERN. Unfortunately, the meaning of
    EXTERN of ld.lld is different from that of ld.bfd. Therefore, this does
    not work with LD=ld.lld (CBL issue #515).
    
    Anyway, the build rule of lib-ksyms.o is somewhat tricky. So, I want to
    get rid of it.
    
    At first, I was thinking of accumulating lib-y objects into obj-y
    (or even replacing lib-y with obj-y entirely), but the lib-y syntax
    is used beyond the ordinary use in lib/ and arch/*/lib/.
    
    Examples:
    
     - drivers/firmware/efi/libstub/Makefile builds lib.a, which is linked
       into vmlinux in the own way (arm64), or linked to the decompressor
       (arm, x86).
    
     - arch/alpha/lib/Makefile builds lib.a which is linked not only to
       vmlinux, but also to bootloaders in arch/alpha/boot/Makefile.
    
     - arch/xtensa/boot/lib/Makefile builds lib.a for use from
       arch/xtensa/boot/boot-redboot/Makefile.
    
    One more thing, adding everything to obj-y would increase the vmlinux
    size of allnoconfig (or tinyconfig).
    
    For less impact, I tweaked the destination of lib.a at the top Makefile;
    when CONFIG_MODULES=y, lib.a goes to KBUILD_VMLINUX_OBJS, which is
    forcibly linked to vmlinux, otherwise lib.a goes to KBUILD_VMLINUX_LIBS
    as before.
    
    The size impact for normal usecases is quite small since at lease one
    symbol in every lib-y object is eventually called by someone. In case
    you are intrested, here are the figures.
    
    x86_64_defconfig:
    
       text	   data	    bss	    dec	    hex	filename
    19566602 5422072 1589328 26578002 1958c52 vmlinux.before
    19566932 5422104 1589328 26578364 1958dbc vmlinux.after
    
    The case with the biggest impact is allnoconfig + CONFIG_MODULES=y.
    
    ARCH=x86 allnoconfig + CONFIG_MODULES=y:
    
       text	   data	    bss	    dec	    hex	filename
    1175162	 254740	1220608	2650510	 28718e	vmlinux.before
    1177974	 254836	1220608	2653418	 287cea	vmlinux.after
    
    Hopefully this is still not a big deal. The per-file trimming with the
    static library is not so effective after all.
    
    If fine-grained optimization is desired, some architectures support
    CONFIG_LD_DEAD_CODE_DATA_ELIMINATION, which trims dead code per-symbol
    basis. When LTO is supported in mainline, even better optimization will
    be possible.
    
    Link: https://github.com/ClangBuiltLinux/linux/issues/515
    
    
    Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
    Reported-by: default avatarkbuild test robot <lkp@intel.com>
    Reviewed-by: default avatarNick Desaulniers <ndesaulniers@google.com>
    7273ad2b