scripts/kallsyms: fix wrong kallsyms_relative_base
authorMikhail Petrov <Mikhail.Petrov@mir.dev>
Wed, 11 Mar 2020 20:37:09 +0000 (23:37 +0300)
committerMasahiro Yamada <masahiroy@kernel.org>
Thu, 19 Mar 2020 14:40:20 +0000 (23:40 +0900)
commit7883a14339299773b2ce08dcfd97c63c199a9289
tree5edb449474faa1d9d5d32d624025eea3c9a68e47
parent4b8a5cfb5fd375cf4c7502a18f0096ed2881be27
scripts/kallsyms: fix wrong kallsyms_relative_base

There is the code in the read_symbol function in 'scripts/kallsyms.c':

if (is_ignored_symbol(name, type))
return NULL;

/* Ignore most absolute/undefined (?) symbols. */
if (strcmp(name, "_text") == 0)
_text = addr;

But the is_ignored_symbol function returns true for name="_text" and
type='A'. So the next condition is not executed and the _text variable
is always zero.

It makes the wrong kallsyms_relative_base symbol as a result of the code
(CONFIG_KALLSYMS_BASE_RELATIVE is defined):

if (base_relative) {
output_label("kallsyms_relative_base");
output_address(relative_base);
printf("\n");
}

Because the output_address function uses the _text variable.

So the kallsyms_lookup function and all related functions in the kernel
do not work properly. For example, the stack trace in oops:

 Call Trace:
 [aa095e58] [809feab8] kobj_ns_ops_tbl+0x7ff09ac8/0x7ff1c1c4 (unreliable)
 [aa095e98] [80002b64] kobj_ns_ops_tbl+0x7f50db74/0x80000010
 [aa095ef8] [809c3d24] kobj_ns_ops_tbl+0x7feced34/0x7ff1c1c4
 [aa095f28] [80002ed0] kobj_ns_ops_tbl+0x7f50dee0/0x80000010
 [aa095f38] [8000f238] kobj_ns_ops_tbl+0x7f51a248/0x80000010

The right stack trace:

 Call Trace:
 [aa095e58] [809feab8] module_vdu_video_init+0x2fc/0x3bc (unreliable)
 [aa095e98] [80002b64] do_one_initcall+0x40/0x1f0
 [aa095ef8] [809c3d24] kernel_init_freeable+0x164/0x1d8
 [aa095f28] [80002ed0] kernel_init+0x14/0x124
 [aa095f38] [8000f238] ret_from_kernel_thread+0x14/0x1c

[masahiroy@kernel.org:

This issue happens on binutils <= 2.22
The following commit fixed it:
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d2667025dd30611514810c28bee9709e4623012a

The symbol type of _text is 'T' on binutils >= 2.23
The minimal supported binutils version for the kernel build is 2.21
]

Signed-off-by: Mikhail Petrov <Mikhail.Petrov@mir.dev>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
scripts/kallsyms.c