fix: net: udp: add IP/port data to the tracepoint udp/udp_fail_queue_rcv_skb (v6.10)
[lttng-modules.git] / src / wrapper / kallsyms.c
index d284876407a0396dbe9a3cd22f574961653b5dbf..295617f6434084f030959bcb33736820eeecf0a3 100644 (file)
@@ -29,6 +29,80 @@ int dummy_kprobe_handler(struct kprobe *p, struct pt_regs *regs)
        return 0;
 }
 
+#ifdef LTTNG_CONFIG_PPC64_ELF_ABI_V2
+static
+void kallsyms_pre_arch_adjust(struct kprobe *probe)
+{
+       /*
+        * With powerpc64 ABIv2, we need the global entry point of
+        * kallsyms_lookup_name to call it later, while kprobe_register would
+        * automatically adjust the global entry point to the local entry point,
+        * when a kprobe was registered at a function entry. So we add 4 bytes
+        * which is the length of one instruction to kallsyms_lookup_name to
+        * avoid the adjustment.
+        */
+       probe->offset = 4;
+}
+#else
+static
+void kallsyms_pre_arch_adjust(struct kprobe *probe)
+{
+}
+#endif
+
+#ifdef LTTNG_CONFIG_PPC64_ELF_ABI_V2
+static
+unsigned long kallsyms_get_arch_call_addr(const struct kprobe *probe)
+{
+       /* Substract 4 bytes to get what we originally want */
+       return (unsigned long)(((char *)probe->addr) - 4);
+}
+
+#elif defined(LTTNG_CONFIG_PPC64_ELF_ABI_V1)
+# if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,18,0))
+# include <asm/elf.h>
+# define LTTNG_FUNC_DESC_TYPE struct func_desc
+# define LTTNG_FUNC_DESC_ADDR_NAME addr
+# else
+# include <asm/types.h>
+# define LTTNG_FUNC_DESC_TYPE func_descr_t
+# define LTTNG_FUNC_DESC_ADDR_NAME entry
+
+static
+LTTNG_FUNC_DESC_TYPE kallsyms_lookup_name_func_desc;
+# endif
+
+static
+unsigned long kallsyms_get_arch_call_addr(const struct kprobe *probe)
+{
+       /*
+        * Build a function descriptor from the address of
+        * 'kallsyms_lookup_name' returned by kprobe and the toc of
+        * 'sprint_symbol' which is in the same compile unit and exported. I
+        * hate this on so many levels but it works.
+        */
+       kallsyms_lookup_name_func_desc.LTTNG_FUNC_DESC_ADDR_NAME = (unsigned long) probe.addr;
+       kallsyms_lookup_name_func_desc.toc = ((LTTNG_FUNC_DESC_TYPE *) &sprint_symbol)->toc;
+       return (unsigned long) &kallsyms_lookup_name_func_desc;
+}
+#elif defined(CONFIG_ARM) && defined(CONFIG_THUMB2_KERNEL)
+static
+unsigned long kallsyms_get_arch_call_addr(const struct kprobe *probe)
+{
+       unsigned long addr = (unsigned long)probe->addr;
+
+       if (addr)
+               addr |= 1; /* set bit 0 in address for thumb mode */
+       return addr;
+}
+#else
+static
+unsigned long kallsyms_get_arch_call_addr(const struct kprobe *probe)
+{
+       return (unsigned long)probe->addr;
+}
+#endif
+
 static
 unsigned long do_get_kallsyms(void)
 {
@@ -39,16 +113,11 @@ unsigned long do_get_kallsyms(void)
        memset(&probe, 0, sizeof(probe));
        probe.pre_handler = dummy_kprobe_handler;
        probe.symbol_name = "kallsyms_lookup_name";
+       kallsyms_pre_arch_adjust(&probe);
        ret = register_kprobe(&probe);
        if (ret)
                return 0;
-       addr = (unsigned long)probe.addr;
-#ifdef CONFIG_ARM
-#ifdef CONFIG_THUMB2_KERNEL
-       if (addr)
-               addr |= 1; /* set bit 0 in address for thumb mode */
-#endif
-#endif
+       addr = kallsyms_get_arch_call_addr(&probe);
        unregister_kprobe(&probe);
        return addr;
 }
@@ -58,9 +127,15 @@ unsigned long wrapper_kallsyms_lookup_name(const char *name)
        if (!kallsyms_lookup_name_sym) {
                kallsyms_lookup_name_sym = (void *)do_get_kallsyms();
        }
-       if (kallsyms_lookup_name_sym)
-               return kallsyms_lookup_name_sym(name);
-       else {
+       if (kallsyms_lookup_name_sym) {
+               struct irq_ibt_state irq_ibt_state;
+               unsigned long ret;
+
+               irq_ibt_state = wrapper_irq_ibt_save();
+               ret = kallsyms_lookup_name_sym(name);
+               wrapper_irq_ibt_restore(irq_ibt_state);
+               return ret;
+       } else {
                printk_once(KERN_WARNING "LTTng: requires kallsyms_lookup_name\n");
                return 0;
        }
@@ -68,3 +143,7 @@ unsigned long wrapper_kallsyms_lookup_name(const char *name)
 EXPORT_SYMBOL_GPL(wrapper_kallsyms_lookup_name);
 
 #endif
+
+#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,4,0) && defined(CONFIG_ANDROID))
+MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
+#endif
This page took 0.025597 seconds and 4 git commands to generate.