lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 11 Mar 2009 17:37:03 +0800
From:	Lai Jiangshan <laijs@...fujitsu.com>
To:	Sam Ravnborg <sam@...nborg.org>, Ingo Molnar <mingo@...e.hu>,
	Andrew Morton <akpm@...l.org>,
	Steven Rostedt <srostedt@...hat.com>,
	Frederic Weisbecker <fweisbec@...il.com>,
	LKML <linux-kernel@...r.kernel.org>
Subject: [PATCH] kallsyms, tracing: output more proper symbol name


Impact: bugfix, output reliable result

Debug tools(dump_stack(), ftrace...) are like to print out symbols.
But it is always print out the first aliased symbol.(Aliased symbols
are symbols with the same address), and the first aliased symbol is
sometime not proper.

# echo function_graph > current_tracer
# cat trace
......
 1)   1.923 us    |    select_nohz_load_balancer();
 1) + 76.692 us   |  }
 1)               |  default_idle() {
 1)   ==========> |    __irqentry_text_start() {
 1)   0.000 us    |      native_apic_mem_write();
 1)               |      irq_enter() {
 1)   0.000 us    |        idle_cpu();
 1)               |        tick_check_idle() {
 1)   0.000 us    |          tick_check_oneshot_broadcast();
 1)               |          tick_nohz_stop_idle() {
......

It's very embarrassing, it ouputs "__irqentry_text_start()",
*actually, it should output "smp_apic_timer_interrupt()"*.
(these two symbol are the same address, but "__irqentry_text_start"
is deemed to the first aliased symbol by scripts/kallsyms)

This patch puts symbols like "__irqentry_text_start" to the second
aliased symbols. And a more proper symbol name becomes the first.

A table is added in scripts/kallsyms.c, and the symbols in this table
have lower priority than other symbols(which are the same address).

This table is statically defined in scripts/kallsyms.c, is not
automatically generated by a script when kernel is being built.
It's for these reasons:
	This table is(will be) updated very infrequently.
	This table is short.
	I don't want to add complexity to kernel-building

Signed-off-by: Lai Jiangshan <laijs@...fujitsu.com>
---
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index ad2434b..96717dd 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -500,11 +500,14 @@ static void optimize_token_table(void)
 	optimize_result();
 }
 
+static void prepare_hide_symbols(void);
+static int is_hide_symbol(const char *symbol);
+
 static int compare_symbols(const void *a, const void *b)
 {
 	const struct sym_entry *sa;
 	const struct sym_entry *sb;
-	int wa, wb;
+	int wa, wb, ha, hb;
 
 	sa = a;
 	sb = b;
@@ -521,12 +524,18 @@ static int compare_symbols(const void *a, const void *b)
 	if (wa != wb)
 		return wa - wb;
 
+	ha = is_hide_symbol((char *)sa->sym + 1);
+	hb = is_hide_symbol((char *)sb->sym + 1);
+	if (ha != hb)
+		return ha - hb;
+
 	/* sort by initial order, so that other symbols are left undisturbed */
 	return sa->start_pos - sb->start_pos;
 }
 
 static void sort_symbols(void)
 {
+	prepare_hide_symbols();
 	qsort(table, table_cnt, sizeof(struct sym_entry), compare_symbols);
 }
 
@@ -556,3 +565,125 @@ int main(int argc, char **argv)
 
 	return 0;
 }
