codegraph_c/platform/
linux.rs

1//! Linux kernel platform module
2//!
3//! Provides platform-specific configurations for parsing Linux kernel code,
4//! including header stubs, attribute lists, and ops struct definitions.
5
6use std::collections::HashMap;
7
8use super::{
9    CallbackCategory, DetectionPattern, HeaderStubs, OpsFieldDef, OpsStructDef, PlatformModule,
10};
11
12/// Linux kernel platform module
13pub struct LinuxPlatform {
14    header_stubs: HeaderStubs,
15    ops_structs: Vec<OpsStructDef>,
16    call_normalizations: HashMap<&'static str, &'static str>,
17}
18
19impl LinuxPlatform {
20    pub fn new() -> Self {
21        let mut platform = Self {
22            header_stubs: HeaderStubs::new(),
23            ops_structs: Vec::new(),
24            call_normalizations: HashMap::new(),
25        };
26        platform.init_header_stubs();
27        platform.init_ops_structs();
28        platform.init_call_normalizations();
29        platform
30    }
31
32    fn init_header_stubs(&mut self) {
33        // linux/types.h - Core type definitions
34        self.header_stubs.add(
35            "linux/types.h",
36            r#"
37typedef unsigned char u8;
38typedef unsigned short u16;
39typedef unsigned int u32;
40typedef unsigned long long u64;
41typedef signed char s8;
42typedef signed short s16;
43typedef signed int s32;
44typedef signed long long s64;
45typedef u8 __u8;
46typedef u16 __u16;
47typedef u32 __u32;
48typedef u64 __u64;
49typedef s8 __s8;
50typedef s16 __s16;
51typedef s32 __s32;
52typedef s64 __s64;
53typedef u16 __le16;
54typedef u32 __le32;
55typedef u64 __le64;
56typedef u16 __be16;
57typedef u32 __be32;
58typedef u64 __be64;
59typedef unsigned long size_t;
60typedef long ssize_t;
61typedef long long loff_t;
62typedef int bool;
63typedef unsigned int gfp_t;
64typedef unsigned int fmode_t;
65typedef unsigned short umode_t;
66typedef unsigned int dev_t;
67typedef int pid_t;
68typedef unsigned int uid_t;
69typedef unsigned int gid_t;
70typedef long long ktime_t;
71typedef unsigned long phys_addr_t;
72typedef unsigned long long dma_addr_t;
73typedef unsigned long long resource_size_t;
74typedef unsigned long uintptr_t;
75typedef long intptr_t;
76typedef long ptrdiff_t;
77"#,
78        );
79
80        // linux/kernel.h - Core kernel definitions
81        self.header_stubs.add(
82            "linux/kernel.h",
83            r#"
84#define NULL ((void *)0)
85#define true 1
86#define false 0
87#define KERN_EMERG ""
88#define KERN_ALERT ""
89#define KERN_CRIT ""
90#define KERN_ERR ""
91#define KERN_WARNING ""
92#define KERN_NOTICE ""
93#define KERN_INFO ""
94#define KERN_DEBUG ""
95#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
96#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))
97#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
98extern int printk(const char *fmt, ...);
99extern void panic(const char *fmt, ...);
100extern void *ERR_PTR(long error);
101extern long PTR_ERR(const void *ptr);
102extern int IS_ERR(const void *ptr);
103"#,
104        );
105
106        // linux/init.h - Module init/exit
107        self.header_stubs.add(
108            "linux/init.h",
109            r#"
110#define __init
111#define __exit
112#define __initdata
113#define __exitdata
114#define __initconst
115#define __devinit
116#define __devexit
117#define module_init(x) int init_module(void) { return x(); }
118#define module_exit(x) void cleanup_module(void) { x(); }
119#define late_initcall(fn)
120#define subsys_initcall(fn)
121#define fs_initcall(fn)
122#define device_initcall(fn)
123#define arch_initcall(fn)
124#define core_initcall(fn)
125#define postcore_initcall(fn)
126"#,
127        );
128
129        // linux/module.h - Module infrastructure
130        self.header_stubs.add(
131            "linux/module.h",
132            r#"
133#define MODULE_LICENSE(license)
134#define MODULE_AUTHOR(author)
135#define MODULE_DESCRIPTION(desc)
136#define MODULE_VERSION(version)
137#define MODULE_ALIAS(alias)
138#define MODULE_DEVICE_TABLE(type, name)
139#define MODULE_FIRMWARE(fw)
140#define MODULE_INFO(tag, info)
141#define MODULE_PARM_DESC(parm, desc)
142#define EXPORT_SYMBOL(sym)
143#define EXPORT_SYMBOL_GPL(sym)
144#define EXPORT_SYMBOL_NS(sym, ns)
145#define EXPORT_SYMBOL_NS_GPL(sym, ns)
146#define THIS_MODULE ((struct module *)0)
147struct module;
148"#,
149        );
150
151        // linux/fs.h - File system operations
152        self.header_stubs.add(
153            "linux/fs.h",
154            r#"
155struct file;
156struct inode;
157struct dentry;
158struct super_block;
159struct file_operations {
160    struct module *owner;
161    loff_t (*llseek)(struct file *, loff_t, int);
162    ssize_t (*read)(struct file *, char *, size_t, loff_t *);
163    ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
164    int (*open)(struct inode *, struct file *);
165    int (*release)(struct inode *, struct file *);
166    long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);
167    int (*mmap)(struct file *, struct vm_area_struct *);
168    unsigned int (*poll)(struct file *, struct poll_table_struct *);
169    int (*fsync)(struct file *, loff_t, loff_t, int);
170    int (*flush)(struct file *, void *);
171};
172struct inode_operations {
173    int (*create)(struct inode *, struct dentry *, umode_t, bool);
174    struct dentry * (*lookup)(struct inode *, struct dentry *, unsigned int);
175    int (*link)(struct dentry *, struct inode *, struct dentry *);
176    int (*unlink)(struct inode *, struct dentry *);
177    int (*mkdir)(struct inode *, struct dentry *, umode_t);
178    int (*rmdir)(struct inode *, struct dentry *);
179};
180extern int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops);
181extern void unregister_chrdev(unsigned int major, const char *name);
182"#,
183        );
184
185        // linux/device.h - Device model
186        self.header_stubs.add(
187            "linux/device.h",
188            r#"
189struct device;
190struct device_driver;
191struct class;
192struct bus_type;
193extern int device_register(struct device *dev);
194extern void device_unregister(struct device *dev);
195extern struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);
196extern void device_destroy(struct class *cls, dev_t devt);
197extern int dev_err(const struct device *dev, const char *fmt, ...);
198extern int dev_warn(const struct device *dev, const char *fmt, ...);
199extern int dev_info(const struct device *dev, const char *fmt, ...);
200extern int dev_dbg(const struct device *dev, const char *fmt, ...);
201"#,
202        );
203
204        // linux/pci.h - PCI driver infrastructure
205        self.header_stubs.add(
206            "linux/pci.h",
207            r#"
208struct pci_dev;
209struct pci_device_id {
210    u32 vendor, device;
211    u32 subvendor, subdevice;
212    u32 class, class_mask;
213    unsigned long driver_data;
214};
215struct pci_driver {
216    const char *name;
217    const struct pci_device_id *id_table;
218    int (*probe)(struct pci_dev *dev, const struct pci_device_id *id);
219    void (*remove)(struct pci_dev *dev);
220    int (*suspend)(struct pci_dev *dev, pm_message_t state);
221    int (*resume)(struct pci_dev *dev);
222    void (*shutdown)(struct pci_dev *dev);
223    struct device_driver driver;
224};
225extern int pci_register_driver(struct pci_driver *drv);
226extern void pci_unregister_driver(struct pci_driver *drv);
227extern int pci_enable_device(struct pci_dev *dev);
228extern void pci_disable_device(struct pci_dev *dev);
229extern void pci_set_master(struct pci_dev *dev);
230extern int pci_request_regions(struct pci_dev *dev, const char *name);
231extern void pci_release_regions(struct pci_dev *dev);
232extern void *pci_ioremap_bar(struct pci_dev *dev, int bar);
233extern int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val);
234extern int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val);
235extern int pci_read_config_dword(const struct pci_dev *dev, int where, u32 *val);
236extern int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val);
237extern int pci_write_config_word(const struct pci_dev *dev, int where, u16 val);
238extern int pci_write_config_dword(const struct pci_dev *dev, int where, u32 val);
239#define PCI_DEVICE(vend, dev) .vendor = (vend), .device = (dev)
240#define module_pci_driver(drv)
241"#,
242        );
243
244        // linux/slab.h - Memory allocation
245        self.header_stubs.add(
246            "linux/slab.h",
247            r#"
248#define GFP_KERNEL 0
249#define GFP_ATOMIC 1
250#define GFP_DMA 2
251#define GFP_NOWAIT 4
252extern void *kmalloc(size_t size, gfp_t flags);
253extern void *kzalloc(size_t size, gfp_t flags);
254extern void *kcalloc(size_t n, size_t size, gfp_t flags);
255extern void *krealloc(void *p, size_t new_size, gfp_t flags);
256extern void kfree(const void *objp);
257extern void *vmalloc(unsigned long size);
258extern void vfree(const void *addr);
259extern void *kvmalloc(size_t size, gfp_t flags);
260extern void kvfree(const void *addr);
261extern struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align, unsigned long flags, void (*ctor)(void *));
262extern void kmem_cache_destroy(struct kmem_cache *s);
263extern void *kmem_cache_alloc(struct kmem_cache *s, gfp_t flags);
264extern void kmem_cache_free(struct kmem_cache *s, void *objp);
265"#,
266        );
267
268        // linux/mutex.h - Mutex primitives
269        self.header_stubs.add(
270            "linux/mutex.h",
271            r#"
272struct mutex {
273    int count;
274};
275#define DEFINE_MUTEX(name) struct mutex name = { .count = 1 }
276#define mutex_init(mutex) do { (mutex)->count = 1; } while(0)
277extern void mutex_lock(struct mutex *lock);
278extern int mutex_trylock(struct mutex *lock);
279extern void mutex_unlock(struct mutex *lock);
280extern int mutex_is_locked(struct mutex *lock);
281"#,
282        );
283
284        // linux/spinlock.h - Spinlock primitives
285        self.header_stubs.add(
286            "linux/spinlock.h",
287            r#"
288typedef struct {
289    int lock;
290} spinlock_t;
291typedef struct {
292    int lock;
293} rwlock_t;
294#define DEFINE_SPINLOCK(name) spinlock_t name = { .lock = 0 }
295#define DEFINE_RWLOCK(name) rwlock_t name = { .lock = 0 }
296#define spin_lock_init(lock) do { (lock)->lock = 0; } while(0)
297extern void spin_lock(spinlock_t *lock);
298extern void spin_unlock(spinlock_t *lock);
299extern void spin_lock_irq(spinlock_t *lock);
300extern void spin_unlock_irq(spinlock_t *lock);
301extern void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);
302extern void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);
303extern int spin_trylock(spinlock_t *lock);
304extern void read_lock(rwlock_t *lock);
305extern void read_unlock(rwlock_t *lock);
306extern void write_lock(rwlock_t *lock);
307extern void write_unlock(rwlock_t *lock);
308"#,
309        );
310
311        // linux/wait.h - Wait queues
312        self.header_stubs.add(
313            "linux/wait.h",
314            r#"
315struct wait_queue_head {
316    spinlock_t lock;
317};
318typedef struct wait_queue_head wait_queue_head_t;
319#define DECLARE_WAIT_QUEUE_HEAD(name) wait_queue_head_t name
320#define init_waitqueue_head(wq) do { } while(0)
321extern void wake_up(wait_queue_head_t *wq);
322extern void wake_up_interruptible(wait_queue_head_t *wq);
323extern void wake_up_all(wait_queue_head_t *wq);
324#define wait_event(wq, condition) do { } while(0)
325#define wait_event_interruptible(wq, condition) 0
326#define wait_event_timeout(wq, condition, timeout) 0
327"#,
328        );
329
330        // linux/interrupt.h - Interrupt handling
331        self.header_stubs.add(
332            "linux/interrupt.h",
333            r#"
334typedef int irqreturn_t;
335#define IRQ_NONE 0
336#define IRQ_HANDLED 1
337#define IRQ_WAKE_THREAD 2
338#define IRQF_SHARED 0x00000080
339#define IRQF_TRIGGER_RISING 0x00000001
340#define IRQF_TRIGGER_FALLING 0x00000002
341typedef irqreturn_t (*irq_handler_t)(int, void *);
342extern int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev);
343extern void free_irq(unsigned int irq, void *dev_id);
344extern int request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn, unsigned long flags, const char *name, void *dev);
345extern void disable_irq(unsigned int irq);
346extern void enable_irq(unsigned int irq);
347extern void local_irq_disable(void);
348extern void local_irq_enable(void);
349"#,
350        );
351
352        // linux/dma-mapping.h - DMA operations
353        self.header_stubs.add(
354            "linux/dma-mapping.h",
355            r#"
356enum dma_data_direction {
357    DMA_BIDIRECTIONAL = 0,
358    DMA_TO_DEVICE = 1,
359    DMA_FROM_DEVICE = 2,
360    DMA_NONE = 3,
361};
362extern void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag);
363extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle);
364extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size, enum dma_data_direction dir);
365extern void dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir);
366extern int dma_set_mask(struct device *dev, u64 mask);
367extern int dma_set_coherent_mask(struct device *dev, u64 mask);
368#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL << (n)) - 1))
369"#,
370        );
371
372        // linux/io.h - Memory-mapped I/O
373        self.header_stubs.add(
374            "linux/io.h",
375            r#"
376extern void *ioremap(phys_addr_t offset, size_t size);
377extern void iounmap(void *addr);
378extern u8 readb(const volatile void *addr);
379extern u16 readw(const volatile void *addr);
380extern u32 readl(const volatile void *addr);
381extern u64 readq(const volatile void *addr);
382extern void writeb(u8 value, volatile void *addr);
383extern void writew(u16 value, volatile void *addr);
384extern void writel(u32 value, volatile void *addr);
385extern void writeq(u64 value, volatile void *addr);
386extern u8 ioread8(const void *addr);
387extern u16 ioread16(const void *addr);
388extern u32 ioread32(const void *addr);
389extern void iowrite8(u8 value, void *addr);
390extern void iowrite16(u16 value, void *addr);
391extern void iowrite32(u32 value, void *addr);
392"#,
393        );
394
395        // linux/errno.h - Error codes
396        self.header_stubs.add(
397            "linux/errno.h",
398            r#"
399#define EPERM 1
400#define ENOENT 2
401#define EIO 5
402#define ENXIO 6
403#define ENOMEM 12
404#define EACCES 13
405#define EFAULT 14
406#define EBUSY 16
407#define EEXIST 17
408#define ENODEV 19
409#define EINVAL 22
410#define ENOSPC 28
411#define ERANGE 34
412#define EOPNOTSUPP 95
413#define ETIMEDOUT 110
414#define ERESTARTSYS 512
415"#,
416        );
417
418        // linux/netdevice.h - Network device operations
419        self.header_stubs.add(
420            "linux/netdevice.h",
421            r#"
422struct net_device;
423struct sk_buff;
424struct net_device_stats;
425typedef u16 netdev_features_t;
426struct net_device_ops {
427    int (*ndo_open)(struct net_device *dev);
428    int (*ndo_stop)(struct net_device *dev);
429    int (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev);
430    void (*ndo_set_rx_mode)(struct net_device *dev);
431    int (*ndo_set_mac_address)(struct net_device *dev, void *addr);
432    int (*ndo_validate_addr)(struct net_device *dev);
433    int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
434    int (*ndo_change_mtu)(struct net_device *dev, int new_mtu);
435    void (*ndo_tx_timeout)(struct net_device *dev, unsigned int txqueue);
436    struct net_device_stats *(*ndo_get_stats)(struct net_device *dev);
437};
438struct ethtool_ops {
439    int (*get_link)(struct net_device *dev);
440    int (*get_link_ksettings)(struct net_device *dev, struct ethtool_link_ksettings *cmd);
441    int (*set_link_ksettings)(struct net_device *dev, const struct ethtool_link_ksettings *cmd);
442};
443extern struct net_device *alloc_etherdev(int sizeof_priv);
444extern void free_netdev(struct net_device *dev);
445extern int register_netdev(struct net_device *dev);
446extern void unregister_netdev(struct net_device *dev);
447extern void *netdev_priv(const struct net_device *dev);
448"#,
449        );
450
451        // linux/uaccess.h - User space access
452        self.header_stubs.add(
453            "linux/uaccess.h",
454            r#"
455extern unsigned long copy_from_user(void *to, const void *from, unsigned long n);
456extern unsigned long copy_to_user(void *to, const void *from, unsigned long n);
457extern int get_user(int x, int *ptr);
458extern int put_user(int x, int *ptr);
459extern int access_ok(int type, const void *addr, unsigned long size);
460#define VERIFY_READ 0
461#define VERIFY_WRITE 1
462"#,
463        );
464
465        // linux/string.h - String operations
466        self.header_stubs.add(
467            "linux/string.h",
468            r#"
469extern void *memset(void *s, int c, size_t n);
470extern void *memcpy(void *dest, const void *src, size_t n);
471extern void *memmove(void *dest, const void *src, size_t n);
472extern int memcmp(const void *s1, const void *s2, size_t n);
473extern size_t strlen(const char *s);
474extern char *strcpy(char *dest, const char *src);
475extern char *strncpy(char *dest, const char *src, size_t n);
476extern int strcmp(const char *s1, const char *s2);
477extern int strncmp(const char *s1, const char *s2, size_t n);
478extern char *strcat(char *dest, const char *src);
479extern char *strchr(const char *s, int c);
480extern char *strstr(const char *haystack, const char *needle);
481"#,
482        );
483
484        // linux/workqueue.h - Work queues
485        self.header_stubs.add(
486            "linux/workqueue.h",
487            r#"
488struct work_struct;
489struct delayed_work;
490struct workqueue_struct;
491typedef void (*work_func_t)(struct work_struct *work);
492#define DECLARE_WORK(n, f) struct work_struct n
493#define DECLARE_DELAYED_WORK(n, f) struct delayed_work n
494#define INIT_WORK(work, func) do { } while(0)
495#define INIT_DELAYED_WORK(dwork, func) do { } while(0)
496extern struct workqueue_struct *create_workqueue(const char *name);
497extern void destroy_workqueue(struct workqueue_struct *wq);
498extern int queue_work(struct workqueue_struct *wq, struct work_struct *work);
499extern int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay);
500extern int schedule_work(struct work_struct *work);
501extern int schedule_delayed_work(struct delayed_work *dwork, unsigned long delay);
502extern int cancel_work_sync(struct work_struct *work);
503extern int cancel_delayed_work_sync(struct delayed_work *dwork);
504extern void flush_workqueue(struct workqueue_struct *wq);
505"#,
506        );
507
508        // linux/timer.h - Timer operations
509        self.header_stubs.add(
510            "linux/timer.h",
511            r#"
512struct timer_list {
513    unsigned long expires;
514    void (*function)(struct timer_list *);
515    unsigned long data;
516};
517#define DEFINE_TIMER(name, func) struct timer_list name
518extern void timer_setup(struct timer_list *timer, void (*callback)(struct timer_list *), unsigned int flags);
519extern int mod_timer(struct timer_list *timer, unsigned long expires);
520extern int del_timer(struct timer_list *timer);
521extern int del_timer_sync(struct timer_list *timer);
522extern unsigned long jiffies;
523#define HZ 100
524#define msecs_to_jiffies(m) ((m) * HZ / 1000)
525"#,
526        );
527
528        // linux/completion.h - Completion mechanism
529        self.header_stubs.add(
530            "linux/completion.h",
531            r#"
532struct completion {
533    unsigned int done;
534    wait_queue_head_t wait;
535};
536#define DECLARE_COMPLETION(name) struct completion name
537#define init_completion(x) do { (x)->done = 0; } while(0)
538extern void wait_for_completion(struct completion *x);
539extern int wait_for_completion_timeout(struct completion *x, unsigned long timeout);
540extern int wait_for_completion_interruptible(struct completion *x);
541extern void complete(struct completion *x);
542extern void complete_all(struct completion *x);
543extern void reinit_completion(struct completion *x);
544"#,
545        );
546
547        // linux/atomic.h - Atomic operations
548        self.header_stubs.add(
549            "linux/atomic.h",
550            r#"
551typedef struct {
552    int counter;
553} atomic_t;
554typedef struct {
555    long long counter;
556} atomic64_t;
557#define ATOMIC_INIT(i) { (i) }
558#define atomic_read(v) ((v)->counter)
559#define atomic_set(v, i) ((v)->counter = (i))
560extern void atomic_inc(atomic_t *v);
561extern void atomic_dec(atomic_t *v);
562extern int atomic_inc_return(atomic_t *v);
563extern int atomic_dec_return(atomic_t *v);
564extern int atomic_dec_and_test(atomic_t *v);
565extern int atomic_add_return(int i, atomic_t *v);
566extern int atomic_sub_return(int i, atomic_t *v);
567extern int atomic_cmpxchg(atomic_t *v, int old, int new);
568"#,
569        );
570
571        // linux/list.h - Linked list operations
572        self.header_stubs.add(
573            "linux/list.h",
574            r#"
575struct list_head {
576    struct list_head *next, *prev;
577};
578#define LIST_HEAD_INIT(name) { &(name), &(name) }
579#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
580#define INIT_LIST_HEAD(ptr) do { (ptr)->next = (ptr); (ptr)->prev = (ptr); } while (0)
581extern void list_add(struct list_head *new, struct list_head *head);
582extern void list_add_tail(struct list_head *new, struct list_head *head);
583extern void list_del(struct list_head *entry);
584extern void list_del_init(struct list_head *entry);
585extern int list_empty(const struct list_head *head);
586#define list_entry(ptr, type, member) container_of(ptr, type, member)
587#define list_for_each(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next)
588#define list_for_each_safe(pos, n, head) for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next)
589"#,
590        );
591    }
592
593    fn init_ops_structs(&mut self) {
594        // file_operations
595        self.ops_structs.push(OpsStructDef {
596            struct_name: "file_operations".to_string(),
597            fields: vec![
598                OpsFieldDef {
599                    name: "open".to_string(),
600                    category: CallbackCategory::Open,
601                },
602                OpsFieldDef {
603                    name: "release".to_string(),
604                    category: CallbackCategory::Close,
605                },
606                OpsFieldDef {
607                    name: "read".to_string(),
608                    category: CallbackCategory::Read,
609                },
610                OpsFieldDef {
611                    name: "write".to_string(),
612                    category: CallbackCategory::Write,
613                },
614                OpsFieldDef {
615                    name: "unlocked_ioctl".to_string(),
616                    category: CallbackCategory::Ioctl,
617                },
618                OpsFieldDef {
619                    name: "compat_ioctl".to_string(),
620                    category: CallbackCategory::Ioctl,
621                },
622                OpsFieldDef {
623                    name: "mmap".to_string(),
624                    category: CallbackCategory::Mmap,
625                },
626                OpsFieldDef {
627                    name: "poll".to_string(),
628                    category: CallbackCategory::Poll,
629                },
630                OpsFieldDef {
631                    name: "llseek".to_string(),
632                    category: CallbackCategory::Other,
633                },
634                OpsFieldDef {
635                    name: "fsync".to_string(),
636                    category: CallbackCategory::Other,
637                },
638            ],
639        });
640
641        // pci_driver
642        self.ops_structs.push(OpsStructDef {
643            struct_name: "pci_driver".to_string(),
644            fields: vec![
645                OpsFieldDef {
646                    name: "probe".to_string(),
647                    category: CallbackCategory::Probe,
648                },
649                OpsFieldDef {
650                    name: "remove".to_string(),
651                    category: CallbackCategory::Remove,
652                },
653                OpsFieldDef {
654                    name: "suspend".to_string(),
655                    category: CallbackCategory::Suspend,
656                },
657                OpsFieldDef {
658                    name: "resume".to_string(),
659                    category: CallbackCategory::Resume,
660                },
661                OpsFieldDef {
662                    name: "shutdown".to_string(),
663                    category: CallbackCategory::Cleanup,
664                },
665            ],
666        });
667
668        // net_device_ops
669        self.ops_structs.push(OpsStructDef {
670            struct_name: "net_device_ops".to_string(),
671            fields: vec![
672                OpsFieldDef {
673                    name: "ndo_open".to_string(),
674                    category: CallbackCategory::Open,
675                },
676                OpsFieldDef {
677                    name: "ndo_stop".to_string(),
678                    category: CallbackCategory::Close,
679                },
680                OpsFieldDef {
681                    name: "ndo_start_xmit".to_string(),
682                    category: CallbackCategory::Write,
683                },
684                OpsFieldDef {
685                    name: "ndo_set_rx_mode".to_string(),
686                    category: CallbackCategory::Other,
687                },
688                OpsFieldDef {
689                    name: "ndo_set_mac_address".to_string(),
690                    category: CallbackCategory::Other,
691                },
692                OpsFieldDef {
693                    name: "ndo_do_ioctl".to_string(),
694                    category: CallbackCategory::Ioctl,
695                },
696                OpsFieldDef {
697                    name: "ndo_tx_timeout".to_string(),
698                    category: CallbackCategory::Timer,
699                },
700            ],
701        });
702
703        // platform_driver
704        self.ops_structs.push(OpsStructDef {
705            struct_name: "platform_driver".to_string(),
706            fields: vec![
707                OpsFieldDef {
708                    name: "probe".to_string(),
709                    category: CallbackCategory::Probe,
710                },
711                OpsFieldDef {
712                    name: "remove".to_string(),
713                    category: CallbackCategory::Remove,
714                },
715                OpsFieldDef {
716                    name: "suspend".to_string(),
717                    category: CallbackCategory::Suspend,
718                },
719                OpsFieldDef {
720                    name: "resume".to_string(),
721                    category: CallbackCategory::Resume,
722                },
723            ],
724        });
725    }
726
727    fn init_call_normalizations(&mut self) {
728        // Memory allocation
729        self.call_normalizations.insert("kmalloc", "MemAlloc");
730        self.call_normalizations.insert("kzalloc", "MemAlloc");
731        self.call_normalizations.insert("kcalloc", "MemAlloc");
732        self.call_normalizations.insert("krealloc", "MemRealloc");
733        self.call_normalizations.insert("vmalloc", "MemAlloc");
734        self.call_normalizations.insert("kvmalloc", "MemAlloc");
735        self.call_normalizations
736            .insert("kmem_cache_alloc", "MemAlloc");
737        self.call_normalizations
738            .insert("dma_alloc_coherent", "DmaAlloc");
739
740        // Memory free
741        self.call_normalizations.insert("kfree", "MemFree");
742        self.call_normalizations.insert("vfree", "MemFree");
743        self.call_normalizations.insert("kvfree", "MemFree");
744        self.call_normalizations
745            .insert("kmem_cache_free", "MemFree");
746        self.call_normalizations
747            .insert("dma_free_coherent", "DmaFree");
748
749        // Memory operations
750        self.call_normalizations.insert("memcpy", "MemCopy");
751        self.call_normalizations.insert("memmove", "MemCopy");
752        self.call_normalizations.insert("memset", "MemSet");
753
754        // User/kernel boundary
755        self.call_normalizations
756            .insert("copy_from_user", "CopyFromUser");
757        self.call_normalizations.insert("get_user", "CopyFromUser");
758        self.call_normalizations
759            .insert("copy_to_user", "CopyToUser");
760        self.call_normalizations.insert("put_user", "CopyToUser");
761
762        // Locking
763        self.call_normalizations.insert("mutex_lock", "LockAcquire");
764        self.call_normalizations.insert("spin_lock", "LockAcquire");
765        self.call_normalizations
766            .insert("spin_lock_irq", "LockAcquire");
767        self.call_normalizations
768            .insert("spin_lock_irqsave", "LockAcquire");
769        self.call_normalizations.insert("read_lock", "LockAcquire");
770        self.call_normalizations.insert("write_lock", "LockAcquire");
771        self.call_normalizations
772            .insert("mutex_unlock", "LockRelease");
773        self.call_normalizations
774            .insert("spin_unlock", "LockRelease");
775        self.call_normalizations
776            .insert("spin_unlock_irq", "LockRelease");
777        self.call_normalizations
778            .insert("spin_unlock_irqrestore", "LockRelease");
779        self.call_normalizations
780            .insert("read_unlock", "LockRelease");
781        self.call_normalizations
782            .insert("write_unlock", "LockRelease");
783
784        // Wait/signal
785        self.call_normalizations
786            .insert("wait_for_completion", "WaitEvent");
787        self.call_normalizations
788            .insert("wait_event_interruptible", "WaitEvent");
789        self.call_normalizations.insert("complete", "SignalEvent");
790        self.call_normalizations
791            .insert("complete_all", "SignalEvent");
792        self.call_normalizations.insert("wake_up", "SignalEvent");
793        self.call_normalizations
794            .insert("wake_up_interruptible", "SignalEvent");
795
796        // I/O mapping
797        self.call_normalizations.insert("ioremap", "IoRemap");
798        self.call_normalizations
799            .insert("pci_ioremap_bar", "IoRemap");
800        self.call_normalizations.insert("iounmap", "IoUnmap");
801
802        // I/O operations
803        self.call_normalizations.insert("readb", "IoRead");
804        self.call_normalizations.insert("readw", "IoRead");
805        self.call_normalizations.insert("readl", "IoRead");
806        self.call_normalizations.insert("readq", "IoRead");
807        self.call_normalizations.insert("ioread8", "IoRead");
808        self.call_normalizations.insert("ioread16", "IoRead");
809        self.call_normalizations.insert("ioread32", "IoRead");
810        self.call_normalizations.insert("writeb", "IoWrite");
811        self.call_normalizations.insert("writew", "IoWrite");
812        self.call_normalizations.insert("writel", "IoWrite");
813        self.call_normalizations.insert("writeq", "IoWrite");
814        self.call_normalizations.insert("iowrite8", "IoWrite");
815        self.call_normalizations.insert("iowrite16", "IoWrite");
816        self.call_normalizations.insert("iowrite32", "IoWrite");
817
818        // DMA mapping
819        self.call_normalizations.insert("dma_map_single", "DmaMap");
820        self.call_normalizations
821            .insert("dma_unmap_single", "DmaUnmap");
822
823        // Interrupts
824        self.call_normalizations
825            .insert("request_irq", "InterruptRegister");
826        self.call_normalizations
827            .insert("request_threaded_irq", "InterruptRegister");
828        self.call_normalizations
829            .insert("free_irq", "InterruptUnregister");
830        self.call_normalizations
831            .insert("disable_irq", "InterruptDisable");
832        self.call_normalizations
833            .insert("enable_irq", "InterruptEnable");
834
835        // Device registration
836        self.call_normalizations
837            .insert("pci_register_driver", "DeviceRegister");
838        self.call_normalizations
839            .insert("register_netdev", "DeviceRegister");
840        self.call_normalizations
841            .insert("register_chrdev", "DeviceRegister");
842        self.call_normalizations
843            .insert("device_register", "DeviceRegister");
844        self.call_normalizations
845            .insert("pci_unregister_driver", "DeviceUnregister");
846        self.call_normalizations
847            .insert("unregister_netdev", "DeviceUnregister");
848        self.call_normalizations
849            .insert("unregister_chrdev", "DeviceUnregister");
850        self.call_normalizations
851            .insert("device_unregister", "DeviceUnregister");
852
853        // Logging
854        self.call_normalizations.insert("printk", "Log");
855        self.call_normalizations.insert("pr_info", "Log");
856        self.call_normalizations.insert("pr_err", "Log");
857        self.call_normalizations.insert("pr_warn", "Log");
858        self.call_normalizations.insert("pr_debug", "Log");
859        self.call_normalizations.insert("dev_info", "Log");
860        self.call_normalizations.insert("dev_err", "Log");
861        self.call_normalizations.insert("dev_warn", "Log");
862        self.call_normalizations.insert("dev_dbg", "Log");
863    }
864}
865
866impl Default for LinuxPlatform {
867    fn default() -> Self {
868        Self::new()
869    }
870}
871
872impl PlatformModule for LinuxPlatform {
873    fn id(&self) -> &'static str {
874        "linux"
875    }
876
877    fn name(&self) -> &'static str {
878        "Linux Kernel"
879    }
880
881    fn detection_patterns(&self) -> Vec<DetectionPattern> {
882        vec![
883            // Include patterns - high weight
884            DetectionPattern::include("linux/", 3.0),
885            DetectionPattern::include("asm/", 1.5),
886            DetectionPattern::include("uapi/", 1.5),
887            // Macro patterns - very high weight for module macros
888            DetectionPattern::macro_pattern("MODULE_LICENSE", 4.0),
889            DetectionPattern::macro_pattern("MODULE_AUTHOR", 2.0),
890            DetectionPattern::macro_pattern("MODULE_DESCRIPTION", 2.0),
891            DetectionPattern::macro_pattern("module_init", 3.0),
892            DetectionPattern::macro_pattern("module_exit", 3.0),
893            DetectionPattern::macro_pattern("EXPORT_SYMBOL", 2.5),
894            DetectionPattern::macro_pattern("EXPORT_SYMBOL_GPL", 2.5),
895            DetectionPattern::macro_pattern("__init", 2.0),
896            DetectionPattern::macro_pattern("__exit", 2.0),
897            DetectionPattern::macro_pattern("CONFIG_", 1.0),
898            DetectionPattern::macro_pattern("KERN_INFO", 1.5),
899            DetectionPattern::macro_pattern("KERN_ERR", 1.5),
900            DetectionPattern::macro_pattern("GFP_KERNEL", 2.0),
901            // Function patterns
902            DetectionPattern::function_call("printk", 2.0),
903            DetectionPattern::function_call("kmalloc", 2.0),
904            DetectionPattern::function_call("kfree", 2.0),
905            DetectionPattern::function_call("kzalloc", 2.0),
906            DetectionPattern::function_call("copy_from_user", 2.5),
907            DetectionPattern::function_call("copy_to_user", 2.5),
908            // Type patterns
909            DetectionPattern::type_name("spinlock_t", 1.5),
910            DetectionPattern::type_name("atomic_t", 1.5),
911            DetectionPattern::type_name("wait_queue_head_t", 1.5),
912        ]
913    }
914
915    fn header_stubs(&self) -> &HeaderStubs {
916        &self.header_stubs
917    }
918
919    fn attributes_to_strip(&self) -> &[&'static str] {
920        &[
921            // Section/init attributes
922            "__init",
923            "__exit",
924            "__initdata",
925            "__exitdata",
926            "__initconst",
927            "__devinit",
928            "__devexit",
929            // Compiler hints
930            "__cold",
931            "__hot",
932            "__pure",
933            "__const",
934            "__noreturn",
935            "__malloc",
936            "__weak",
937            "__alias",
938            "__always_inline",
939            "__noinline",
940            "noinline",
941            "inline",
942            "__inline",
943            "__inline__",
944            "__section",
945            "__visible",
946            "__flatten",
947            // Address space annotations
948            "__user",
949            "__kernel",
950            "__iomem",
951            "__percpu",
952            "__rcu",
953            "__force",
954            "__bitwise",
955            "__safe",
956            // Unused/maybe annotations
957            "__maybe_unused",
958            "__always_unused",
959            "__unused",
960            // Packing and alignment
961            "__packed",
962            "__aligned",
963            "__cacheline_aligned",
964            "__cacheline_aligned_in_smp",
965            "__page_aligned_data",
966            "__page_aligned_bss",
967            // Deprecation
968            "__deprecated",
969            "__deprecated_for_modules",
970            // Locking annotations
971            "__must_check",
972            "__must_hold",
973            "__acquires",
974            "__releases",
975            "__acquire",
976            "__release",
977            "__cond_lock",
978            // Memory placement
979            "__read_mostly",
980            "__ro_after_init",
981            // Calling conventions
982            "asmlinkage",
983            "fastcall",
984            "regparm",
985        ]
986    }
987
988    fn ops_structs(&self) -> &[OpsStructDef] {
989        &self.ops_structs
990    }
991
992    fn call_normalizations(&self) -> &HashMap<&'static str, &'static str> {
993        &self.call_normalizations
994    }
995}
996
997#[cfg(test)]
998mod tests {
999    use super::*;
1000    use crate::platform::DetectionKind;
1001
1002    #[test]
1003    fn test_linux_platform_id() {
1004        let platform = LinuxPlatform::new();
1005        assert_eq!(platform.id(), "linux");
1006        assert_eq!(platform.name(), "Linux Kernel");
1007    }
1008
1009    #[test]
1010    fn test_linux_header_stubs() {
1011        let platform = LinuxPlatform::new();
1012        let stubs = platform.header_stubs();
1013
1014        assert!(stubs.has_stub("linux/types.h"));
1015        assert!(stubs.has_stub("linux/kernel.h"));
1016        assert!(stubs.has_stub("linux/module.h"));
1017        assert!(stubs.has_stub("linux/fs.h"));
1018        assert!(stubs.has_stub("linux/pci.h"));
1019        assert!(stubs.has_stub("linux/slab.h"));
1020    }
1021
1022    #[test]
1023    fn test_linux_stubs_content() {
1024        let platform = LinuxPlatform::new();
1025        let stubs = platform.header_stubs();
1026
1027        let source = "#include <linux/types.h>\n#include <linux/kernel.h>";
1028        let stub_content = stubs.get_for_includes(source);
1029
1030        // Should contain type definitions from linux/types.h
1031        assert!(stub_content.contains("typedef unsigned int u32"));
1032        assert!(stub_content.contains("typedef unsigned long long u64"));
1033
1034        // Should contain definitions from linux/kernel.h
1035        assert!(stub_content.contains("extern int printk"));
1036    }
1037
1038    #[test]
1039    fn test_linux_detection_patterns() {
1040        let platform = LinuxPlatform::new();
1041        let patterns = platform.detection_patterns();
1042
1043        // Should have include patterns
1044        let include_patterns: Vec<_> = patterns
1045            .iter()
1046            .filter(|p| p.kind == DetectionKind::Include)
1047            .collect();
1048        assert!(!include_patterns.is_empty());
1049
1050        // Should have macro patterns
1051        let macro_patterns: Vec<_> = patterns
1052            .iter()
1053            .filter(|p| p.kind == DetectionKind::Macro)
1054            .collect();
1055        assert!(!macro_patterns.is_empty());
1056
1057        // MODULE_LICENSE should have high weight
1058        let module_license = patterns
1059            .iter()
1060            .find(|p| p.pattern == "MODULE_LICENSE")
1061            .unwrap();
1062        assert!(module_license.weight >= 3.0);
1063    }
1064
1065    #[test]
1066    fn test_linux_attributes_to_strip() {
1067        let platform = LinuxPlatform::new();
1068        let attrs = platform.attributes_to_strip();
1069
1070        assert!(attrs.contains(&"__init"));
1071        assert!(attrs.contains(&"__exit"));
1072        assert!(attrs.contains(&"__user"));
1073        assert!(attrs.contains(&"__iomem"));
1074        assert!(attrs.contains(&"__must_check"));
1075    }
1076
1077    #[test]
1078    fn test_linux_ops_structs() {
1079        let platform = LinuxPlatform::new();
1080        let ops = platform.ops_structs();
1081
1082        // Should have file_operations
1083        let file_ops = ops.iter().find(|o| o.struct_name == "file_operations");
1084        assert!(file_ops.is_some());
1085        let file_ops = file_ops.unwrap();
1086
1087        // Check fields
1088        let open_field = file_ops.fields.iter().find(|f| f.name == "open");
1089        assert!(open_field.is_some());
1090        assert_eq!(open_field.unwrap().category, CallbackCategory::Open);
1091
1092        // Should have pci_driver
1093        let pci_driver = ops.iter().find(|o| o.struct_name == "pci_driver");
1094        assert!(pci_driver.is_some());
1095    }
1096
1097    #[test]
1098    fn test_linux_call_normalizations() {
1099        let platform = LinuxPlatform::new();
1100        let norms = platform.call_normalizations();
1101
1102        assert_eq!(norms.get("kmalloc"), Some(&"MemAlloc"));
1103        assert_eq!(norms.get("kfree"), Some(&"MemFree"));
1104        assert_eq!(norms.get("copy_from_user"), Some(&"CopyFromUser"));
1105        assert_eq!(norms.get("mutex_lock"), Some(&"LockAcquire"));
1106        assert_eq!(norms.get("printk"), Some(&"Log"));
1107    }
1108}