Skip to content

Commit

Permalink
kbuild: add an elfnote for whether vmlinux is built with lto
Browse files Browse the repository at this point in the history
Currently, clang LTO built vmlinux won't work with pahole.
LTO introduced cross-cu dwarf tag references and broke
current pahole model which handles one cu as a time.
The solution is to merge all cu's as one pahole cu as in [1].
We would like to do this merging only if cross-cu dwarf
references happens. The LTO build mode is a pretty good
indication for that.

In earlier version of this patch ([2]), clang flag
-grecord-gcc-switches is proposed to add to compilation flags
so pahole could detect "-flto" and then merging cu's.
This will increate the binary size of 1% without LTO though.

Arnaldo suggested to use a note to indicate the vmlinux
is built with LTO. Such a cheap way to get whether the vmlinux
is built with LTO or not helps pahole but is also useful
for tracing as LTO may inline/delete/demote global functions,
promote static functions, etc.

So this patch added an elfnote with a new type LINUX_ELFNOTE_LTO_INFO.
The owner of the note is "Linux".

With gcc 8.4.1 and clang trunk, without LTO, I got
  $ readelf -n vmlinux
  Displaying notes found in: .notes
    Owner                Data size        Description
  ...
    Linux                0x00000004       func
     description data: 00 00 00 00
  ...
With "readelf -x ".notes" vmlinux", I can verify the above "func"
with type code 0x101.

With clang thin-LTO, I got the same as above except the following:
     description data: 01 00 00 00
which indicates the vmlinux is built with LTO.

  [1] https://lore.kernel.org/bpf/[email protected]/
  [2] https://lore.kernel.org/bpf/[email protected]/

Suggested-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Yonghong Song <[email protected]>
Reviewed-by: Nick Desaulniers <[email protected]>
Tested-by: Sedat Dilek <[email protected]> # LLVM/Clang v12.0.0-rc4 (x86-64)
Tested-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Masahiro Yamada <[email protected]>
  • Loading branch information
yonghong-song authored and masahir0y committed Apr 24, 2021
1 parent 6e74bc4 commit 1fdd743
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 0 deletions.
14 changes: 14 additions & 0 deletions include/linux/elfnote-lto.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef __ELFNOTE_LTO_H
#define __ELFNOTE_LTO_H

#include <linux/elfnote.h>

#define LINUX_ELFNOTE_LTO_INFO 0x101

#ifdef CONFIG_LTO
#define BUILD_LTO_INFO ELFNOTE32("Linux", LINUX_ELFNOTE_LTO_INFO, 1)
#else
#define BUILD_LTO_INFO ELFNOTE32("Linux", LINUX_ELFNOTE_LTO_INFO, 0)
#endif

#endif /* __ELFNOTE_LTO_H */
2 changes: 2 additions & 0 deletions init/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <generated/compile.h>
#include <linux/build-salt.h>
#include <linux/elfnote-lto.h>
#include <linux/export.h>
#include <linux/uts.h>
#include <linux/utsname.h>
Expand Down Expand Up @@ -45,3 +46,4 @@ const char linux_proc_banner[] =
" (" LINUX_COMPILER ") %s\n";

BUILD_SALT;
BUILD_LTO_INFO;
2 changes: 2 additions & 0 deletions scripts/mod/modpost.c
Original file line number Diff line number Diff line change
Expand Up @@ -2193,10 +2193,12 @@ static void add_header(struct buffer *b, struct module *mod)
*/
buf_printf(b, "#define INCLUDE_VERMAGIC\n");
buf_printf(b, "#include <linux/build-salt.h>\n");
buf_printf(b, "#include <linux/elfnote-lto.h>\n");
buf_printf(b, "#include <linux/vermagic.h>\n");
buf_printf(b, "#include <linux/compiler.h>\n");
buf_printf(b, "\n");
buf_printf(b, "BUILD_SALT;\n");
buf_printf(b, "BUILD_LTO_INFO;\n");
buf_printf(b, "\n");
buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
Expand Down

0 comments on commit 1fdd743

Please sign in to comment.