The following commit has been merged into the x86/core branch of tip:
Commit-ID: f1389181622a08d6f1c71407a64df36b809d632b
Gitweb: https://git.kernel.org/tip/f1389181622a08d6f1c71407a64df36b809d632b
Author: Peter Zijlstra <peterz@infradead.org>
AuthorDate: Thu, 15 Sep 2022 13:11:32 +02:00
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Mon, 17 Oct 2022 16:41:17 +02:00
kallsyms: Take callthunks into account
Since the pre-symbol function padding is an integral part of the
symbol make kallsyms report it as part of the symbol by reporting it
as sym-x instead of prev_sym+y.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220915111148.409656012@infradead.org
---
kernel/kallsyms.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 40 insertions(+), 5 deletions(-)
@@ -293,6 +293,12 @@ static unsigned long get_symbol_pos(unsigned long addr,
return low;
}
+#ifdef CONFIG_FUNCTION_PADDING_BYTES
+#define PADDING_BYTES CONFIG_FUNCTION_PADDING_BYTES
+#else
+#define PADDING_BYTES 0
+#endif
+
/*
* Lookup an address but don't bother to find any names.
*/
@@ -300,13 +306,25 @@ int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize,
unsigned long *offset)
{
char namebuf[KSYM_NAME_LEN];
+ int ret;
+
+ addr += PADDING_BYTES;
if (is_ksym_addr(addr)) {
get_symbol_pos(addr, symbolsize, offset);
- return 1;
+ ret = 1;
+ goto found;
+ }
+
+ ret = !!module_address_lookup(addr, symbolsize, offset, NULL, NULL, namebuf);
+ if (!ret) {
+ ret = !!__bpf_address_lookup(addr, symbolsize,
+ offset, namebuf);
}
- return !!module_address_lookup(addr, symbolsize, offset, NULL, NULL, namebuf) ||
- !!__bpf_address_lookup(addr, symbolsize, offset, namebuf);
+found:
+ if (ret && offset)
+ *offset -= PADDING_BYTES;
+ return ret;
}
static const char *kallsyms_lookup_buildid(unsigned long addr,
@@ -319,6 +337,8 @@ static const char *kallsyms_lookup_buildid(unsigned long addr,
namebuf[KSYM_NAME_LEN - 1] = 0;
namebuf[0] = 0;
+ addr += PADDING_BYTES;
+
if (is_ksym_addr(addr)) {
unsigned long pos;
@@ -348,6 +368,8 @@ static const char *kallsyms_lookup_buildid(unsigned long addr,
found:
cleanup_symbol_name(namebuf);
+ if (ret && offset)
+ *offset -= PADDING_BYTES;
return ret;
}
@@ -374,6 +396,8 @@ int lookup_symbol_name(unsigned long addr, char *symname)
symname[0] = '\0';
symname[KSYM_NAME_LEN - 1] = '\0';
+ addr += PADDING_BYTES;
+
if (is_ksym_addr(addr)) {
unsigned long pos;
@@ -401,6 +425,8 @@ int lookup_symbol_attrs(unsigned long addr, unsigned long *size,
name[0] = '\0';
name[KSYM_NAME_LEN - 1] = '\0';
+ addr += PADDING_BYTES;
+
if (is_ksym_addr(addr)) {
unsigned long pos;
@@ -417,6 +443,8 @@ int lookup_symbol_attrs(unsigned long addr, unsigned long *size,
return res;
found:
+ if (offset)
+ *offset -= PADDING_BYTES;
cleanup_symbol_name(name);
return 0;
}
@@ -442,8 +470,15 @@ static int __sprint_symbol(char *buffer, unsigned long address,
len = strlen(buffer);
offset -= symbol_offset;
- if (add_offset)
- len += sprintf(buffer + len, "+%#lx/%#lx", offset, size);
+ if (add_offset) {
+ char s = '+';
+
+ if ((long)offset < 0) {
+ s = '-';
+ offset = 0UL - offset;
+ }
+ len += sprintf(buffer + len, "%c%#lx/%#lx", s, offset, size);
+ }
if (modname) {
len += sprintf(buffer + len, " [%s", modname);