+
+#define VMLINUX_SYMBOL(_sym_) #_sym_
+
+static const char *hide_symbols[] = {
+	/* misc symbols */
+	"_text",
+	"_stext",
+	"_etext",
+	"_sinittext",
+	"_einittext",
+
+	/* symbols from include/asm-generic/vmlinux.lds.h */
+	VMLINUX_SYMBOL(__start_mcount_loc),
+	VMLINUX_SYMBOL(__stop_mcount_loc),
+	VMLINUX_SYMBOL(__start_annotated_branch_profile),
+	VMLINUX_SYMBOL(__stop_annotated_branch_profile),
+	VMLINUX_SYMBOL(__start_branch_profile),
+	VMLINUX_SYMBOL(__stop_branch_profile),
+	VMLINUX_SYMBOL(__start___markers),
+	VMLINUX_SYMBOL(__stop___markers),
+	VMLINUX_SYMBOL(__start___tracepoints),
+	VMLINUX_SYMBOL(__stop___tracepoints),
+	VMLINUX_SYMBOL(__start_rodata),
+	VMLINUX_SYMBOL(__start_pci_fixups_early),
+	VMLINUX_SYMBOL(__end_pci_fixups_early),
+	VMLINUX_SYMBOL(__start_pci_fixups_header),
+	VMLINUX_SYMBOL(__end_pci_fixups_header),
+	VMLINUX_SYMBOL(__start_pci_fixups_final),
+	VMLINUX_SYMBOL(__end_pci_fixups_final),
+	VMLINUX_SYMBOL(__start_pci_fixups_enable),
+	VMLINUX_SYMBOL(__end_pci_fixups_enable),
+	VMLINUX_SYMBOL(__start_pci_fixups_resume),
+	VMLINUX_SYMBOL(__end_pci_fixups_resume),
+	VMLINUX_SYMBOL(__start_pci_fixups_resume_early),
+	VMLINUX_SYMBOL(__end_pci_fixups_resume_early),
+	VMLINUX_SYMBOL(__start_pci_fixups_suspend),
+	VMLINUX_SYMBOL(__end_pci_fixups_suspend),
+	VMLINUX_SYMBOL(__start_builtin_fw),
+	VMLINUX_SYMBOL(__end_builtin_fw),
+	VMLINUX_SYMBOL(__start_rio_route_ops),
+	VMLINUX_SYMBOL(__end_rio_route_ops),
+	VMLINUX_SYMBOL(__start___ksymtab),
+	VMLINUX_SYMBOL(__stop___ksymtab),
+	VMLINUX_SYMBOL(__start___ksymtab_gpl),
+	VMLINUX_SYMBOL(__stop___ksymtab_gpl),
+	VMLINUX_SYMBOL(__start___ksymtab_unused),
+	VMLINUX_SYMBOL(__stop___ksymtab_unused),
+	VMLINUX_SYMBOL(__start___ksymtab_unused_gpl),
+	VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl),
+	VMLINUX_SYMBOL(__start___ksymtab_gpl_future),
+	VMLINUX_SYMBOL(__stop___ksymtab_gpl_future),
+	VMLINUX_SYMBOL(__start___kcrctab),
+	VMLINUX_SYMBOL(__stop___kcrctab),
+	VMLINUX_SYMBOL(__start___kcrctab_gpl),
+	VMLINUX_SYMBOL(__stop___kcrctab_gpl),
+	VMLINUX_SYMBOL(__start___kcrctab_unused),
+	VMLINUX_SYMBOL(__stop___kcrctab_unused),
+	VMLINUX_SYMBOL(__start___kcrctab_unused_gpl),
+	VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl),
+	VMLINUX_SYMBOL(__start___kcrctab_gpl_future),
+	VMLINUX_SYMBOL(__stop___kcrctab_gpl_future),
+	VMLINUX_SYMBOL(__start___param),
+	VMLINUX_SYMBOL(__stop___param),
+	VMLINUX_SYMBOL(__end_rodata),
+	VMLINUX_SYMBOL(__security_initcall_start),
+	VMLINUX_SYMBOL(__security_initcall_end),
+	VMLINUX_SYMBOL(__sched_text_start),
+	VMLINUX_SYMBOL(__sched_text_end),
+	VMLINUX_SYMBOL(__lock_text_start),
+	VMLINUX_SYMBOL(__lock_text_end),
+	VMLINUX_SYMBOL(__kprobes_text_start),
+	VMLINUX_SYMBOL(__kprobes_text_end),
+	VMLINUX_SYMBOL(__irqentry_text_start),
+	VMLINUX_SYMBOL(__irqentry_text_end),
+	VMLINUX_SYMBOL(__start___verbose_strings),
+	VMLINUX_SYMBOL(__stop___verbose_strings),
+	VMLINUX_SYMBOL(__start___verbose),
+	VMLINUX_SYMBOL(__stop___verbose),
+	VMLINUX_SYMBOL(__start___bug_table),
+	VMLINUX_SYMBOL(__stop___bug_table),
+	VMLINUX_SYMBOL(__tracedata_start),
+	VMLINUX_SYMBOL(__tracedata_end),
+	VMLINUX_SYMBOL(__start_notes),
+	VMLINUX_SYMBOL(__stop_notes),
+	VMLINUX_SYMBOL(__early_initcall_end),
+	VMLINUX_SYMBOL(__per_cpu_start),
+	VMLINUX_SYMBOL(__per_cpu_end)
+};
+
+
+static int cmp_str(const void *p1, const void *p2)
+{
+	const char *str1 = *(const char * const *)p1;
+	const char *str2 = *(const char * const *)p2;
+
+	return strcmp(str1, str2);
+}
+
+static void prepare_hide_symbols(void)
+{
+	qsort(hide_symbols, sizeof(hide_symbols) / sizeof(hide_symbols[0]),
+			sizeof(hide_symbols[0]), cmp_str);
+}
+
+static int is_hide_symbol(const char *symbol)
+{
+	int low = 0;
+	int high = sizeof(hide_symbols) / sizeof(hide_symbols[0]);
+
+	while (high - low > 0) {
+		int mid = low + (high - low) / 2;
+		int eq = strcmp(hide_symbols[mid], symbol);
+		if (eq == 0)
+			return 1;
+		else if (eq < 0)
+			low = mid + 1;
+		else
+			high = mid;
+	}
+	return 0;
+}
+




--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