[v2] scripts/kallsyms: fix wrong kallsyms_relative_base
diff mbox series

Message ID 306f76fc-c445-6578-d4fe-5e462861920c@mir.dev
State New
Headers show
Series
  • [v2] scripts/kallsyms: fix wrong kallsyms_relative_base
Related show

Commit Message

Mikhail Petrov March 11, 2020, 8:37 p.m. UTC
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

Signed-off-by: Mikhail Petrov <Mikhail.Petrov@mir.dev>

---

Comments

Masahiro Yamada March 19, 2020, 8:15 a.m. UTC | #1
On Thu, Mar 12, 2020 at 5:37 AM Mikhail Petrov <Mikhail.Petrov@mir.dev> wrote:
>
> 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
>
> Signed-off-by: Mikhail Petrov <Mikhail.Petrov@mir.dev>



Applied with the following info:

[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 is 'T' on binutils >= 2.23
The current minimal supported binutils version is 2.21
]



Thanks.



> ---
>
> diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
> index 0133dfaaf352..3e8dea6e0a95 100644
> --- a/scripts/kallsyms.c
> +++ b/scripts/kallsyms.c
> @@ -195,13 +195,13 @@ static struct sym_entry *read_symbol(FILE *in)
>                 return NULL;
>         }
>
> -       if (is_ignored_symbol(name, type))
> -               return NULL;
> -
> -       /* Ignore most absolute/undefined (?) symbols. */
>         if (strcmp(name, "_text") == 0)
>                 _text = addr;
>
> +       /* Ignore most absolute/undefined (?) symbols. */
> +       if (is_ignored_symbol(name, type))
> +               return NULL;
> +
>         check_symbol_range(name, addr, text_ranges, ARRAY_SIZE(text_ranges));
>         check_symbol_range(name, addr, &percpu_range, 1);
>


--
Best Regards
Masahiro Yamada

Patch
diff mbox series

diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 0133dfaaf352..3e8dea6e0a95 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -195,13 +195,13 @@  static struct sym_entry *read_symbol(FILE *in)
 		return NULL;
 	}
 
-	if (is_ignored_symbol(name, type))
-		return NULL;
-
-	/* Ignore most absolute/undefined (?) symbols. */
 	if (strcmp(name, "_text") == 0)
 		_text = addr;
 
+	/* Ignore most absolute/undefined (?) symbols. */
+	if (is_ignored_symbol(name, type))
+		return NULL;
+
 	check_symbol_range(name, addr, text_ranges, ARRAY_SIZE(text_ranges));
 	check_symbol_range(name, addr, &percpu_range, 1);