From 05fb7fe5f3c3d0d24a39f9510108f73c9ee8e3d6 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Wed, 14 Feb 2018 10:26:35 -0800 Subject: [PATCH] ANDROID: kallsyms: strip the .cfi postfix from symbols with CONFIG_CFI_CLANG With CFI enabled, LLVM appends .cfi to most function names, which potentially breaks user space tools. While stripping the postfix is not optimal either, this should at least create less confusion. Bug: 67506682 Bug: 73328469 Bug: 133186739 Change-Id: I253f34a562629032ddd792b8498e171109ea7cbc Signed-off-by: Sami Tolvanen --- kernel/kallsyms.c | 49 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 02a0b01380d8..672ed40e60c2 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -268,6 +268,24 @@ int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize, !!__bpf_address_lookup(addr, symbolsize, offset, namebuf); } +#ifdef CONFIG_CFI_CLANG +/* + * LLVM appends .cfi to function names when CONFIG_CFI_CLANG is enabled, + * which causes confusion and potentially breaks user space tools, so we + * will strip the postfix from expanded symbol names. + */ +static inline void cleanup_symbol_name(char *s) +{ + char *res; + + res = strrchr(s, '.'); + if (res && !strcmp(res, ".cfi")) + *res = '\0'; +} +#else +static inline void cleanup_symbol_name(char *s) {} +#endif + /* * Lookup an address * - modname is set to NULL if it's in the kernel. @@ -294,7 +312,9 @@ const char *kallsyms_lookup(unsigned long addr, namebuf, KSYM_NAME_LEN); if (modname) *modname = NULL; - return namebuf; + + ret = namebuf; + goto found; } /* See if it's in a module or a BPF JITed image. */ @@ -307,11 +327,16 @@ const char *kallsyms_lookup(unsigned long addr, if (!ret) ret = ftrace_mod_address_lookup(addr, symbolsize, offset, modname, namebuf); + +found: + cleanup_symbol_name(namebuf); return ret; } int lookup_symbol_name(unsigned long addr, char *symname) { + int res; + symname[0] = '\0'; symname[KSYM_NAME_LEN - 1] = '\0'; @@ -322,15 +347,23 @@ int lookup_symbol_name(unsigned long addr, char *symname) /* Grab name */ kallsyms_expand_symbol(get_symbol_offset(pos), symname, KSYM_NAME_LEN); - return 0; + goto found; } /* See if it's in a module. */ - return lookup_module_symbol_name(addr, symname); + res = lookup_module_symbol_name(addr, symname); + if (res) + return res; + +found: + cleanup_symbol_name(symname); + return 0; } int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name) { + int res; + name[0] = '\0'; name[KSYM_NAME_LEN - 1] = '\0'; @@ -342,10 +375,16 @@ int lookup_symbol_attrs(unsigned long addr, unsigned long *size, kallsyms_expand_symbol(get_symbol_offset(pos), name, KSYM_NAME_LEN); modname[0] = '\0'; - return 0; + goto found; } /* See if it's in a module. */ - return lookup_module_symbol_attrs(addr, size, offset, modname, name); + res = lookup_module_symbol_attrs(addr, size, offset, modname, name); + if (res) + return res; + +found: + cleanup_symbol_name(name); + return 0; } /* Look up a kernel symbol and return it in a text buffer. */