ANDROID: kallsyms: strip the .cfi postfix from symbols with CONFIG_CFI_CLANG
authorSami Tolvanen <samitolvanen@google.com>
Wed, 14 Feb 2018 18:26:35 +0000 (10:26 -0800)
committerSami Tolvanen <samitolvanen@google.com>
Thu, 26 Apr 2018 23:03:37 +0000 (16:03 -0700)
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
Change-Id: I253f34a562629032ddd792b8498e171109ea7cbc
Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
kernel/kallsyms.c

index 127e7cfafa55207a3fb45e5dc158c7885b949b49..3314c0c6c0300a0d4ff3dd2fc39d285bfa971a62 100644 (file)
@@ -302,6 +302,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.
@@ -328,7 +346,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. */
@@ -337,11 +357,16 @@ const char *kallsyms_lookup(unsigned long addr,
        if (!ret)
                ret = bpf_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';
 
@@ -352,15 +377,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';
 
@@ -372,10 +405,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. */