From: Michael Jeanson Date: Thu, 14 May 2020 17:47:35 +0000 (-0400) Subject: Detect missing symbols used with kallsyms_lookup at compile time X-Git-Tag: v2.12.2~11 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=60c64030e811165e62a62eb551459dd2416d6ec2;p=lttng-modules.git Detect missing symbols used with kallsyms_lookup at compile time Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers Change-Id: I19a9a31c386196899517899d861fe63611272139 --- diff --git a/lttng-context-prio.c b/lttng-context-prio.c index 367f7bd6..c786f5d3 100644 --- a/lttng-context-prio.c +++ b/lttng-context-prio.c @@ -29,6 +29,19 @@ int wrapper_task_prio_init(void) return 0; } +/* + * Canary function to check for 'task_prio()' at compile time. + * + * From 'include/linux/sched.h': + * + * extern int task_prio(const struct task_struct *p); + */ +__attribute__((unused)) static +int __canary__task_prio(const struct task_struct *p) +{ + return task_prio(p); +} + static size_t prio_get_size(size_t offset) { diff --git a/wrapper/genhd.h b/wrapper/genhd.h index 4eac2c1a..98feb57b 100644 --- a/wrapper/genhd.h +++ b/wrapper/genhd.h @@ -32,6 +32,19 @@ struct class *wrapper_get_block_class(void) return ptr_block_class; } +/* + * Canary function to check for 'block_class' at compile time. + * + * From 'include/linux/genhd.h': + * + * extern struct class block_class; + */ +static inline +struct class *__canary__get_block_class(void) +{ + return &block_class; +} + static inline struct device_type *wrapper_get_disk_type(void) { @@ -45,6 +58,16 @@ struct device_type *wrapper_get_disk_type(void) return ptr_disk_type; } +/* + * No canary for 'disk_type', it's only defined in 'block/genhd.c'. + * + * static inline + * struct device_type *__canary__get_disk_type(void) + * { + * return &disk_type; + * } + */ + #else static inline diff --git a/wrapper/irqdesc.h b/wrapper/irqdesc.h index 514d0162..ce7da2b4 100644 --- a/wrapper/irqdesc.h +++ b/wrapper/irqdesc.h @@ -17,4 +17,17 @@ struct irq_desc *wrapper_irq_to_desc(unsigned int irq); +/* + * Canary function to check for 'irq_to_desc()' at compile time. + * + * From 'include/linux/irqnr.h': + * + * extern struct irq_desc *irq_to_desc(unsigned int irq); + */ +static inline +struct irq_desc *__canary__irq_to_desc(unsigned int irq) +{ + return irq_to_desc(irq); +} + #endif /* _LTTNG_WRAPPER_IRQDESC_H */ diff --git a/wrapper/page_alloc.c b/wrapper/page_alloc.c index 40998199..2de24f9e 100644 --- a/wrapper/page_alloc.c +++ b/wrapper/page_alloc.c @@ -54,6 +54,25 @@ int wrapper_get_pfnblock_flags_mask_init(void) } EXPORT_SYMBOL_GPL(wrapper_get_pfnblock_flags_mask_init); +/* + * Canary function to check for 'get_pfnblock_flags_mask()' at compile time. + * + * From 'include/linux/pageblock-flags.h': + * + * unsigned long get_pfnblock_flags_mask(struct page *page, + * unsigned long pfn, + * unsigned long end_bitidx, + * unsigned long mask); + */ +__attribute__((unused)) static +unsigned long __canary__get_pfnblock_flags_mask(struct page *page, + unsigned long pfn, + unsigned long end_bitidx, + unsigned long mask) +{ + return get_pfnblock_flags_mask(page, pfn, end_bitidx, mask); +} + #else #include diff --git a/wrapper/splice.c b/wrapper/splice.c index 2ecc98f3..282bd863 100644 --- a/wrapper/splice.c +++ b/wrapper/splice.c @@ -36,6 +36,21 @@ ssize_t wrapper_splice_to_pipe(struct pipe_inode_info *pipe, } } +/* + * Canary function to check for 'splice_to_pipe()' at compile time. + * + * From 'include/linux/splice.h': + * + * extern ssize_t splice_to_pipe(struct pipe_inode_info *, + * struct splice_pipe_desc *spd); + */ +__attribute__((unused)) static +ssize_t __canary__splice_to_pipe(struct pipe_inode_info *pipe, + struct splice_pipe_desc *spd) +{ + return splice_to_pipe(pipe, spd); +} + #else #include diff --git a/wrapper/tracepoint.h b/wrapper/tracepoint.h index 08e8ccab..c4ba0123 100644 --- a/wrapper/tracepoint.h +++ b/wrapper/tracepoint.h @@ -68,6 +68,17 @@ int wrapper_tracepoint_module_notify(struct notifier_block *nb, } } +/* + * No canary for 'tracepoint_module_notify()', it's only defined in 'kernel/tracepoint.c'. + * + * static inline + * int __canary__tracepoint_module_notify(struct notifier_block *nb, + * unsigned long val, struct module *mod) + * { + * return tracepoint_module_notify(nb, val, mod); + * } + */ + #endif /* #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0) && defined(CONFIG_MODULE_SIG)) */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0) && defined(CONFIG_MODULE_SIG) && defined(MODULE)) diff --git a/wrapper/uprobes.h b/wrapper/uprobes.h index 6ea9df18..d76a7881 100644 --- a/wrapper/uprobes.h +++ b/wrapper/uprobes.h @@ -52,6 +52,19 @@ int wrapper_uprobe_register(struct inode *inode, loff_t offset, struct uprobe_co } } +/* + * Canary function to check for 'uprobe_register()' at compile time. + * + * From 'include/linux/uprobes.h': + * + * extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); + */ +static inline +int __canary__uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) +{ + return uprobe_register(inode, offset, uc); +} + static inline void wrapper_uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) { @@ -66,6 +79,20 @@ void wrapper_uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe WARN_ON(1); } } + +/* + * Canary function to check for 'uprobe_unregister()' at compile time. + * + * From 'include/linux/uprobes.h': + * + * extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); + */ +static inline +int __canary__uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) +{ + return uprobe_unregister(inode, offset, uc); +} + #endif #else /* Version < 3.5, before uprobe was added. */ diff --git a/wrapper/vmalloc.h b/wrapper/vmalloc.h index e78d99bb..362054b1 100644 --- a/wrapper/vmalloc.h +++ b/wrapper/vmalloc.h @@ -64,10 +64,23 @@ void wrapper_vmalloc_sync_mappings(void) } } +/* + * Canary function to check for 'vmalloc_sync_mappings()' at compile time. + * + * From 'include/linux/vmalloc.h': + * + * void vmalloc_sync_mappings(void); + */ +static inline +void __canary__vmalloc_sync_mappings(void) +{ + vmalloc_sync_mappings(); +} + #else /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) */ /* - * Map vmalloc_sync_mappings to vmalloc_sync_all() on kernels before 5.7. + * Map vmalloc_sync_mappings to vmalloc_sync_all() on kernels before 5.6. */ static inline void wrapper_vmalloc_sync_mappings(void) @@ -89,6 +102,19 @@ void wrapper_vmalloc_sync_mappings(void) } } +/* + * Canary function to check for 'vmalloc_sync_all()' at compile time. + * + * From 'include/linux/vmalloc.h': + * + * void vmalloc_sync_all(void); + */ +static inline +void __canary__vmalloc_sync_all(void) +{ + vmalloc_sync_all(); +} + #endif /* #else #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) */ #else @@ -204,6 +230,26 @@ void *__lttng_vmalloc_node_range(unsigned long size, unsigned long align, return __vmalloc(size, gfp_mask, prot); } +/* + * Canary function to check for '__vmalloc_node_range()' at compile time. + * + * From 'include/linux/vmalloc.h': + * + * extern void *__vmalloc_node_range(unsigned long size, unsigned long align, + * unsigned long start, unsigned long end, gfp_t gfp_mask, + * pgprot_t prot, unsigned long vm_flags, int node, + * const void *caller); + */ +static inline +void *__canary____lttng_vmalloc_node_range(unsigned long size, unsigned long align, + unsigned long start, unsigned long end, gfp_t gfp_mask, + pgprot_t prot, unsigned long vm_flags, int node, + const void *caller) +{ + return __vmalloc_node_range(size, align, start, end, gfp_mask, prot, + vm_flags, node, caller); +} + /** * lttng_kvmalloc_node - attempt to allocate physically contiguous memory, but upon * failure, fall back to non-contiguous (vmalloc) allocation. diff --git a/wrapper/writeback.h b/wrapper/writeback.h index 64624662..00d727cc 100644 --- a/wrapper/writeback.h +++ b/wrapper/writeback.h @@ -37,6 +37,20 @@ unsigned long wrapper_global_dirty_limit(void) return 0; } } + +/* + * Canary function to check for 'global_wb_domain' at compile time. + * + * From 'include/linux/writeback.h': + * + * extern struct wb_domain global_wb_domain; + */ +static inline +unsigned long __canary__global_wb_domain(void) +{ + return global_wb_domain.dirty_limit; +} + #else static unsigned long *global_dirty_limit_sym; @@ -54,6 +68,20 @@ unsigned long wrapper_global_dirty_limit(void) return 0; } } + +/* + * Canary function to check for 'global_dirty_limit' at compile time. + * + * From 'include/linux/writeback.h': + * + * extern unsigned long global_dirty_limit; + */ +static inline +unsigned long __canary__global_dirty_limit(void) +{ + return global_dirty_limit; +} + #endif #else /* CONFIG_KALLSYMS_ALL */