]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
fix: resolve all sparse static analysis warnings
authorTulio A M Mendes <[email protected]>
Mon, 6 Apr 2026 23:37:35 +0000 (20:37 -0300)
committerTulio A M Mendes <[email protected]>
Mon, 6 Apr 2026 23:37:35 +0000 (20:37 -0300)
- Replace plain integer 0 with NULL for pointer assignments, returns,
  and comparisons across 24 source files (kernel, drivers, HAL, arch, net)
- Add missing <stddef.h> includes for NULL in keyboard.c and uart.c
- Make file-local symbols static in idt.c (idt, idtp, interrupt_handlers,
  idt_set_gate, pic_remap, print_reg) and scheduler.c (ready_queue_tail)
- Add missing extern/prototype declarations to headers:
  idt.h (isr_handler), syscall.h (syscall_handler),
  process.h (ready_queue_head, sched_lock, sched_set_init_pid,
  sched_assign_pid1, sched_ap_init), net.h (net_dhcp_start),
  percpu.h (_percpu_gs_lut, percpu_get_ptr), smp.h (ap_sched_go,
  ap_entry), arch_syscall.h (x86_sysenter_set_kernel_stack,
  sysenter_init_ap), hal/usermode.h (x86_usermode_test_start),
  hal/cpu.h (g_smap_enabled), ata_pio.h (ata_register_devfs),
  boot_info.h (kernel_main)
- Add forward declarations for compiler ABI symbols in utils.c
- Include own headers in source files so sparse sees declarations
- Add lwIP/net include paths to SPARSE_FLAGS in Makefile

Verified: make check (0 warnings), make test-host (116/116 pass),
make test (102/103 pass, 1 pre-existing timeout)

42 files changed:
Makefile
include/arch/x86/idt.h
include/arch/x86/percpu.h
include/arch/x86/smp.h
include/arch_syscall.h
include/ata_pio.h
include/hal/cpu.h
include/hal/usermode.h
include/kernel/boot_info.h
include/net.h
include/process.h
include/syscall.h
src/arch/x86/idt.c
src/arch/x86/ioapic.c
src/arch/x86/lapic.c
src/arch/x86/sysenter_init.c
src/arch/x86/usermode.c
src/drivers/ata_pio.c
src/drivers/e1000.c
src/drivers/initrd.c
src/drivers/pci.c
src/drivers/vga_console.c
src/hal/x86/ata_pio.c
src/hal/x86/cpu_features.c
src/hal/x86/keyboard.c
src/hal/x86/pci.c
src/hal/x86/timer.c
src/hal/x86/uart.c
src/kernel/devfs.c
src/kernel/diskfs.c
src/kernel/kconsole.c
src/kernel/overlayfs.c
src/kernel/persistfs.c
src/kernel/pty.c
src/kernel/scheduler.c
src/kernel/sync.c
src/kernel/syscall.c
src/kernel/tmpfs.c
src/kernel/utils.c
src/kernel/vdso.c
src/net/dns.c
src/net/e1000_netif.c

index a89e0844f59dcc4ff39bd77fa6a1e5e7db17e6ac..c876038ecddac203dc1131bab57c2385eff96651 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -309,7 +309,7 @@ cppcheck:
                -I include $(SRC_DIR)
 
 # Sparse: kernel-oriented semantic checker (type safety, NULL, bitwise vs logical)
-SPARSE_FLAGS := -m32 -D__i386__ -D__linux__ -Iinclude
+SPARSE_FLAGS := -m32 -D__i386__ -D__linux__ -Iinclude -Iinclude/net -Ithird_party/lwip/src/include
 SPARSE_SRCS := $(filter-out $(wildcard $(SRC_DIR)/arch/arm/*.c) \
                              $(wildcard $(SRC_DIR)/arch/riscv/*.c) \
                              $(wildcard $(SRC_DIR)/arch/mips/*.c) \
index e0b31b4d957bf08d711a1c04f5b87383234ef8b3..23fba609d41e9c54fa563d7744ab69aa64f0d5e8 100644 (file)
@@ -47,4 +47,7 @@ typedef void (*isr_handler_t)(struct registers*);
 void register_interrupt_handler(uint8_t n, isr_handler_t handler);
 void unregister_interrupt_handler(uint8_t n, isr_handler_t handler);
 
+// Main ISR dispatch — called from assembly (interrupts.S)
+void isr_handler(struct registers* regs);
+
 #endif
index 795b609609b3cfa62749d5baa70ff3bfc3aa3b60..90576358a38622fb912af40c994c13dcf9428ee4 100644 (file)
@@ -63,4 +63,10 @@ static inline void percpu_set_current(struct process* proc) {
     __asm__ volatile("mov %0, %%gs:12" : : "r"(proc) : "memory");
 }
 
+/* GS selector lookup table indexed by LAPIC ID (used by interrupts.S). */
+extern uint16_t _percpu_gs_lut[256];
+
+/* Get percpu_data pointer for a specific CPU by index. */
+struct percpu_data* percpu_get_ptr(uint32_t cpu_index);
+
 #endif
index ceffca849d878ce4cca3c16e69006718ca2a6c5c..c64326ad596bd5e0754e6c6b0f303682d1337f56 100644 (file)
@@ -42,4 +42,10 @@ const struct cpu_info* smp_get_cpu(uint32_t index);
 /* Get the current CPU's index (based on LAPIC ID). */
 uint32_t smp_current_cpu(void);
 
+/* Flag set by BSP to signal APs that scheduling is ready. */
+extern volatile uint32_t ap_sched_go;
+
+/* AP C entry point (called from SMP trampoline assembly). */
+void ap_entry(void);
+
 #endif
index 07cbe946ea3630f17d3c9065bce19eaf44898815..8fc83cc86f33bf8daa94e059200c7dd0fb48c3f6 100644 (file)
@@ -58,4 +58,10 @@ extern uint32_t __arch_syscall_stub_sink;
  */
 void arch_syscall_init(void);
 
+#if defined(__i386__)
+/* x86 SYSENTER helpers */
+void x86_sysenter_set_kernel_stack(uintptr_t esp0);
+void sysenter_init_ap(uint32_t cpu_index);
+#endif
+
 #endif /* ARCH_SYSCALL_H */
index a70891fb15e0c7c45b14ae34a807fc1903e48155..63dbeffc2575c7aa9c8bc4bfee71959cf815921d 100644 (file)
@@ -43,4 +43,7 @@ int ata_name_to_drive(const char* name);
 /* Map drive ID to device name. Returns NULL if invalid. */
 const char* ata_drive_to_name(int drive);
 
+/* Register detected ATA drives in devfs (/dev/hdX). */
+void ata_register_devfs(void);
+
 #endif
index 31ceb7f44f7a61cf954668fcdfe6c9fd6aeff0b4..79ec0c1fc0089c83e783e9235d16e1be8e25b89d 100644 (file)
@@ -26,4 +26,7 @@ uint64_t hal_cpu_read_timestamp(void);
 
 void hal_cpu_set_tls(uintptr_t base);
 
+/* SMAP (Supervisor Mode Access Prevention) status — set by cpu_features init */
+extern int g_smap_enabled;
+
 #endif
index 9c5d8aeee57778cbc4cb62839a95d86e792a4e05..47e6fea1388f2a8132e121c108c2d47b87386d68 100644 (file)
@@ -16,4 +16,8 @@ int hal_usermode_enter(uintptr_t user_eip, uintptr_t user_esp);
 
 void hal_usermode_enter_regs(const void* regs);
 
+#if defined(__i386__)
+void x86_usermode_test_start(void);
+#endif
+
 #endif
index 3d2d9e2b3443060249061f713389390fbfd7b6ac..d30665badb9646e2a0106c416027fec19f08c75e 100644 (file)
@@ -30,4 +30,7 @@ struct boot_info {
     uint8_t   fb_type;      /* 0=indexed, 1=direct RGB (linear), 2=EGA text */
 };
 
+/* Kernel entry point (called from arch-specific boot code). */
+void kernel_main(const struct boot_info* bi);
+
 #endif
index 8c23729c1512c75301c77962ad7ab673be3b1948..2c92071fbb1cc416f202b16a137612fe3f0e83cd 100644 (file)
@@ -21,6 +21,9 @@ void net_poll(void);
 /* Get the active network interface (or NULL). */
 struct netif* net_get_netif(void);
 
+/* Start DHCP client on the active network interface. */
+void net_dhcp_start(void);
+
 /* Run ICMP ping test (sends echo requests to QEMU gateway 10.0.2.2). */
 void net_ping_test(void);
 
index 33294d452dd1616c2a0ad8f0b2613482febc25e0..2cfb4110079af95115c3a3d30593ccd303eb3fd7 100644 (file)
@@ -15,6 +15,7 @@
 #include "arch_fpu.h"
 #include "fs.h"
 #include "signal.h"
+#include "spinlock.h"
 
 /* clone() flags (Linux-compatible subset) */
 #define CLONE_VM        0x00000100  /* Share address space */
@@ -233,4 +234,13 @@ void sched_ap_tick(void);
 // Periodic load balancing: migrate one process from busiest to idlest CPU.
 void sched_load_balance(void);
 
+// Scheduler globals (used by procfs)
+extern struct process* ready_queue_head;
+extern spinlock_t sched_lock;
+
+// Scheduler init helpers (called from arch platform code)
+void sched_set_init_pid(uint32_t pid);
+void sched_assign_pid1(struct process* p);
+void sched_ap_init(uint32_t cpu);
+
 #endif
index 35e4e62fc8c763533c28d85af4446b68c7d70496..58d3ec8d3cb616e21f1c7b7ee334cf09832b1eb1 100644 (file)
@@ -12,7 +12,9 @@
 
 #include <stdint.h>
 
+struct registers;
 void syscall_init(void);
+void syscall_handler(struct registers* regs);
 
 enum {
     SYSCALL_WRITE = 1,
index 1f932187ad8417c7df0eadaf3ee8bbc3c2b63e18..c1a2015ad6c044dbd59827efce76479dee3bde52 100644 (file)
@@ -24,8 +24,8 @@
 #define IDT_ENTRIES 256
 #define IRQ_CHAIN_POOL_SIZE 32
 
-struct idt_entry idt[IDT_ENTRIES];
-struct idt_ptr idtp;
+static struct idt_entry idt[IDT_ENTRIES];
+static struct idt_ptr idtp;
 
 struct irq_chain_node {
     isr_handler_t handler;
@@ -37,17 +37,17 @@ static struct irq_chain_node* irq_chain_heads[IDT_ENTRIES];
 
 /* Legacy single-handler array kept for backward compatibility.
  * New registrations via register_interrupt_handler go through the chain. */
-isr_handler_t interrupt_handlers[IDT_ENTRIES];
+static isr_handler_t interrupt_handlers[IDT_ENTRIES];
 
 static spinlock_t idt_handlers_lock = {0};
 
 static struct irq_chain_node* irq_chain_alloc(void) {
     for (int i = 0; i < IRQ_CHAIN_POOL_SIZE; i++) {
-        if (irq_chain_pool[i].handler == 0) {
+        if (irq_chain_pool[i].handler == NULL) {
             return &irq_chain_pool[i];
         }
     }
-    return 0;
+    return NULL;
 }
 
 // Extern prototypes for Assembly stubs
@@ -68,7 +68,7 @@ extern void irq12(); extern void irq13(); extern void irq14(); extern void irq15
 extern void isr128();
 extern void isr255();
 
-void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
+static void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
     idt[num].base_lo = base & 0xFFFF;
     idt[num].base_hi = (base >> 16) & 0xFFFF;
     idt[num].sel     = sel;
@@ -215,7 +215,7 @@ static void deliver_signals_to_usermode(struct registers* regs) {
 }
 
 /* Reconfigure the PIC to remap IRQs from 0-15 to 32-47 */
-void pic_remap(void) {
+static void pic_remap(void) {
     uint8_t a1, a2;
 
     a1 = inb(0x21); // Save masks
@@ -344,10 +344,10 @@ void register_interrupt_handler(uint8_t n, isr_handler_t handler) {
         struct irq_chain_node* first = irq_chain_alloc();
         if (first) {
             first->handler = interrupt_handlers[n];
-            first->next = 0;
+            first->next = NULL;
             irq_chain_heads[n] = first;
         }
-        interrupt_handlers[n] = 0;
+        interrupt_handlers[n] = NULL;
     }
 
     /* Add new handler to chain */
@@ -366,7 +366,7 @@ void unregister_interrupt_handler(uint8_t n, isr_handler_t handler) {
 
     /* Check legacy slot */
     if (interrupt_handlers[n] == handler) {
-        interrupt_handlers[n] = 0;
+        interrupt_handlers[n] = NULL;
         spin_unlock_irqrestore(&idt_handlers_lock, flags);
         return;
     }
@@ -377,8 +377,8 @@ void unregister_interrupt_handler(uint8_t n, isr_handler_t handler) {
         if ((*pp)->handler == handler) {
             struct irq_chain_node* victim = *pp;
             *pp = victim->next;
-            victim->handler = 0;
-            victim->next = 0;
+            victim->handler = NULL;
+            victim->next = NULL;
             break;
         }
         pp = &(*pp)->next;
@@ -387,8 +387,8 @@ void unregister_interrupt_handler(uint8_t n, isr_handler_t handler) {
     /* If only one handler left in chain, migrate back to legacy slot */
     if (irq_chain_heads[n] && !irq_chain_heads[n]->next) {
         interrupt_handlers[n] = irq_chain_heads[n]->handler;
-        irq_chain_heads[n]->handler = 0;
-        irq_chain_heads[n] = 0;
+        irq_chain_heads[n]->handler = NULL;
+        irq_chain_heads[n] = NULL;
     }
 
     spin_unlock_irqrestore(&idt_handlers_lock, flags);
@@ -398,7 +398,7 @@ void unregister_interrupt_handler(uint8_t n, isr_handler_t handler) {
 
 // ... imports ...
 
-void print_reg(const char* name, uint32_t val) {
+static void print_reg(const char* name, uint32_t val) {
     kprintf("%s: %x  ", name, val);
 }
 
@@ -440,7 +440,7 @@ void isr_handler(struct registers* regs) {
             if (node->handler) node->handler(regs);
             node = node->next;
         }
-    } else if (interrupt_handlers[regs->int_no] != 0) {
+    } else if (interrupt_handlers[regs->int_no] != NULL) {
         isr_handler_t handler = interrupt_handlers[regs->int_no];
         handler(regs);
     } else {
index 2e48cd67a0a04c7bca84815283fabc339bd9614d..30b80b04f99cab66d0c2b6b5a97b1ce79925492b 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <stdint.h>
 
-static volatile uint32_t* ioapic_base = 0;
+static volatile uint32_t* ioapic_base = NULL;
 static int ioapic_active = 0;
 static uint8_t ioapic_max_irqs = 0;
 
@@ -107,7 +107,7 @@ void ioapic_route_irq_level(uint8_t irq, uint8_t vector, uint8_t lapic_id) {
 }
 
 void ioapic_mask_irq(uint8_t irq) {
-    if (!ioapic_active && ioapic_base == 0) return;
+    if (!ioapic_active && ioapic_base == NULL) return;
     if (irq >= IOAPIC_MAX_IRQS) return;
 
     uint32_t reg_lo = IOAPIC_REG_REDTBL + (uint32_t)irq * 2;
index bf6fb54a295304d2f2c953e1f8da34eed8f551ab..96eedc0bc4abefea6e2a7afa0adc926e5aa31c7f 100644 (file)
@@ -23,7 +23,7 @@
 #define IA32_APIC_BASE_ENABLE  (1U << 11)
 #define IA32_APIC_BASE_ADDR    0xFFFFF000U
 
-static volatile uint32_t* lapic_base = 0;
+static volatile uint32_t* lapic_base = NULL;
 static int lapic_active = 0;
 static uint32_t lapic_timer_ticks_saved = 0; /* BSP-calibrated ticks for AP reuse */
 
index 4fce3fcab785cc9ebf0949da12179eef373369c3..85a597f6618569492ee473159fcb1be6985374ec 100644 (file)
@@ -11,6 +11,7 @@
 #include "interrupts.h"
 #include "console.h"
 #include "arch/x86/smp.h"
+#include "arch_syscall.h"
 
 #include <stdint.h>
 
index a7171eecfa9304fdebc8d3d57e971d44bf2868cc..0810f2cb314951a3dbafd5d58e164e1f4f631601 100644 (file)
@@ -16,6 +16,7 @@
 #include "process.h"
 #include "utils.h"
 #include "arch/x86/usermode.h"
+#include "hal/usermode.h"
 #include "arch/x86/idt.h"
 
 #if defined(__i386__)
index d139db9d8e51018220a7d996a5407ba705aff74a..97b5842ffa04b317f2a051199c41d339910fa6d6 100644 (file)
@@ -34,7 +34,7 @@ __attribute__((weak))
 int ata_name_to_drive(const char* name) { (void)name; return -1; }
 
 __attribute__((weak))
-const char* ata_drive_to_name(int drive) { (void)drive; return 0; }
+const char* ata_drive_to_name(int drive) { (void)drive; return NULL; }
 
 __attribute__((weak))
 void ata_register_devfs(void) { }
index 5d912deffd66d82140f97c5c6b9647ab96ff7fca..504c3213f884a3ea4587a0a0d66ba694e8f7d0df 100644 (file)
@@ -29,7 +29,7 @@
 #define E1000_TX_BUF_VA    KVA_E1000_TX_BUF
 #define E1000_RX_BUF_VA    KVA_E1000_RX_BUF
 
-static volatile uint32_t* e1000_mmio = 0;
+static volatile uint32_t* e1000_mmio = NULL;
 static uint8_t e1000_mac[6];
 static int e1000_ready = 0;
 
index 8948676f2cfe06e402e98c7b309ab1ffd9fa32b5..64041a7e9e7ccd9a52867be44f173588aa1601be 100644 (file)
@@ -189,9 +189,9 @@ static uint32_t initrd_read_impl(fs_node_t* node, uint32_t offset, uint32_t size
 }
 
 static struct fs_node* initrd_finddir(struct fs_node* node, const char* name) {
-    if (!node || !name) return 0;
+    if (!node || !name) return NULL;
     int parent = (int)node->inode;
-    if (parent < 0 || parent >= entry_count) return 0;
+    if (parent < 0 || parent >= entry_count) return NULL;
 
     int c = entries[parent].first_child;
     while (c != -1) {
@@ -200,7 +200,7 @@ static struct fs_node* initrd_finddir(struct fs_node* node, const char* name) {
         }
         c = entries[c].next_sibling;
     }
-    return 0;
+    return NULL;
 }
 
 static const struct file_operations initrd_file_ops = {
@@ -305,14 +305,14 @@ fs_node_t* initrd_init(uint32_t location, uint32_t size) {
         decomp_buf = (uint8_t*)kmalloc(orig_sz);
         if (!decomp_buf) {
             kprintf("[INITRD] OOM decompressing LZ4 (%u bytes)\n", orig_sz);
-            return 0;
+            return NULL;
         }
 
         int ret = lz4_decompress_frame(raw, size, decomp_buf, orig_sz);
         if (ret < 0) {
             kprintf("[INITRD] LZ4 Frame decompress failed (ret=%d)\n", ret);
             kfree(decomp_buf);
-            return 0;
+            return NULL;
         }
 
         kprintf("[INITRD] LZ4: %u -> %d bytes\n", size, ret);
@@ -327,7 +327,7 @@ fs_node_t* initrd_init(uint32_t location, uint32_t size) {
         decomp_buf = (uint8_t*)kmalloc(orig_sz);
         if (!decomp_buf) {
             kprintf("[INITRD] OOM decompressing LZ4 (%u bytes)\n", orig_sz);
-            return 0;
+            return NULL;
         }
 
         int ret = lz4_decompress_block(raw + LZ4B_HDR_SIZE, comp_sz,
@@ -336,7 +336,7 @@ fs_node_t* initrd_init(uint32_t location, uint32_t size) {
             kprintf("[INITRD] LZ4 decompress failed (ret=%d, expected=%u)\n",
                     ret, orig_sz);
             kfree(decomp_buf);
-            return 0;
+            return NULL;
         }
 
         kprintf("[INITRD] LZ4: %u -> %u bytes\n", comp_sz, orig_sz);
@@ -349,7 +349,7 @@ fs_node_t* initrd_init(uint32_t location, uint32_t size) {
     entry_count = 0;
 
     int root = entry_alloc();
-    if (root < 0) { kfree(decomp_buf); return 0; }
+    if (root < 0) { kfree(decomp_buf); return NULL; }
     strcpy(entries[root].name, "");
     entries[root].flags = FS_DIRECTORY;
     entries[root].data_offset = 0;
index ce0896541493d16edce8624a4d5e33554ddc43d7..1b65a1b523aff75efc4f80585780d09e26b5f773 100644 (file)
@@ -30,10 +30,10 @@ __attribute__((weak))
 int pci_get_device_count(void) { return 0; }
 
 __attribute__((weak))
-const struct pci_device* pci_get_device(int index) { (void)index; return 0; }
+const struct pci_device* pci_get_device(int index) { (void)index; return NULL; }
 
 __attribute__((weak))
-const struct pci_device* pci_find_device(uint16_t vendor, uint16_t device) { (void)vendor; (void)device; return 0; }
+const struct pci_device* pci_find_device(uint16_t vendor, uint16_t device) { (void)vendor; (void)device; return NULL; }
 
 __attribute__((weak))
-const struct pci_device* pci_find_class(uint8_t class_code, uint8_t subclass) { (void)class_code; (void)subclass; return 0; }
+const struct pci_device* pci_find_class(uint8_t class_code, uint8_t subclass) { (void)class_code; (void)subclass; return NULL; }
index 81b672fd0c75f26490da1975d932f671661dd7ca..bfdf969f15826ea50f4a96a3b482afc66e0a1337 100644 (file)
@@ -13,7 +13,7 @@
 
 #include "spinlock.h"
 
-static volatile uint16_t* VGA_BUFFER = 0;
+static volatile uint16_t* VGA_BUFFER = NULL;
 #define VGA_WIDTH  80
 #define VGA_HEIGHT 25
 #define VGA_CELLS  (VGA_WIDTH * VGA_HEIGHT)
index 3eb967086833b4f8f1297579023649c15b4733ba..2d4ab22a8ff7f9c7e2c9759d5ffdcb3ddffdb2a4 100644 (file)
@@ -355,6 +355,6 @@ int ata_name_to_drive(const char* name) {
 }
 
 const char* ata_drive_to_name(int drive) {
-    if (drive < 0 || drive >= ATA_MAX_DRIVES) return 0;
+    if (drive < 0 || drive >= ATA_MAX_DRIVES) return NULL;
     return drive_names[drive];
 }
index cee149f2c1da078bb0b25fadfdec23248c0e9a90..8911176389dcd1a38bb5bb67964f18bd219fe254 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include "hal/cpu_features.h"
+#include "hal/cpu.h"
 #include "arch/x86/cpuid.h"
 #include "console.h"
 
index 5c3d759ac75cad0abd2bedae8f14d81293929e14..5a1faea27f5b47c65c390b2309d59e1dede28eee 100644 (file)
 #include "arch/x86/idt.h"
 #include "io.h"
 #include "vga_console.h"
+#include <stddef.h>
 
-static hal_keyboard_char_cb_t g_cb = 0;
-static hal_keyboard_scan_cb_t g_scan_cb = 0;
+static hal_keyboard_char_cb_t g_cb = NULL;
+static hal_keyboard_scan_cb_t g_scan_cb = NULL;
 
 /* Modifier state */
 static volatile int shift_held = 0;
index d6d15dcfd632650f6bb000a3ab3b8c24881b8e3d..58e9b38814d16397d84b6bf32d804af6d0c58991 100644 (file)
@@ -124,7 +124,7 @@ int pci_get_device_count(void) {
 }
 
 const struct pci_device* pci_get_device(int index) {
-    if (index < 0 || index >= pci_device_count) return 0;
+    if (index < 0 || index >= pci_device_count) return NULL;
     return &pci_devices[index];
 }
 
@@ -133,7 +133,7 @@ const struct pci_device* pci_find_device(uint16_t vendor, uint16_t device) {
         if (pci_devices[i].vendor_id == vendor && pci_devices[i].device_id == device)
             return &pci_devices[i];
     }
-    return 0;
+    return NULL;
 }
 
 const struct pci_device* pci_find_class(uint8_t class_code, uint8_t subclass) {
@@ -141,7 +141,7 @@ const struct pci_device* pci_find_class(uint8_t class_code, uint8_t subclass) {
         if (pci_devices[i].class_code == class_code && pci_devices[i].subclass == subclass)
             return &pci_devices[i];
     }
-    return 0;
+    return NULL;
 }
 
 /* HAL driver registration */
index 44e9a7794962482e401f86b96b8c85112fec33c7..30c865035ddbef0f9fad946c400a8ccffb10d0bc 100644 (file)
@@ -16,7 +16,7 @@
 #include "io.h"
 #include "console.h"
 
-static hal_timer_tick_cb_t g_tick_cb = 0;
+static hal_timer_tick_cb_t g_tick_cb = NULL;
 
 static void timer_irq(struct registers* regs) {
     (void)regs;
index 7ddadd1b7b961c22bfbbe945d77b5825f5e6a335..9b3c4eb5b0b6f24277f6e8cec46e4b383e0bbd87 100644 (file)
 #include "arch/x86/idt.h"
 
 #include <stdint.h>
+#include <stddef.h>
 
 #define UART_BASE 0x3F8
 
 static int uart_present = 0;
-static void (*uart_rx_cb)(char) = 0;
+static void (*uart_rx_cb)(char) = NULL;
 
 static void uart_irq_handler(struct registers* regs) {
     (void)regs;
index 8761841e7352776d4b38ffd447f88ad9189478d7..ce76c531857038c354fd58110143174dbddb4a80 100644 (file)
@@ -158,7 +158,7 @@ static int dev_always_ready_poll(fs_node_t* node, int events) {
 
 static struct fs_node* devfs_finddir_impl(struct fs_node* node, const char* name) {
     (void)node;
-    if (!name || name[0] == 0) return 0;
+    if (!name || name[0] == 0) return NULL;
 
     if (strcmp(name, "null") == 0) return &g_dev_null;
     if (strcmp(name, "zero") == 0) return &g_dev_zero;
@@ -169,7 +169,7 @@ static struct fs_node* devfs_finddir_impl(struct fs_node* node, const char* name
         if (strcmp(g_registered[i]->name, name) == 0)
             return g_registered[i];
     }
-    return 0;
+    return NULL;
 }
 
 static int devfs_readdir_impl(struct fs_node* node, uint32_t* inout_index, void* buf, uint32_t buf_len) {
index 818de00020b7422a5678f550c5a19a09145200f0..3072a90de7b6ebe4d993cf2112f0dc5a85989871 100644 (file)
@@ -506,23 +506,23 @@ static const struct inode_operations diskfs_dir_iops = {
 
 static struct fs_node* diskfs_root_finddir(struct fs_node* node, const char* name) {
     struct diskfs_node* parent = (struct diskfs_node*)node;
-    if (!g_ready) return 0;
-    if (!name || name[0] == 0) return 0;
-    if (!diskfs_segment_valid(name)) return 0;
+    if (!g_ready) return NULL;
+    if (!name || name[0] == 0) return NULL;
+    if (!diskfs_segment_valid(name)) return NULL;
 
     uint16_t parent_ino = parent ? parent->ino : 0;
 
     struct diskfs_super sb;
-    if (diskfs_super_load(&sb) < 0) return 0;
-    if (parent_ino >= DISKFS_MAX_INODES) return 0;
-    if (sb.inodes[parent_ino].type != DISKFS_INODE_DIR) return 0;
+    if (diskfs_super_load(&sb) < 0) return NULL;
+    if (parent_ino >= DISKFS_MAX_INODES) return NULL;
+    if (sb.inodes[parent_ino].type != DISKFS_INODE_DIR) return NULL;
 
     int child = diskfs_find_child(&sb, parent_ino, name);
-    if (child < 0) return 0;
+    if (child < 0) return NULL;
     uint16_t cino = (uint16_t)child;
 
     struct diskfs_node* dn = (struct diskfs_node*)kmalloc(sizeof(*dn));
-    if (!dn) return 0;
+    if (!dn) return NULL;
     memset(dn, 0, sizeof(*dn));
 
     strcpy(dn->vfs.name, name);
@@ -546,7 +546,7 @@ static struct fs_node* diskfs_root_finddir(struct fs_node* node, const char* nam
 
 int diskfs_open_file(const char* rel_path, uint32_t flags, fs_node_t** out_node) {
     if (!out_node) return -EINVAL;
-    *out_node = 0;
+    *out_node = NULL;
     if (!g_ready) return -ENODEV;
     if (!rel_path || rel_path[0] == 0) return -EINVAL;
 
@@ -644,7 +644,7 @@ int diskfs_unlink(const char* rel_path) {
     if (diskfs_super_load(&sb) < 0) return -EIO;
 
     uint16_t ino = 0;
-    int rc = diskfs_lookup_path(&sb, rel_path, &ino, 0, 0, 0);
+    int rc = diskfs_lookup_path(&sb, rel_path, &ino, NULL, NULL, 0);
     if (rc < 0) return rc;
     if (ino == 0) return -EPERM;
     if (ino >= DISKFS_MAX_INODES) return -EIO;
@@ -680,7 +680,7 @@ int diskfs_link(const char* old_rel, const char* new_rel) {
     if (diskfs_super_load(&sb) < 0) return -EIO;
 
     uint16_t old_ino = 0;
-    int rc = diskfs_lookup_path(&sb, old_rel, &old_ino, 0, 0, 0);
+    int rc = diskfs_lookup_path(&sb, old_rel, &old_ino, NULL, NULL, 0);
     if (rc < 0) return rc;
     if (old_ino >= DISKFS_MAX_INODES) return -EIO;
     if (sb.inodes[old_ino].type != DISKFS_INODE_FILE) return -EPERM;
@@ -695,7 +695,7 @@ int diskfs_link(const char* old_rel, const char* new_rel) {
 
     /* Check new name doesn't already exist */
     uint16_t dummy = 0;
-    if (diskfs_lookup_path(&sb, new_rel, &dummy, 0, 0, 0) == 0) return -EEXIST;
+    if (diskfs_lookup_path(&sb, new_rel, &dummy, NULL, NULL, 0) == 0) return -EEXIST;
 
     /* Find a free inode slot */
     uint16_t new_ino = 0;
@@ -728,7 +728,7 @@ int diskfs_rmdir(const char* rel_path) {
     if (diskfs_super_load(&sb) < 0) return -EIO;
 
     uint16_t ino = 0;
-    int rc = diskfs_lookup_path(&sb, rel_path, &ino, 0, 0, 0);
+    int rc = diskfs_lookup_path(&sb, rel_path, &ino, NULL, NULL, 0);
     if (rc < 0) return rc;
     if (ino == 0) return -EPERM;
     if (ino >= DISKFS_MAX_INODES) return -EIO;
@@ -753,7 +753,7 @@ int diskfs_rename(const char* old_rel, const char* new_rel) {
     if (diskfs_super_load(&sb) < 0) return -EIO;
 
     uint16_t src_ino = 0;
-    int rc = diskfs_lookup_path(&sb, old_rel, &src_ino, 0, 0, 0);
+    int rc = diskfs_lookup_path(&sb, old_rel, &src_ino, NULL, NULL, 0);
     if (rc < 0) return rc;
     if (src_ino == 0) return -EPERM;
     if (src_ino >= DISKFS_MAX_INODES) return -EIO;
@@ -849,7 +849,7 @@ int diskfs_getdents(uint16_t dir_ino, uint32_t* inout_index, void* out, uint32_t
 
 static int diskfs_vfs_create(struct fs_node* dir, const char* name, uint32_t flags, struct fs_node** out) {
     if (!dir || !name || !out) return -EINVAL;
-    *out = 0;
+    *out = NULL;
     if (!g_ready) return -ENODEV;
 
     struct diskfs_node* parent = (struct diskfs_node*)dir;
@@ -1098,5 +1098,5 @@ fs_node_t* diskfs_create_root(int drive) {
         }
     }
 
-    return g_ready ? &g_root.vfs : 0;
+    return g_ready ? &g_root.vfs : NULL;
 }
index 2046e6e5c3f3a50ec1a4064c51e00178cf943e1e..5ea18bdb671c348f37a6e9504e964f25bcc0aa34 100644 (file)
@@ -56,7 +56,7 @@ static void hist_add(const char* line) {
 
 static const char* hist_get(int idx) {
     /* idx 0 = most recent, 1 = second most recent, etc. */
-    if (idx < 0 || idx >= hist_count) return 0;
+    if (idx < 0 || idx >= hist_count) return NULL;
     int slot = (hist_head - 1 - idx + HIST_MAX) % HIST_MAX;
     return hist_buf[slot];
 }
@@ -446,7 +446,7 @@ static void kconsole_exec(const char* cmd) {
 /* ---- Main entry ---- */
 
 void kconsole_enter(void) {
-    keyboard_set_callback(0);
+    keyboard_set_callback(NULL);
 
     kc_puts("\n[PANIC] Userspace init failed -- dropping to kconsole.\n");
     kc_puts("        Type 'help' for commands, 'reboot' to restart.\n\n");
index f809832ea9fb6b432b260a505307f56462887d62..9ec13d2e56b48cf536c905b0e3fa8899d98a9c47 100644 (file)
@@ -247,8 +247,8 @@ static int overlay_readdir_impl(struct fs_node* node, uint32_t* inout_index, voi
 }
 
 static struct fs_node* overlay_finddir_impl(struct fs_node* node, const char* name) {
-    if (!node || !name) return 0;
-    if (node->flags != FS_DIRECTORY) return 0;
+    if (!node || !name) return NULL;
+    if (node->flags != FS_DIRECTORY) return NULL;
 
     struct overlay_node* dir = (struct overlay_node*)node;
 
@@ -260,7 +260,7 @@ static struct fs_node* overlay_finddir_impl(struct fs_node* node, const char* na
     if (dir->lower && dir->lower->i_ops && dir->lower->i_ops->lookup)
         lower_child = dir->lower->i_ops->lookup(dir->lower, name);
 
-    if (!upper_child && !lower_child) return 0;
+    if (!upper_child && !lower_child) return NULL;
     return overlay_wrap_child(dir, name, lower_child, upper_child);
 }
 
index c2e42b782d6dbc4e8ebb4ac634d78d271f92793c..efeab7aafde088f3dc54d80c084a8e3b5712fa0d 100644 (file)
@@ -33,8 +33,8 @@ static fs_node_t g_counter;
 static uint32_t g_ready = 0;
 
 static fs_node_t* persistfs_backing_open(uint32_t flags) {
-    fs_node_t* n = 0;
-    if (diskfs_open_file(PERSISTFS_BACKING_NAME, flags, &n) < 0) return 0;
+    fs_node_t* n = NULL;
+    if (diskfs_open_file(PERSISTFS_BACKING_NAME, flags, &n) < 0) return NULL;
     return n;
 }
 
@@ -75,9 +75,9 @@ static uint32_t persist_counter_write(fs_node_t* node, uint32_t offset, uint32_t
 
 static struct fs_node* persist_root_finddir(struct fs_node* node, const char* name) {
     (void)node;
-    if (!name || name[0] == 0) return 0;
+    if (!name || name[0] == 0) return NULL;
     if (strcmp(name, "counter") == 0) return &g_counter;
-    return 0;
+    return NULL;
 }
 
 static const struct file_operations persistfs_root_fops = {0};
@@ -134,5 +134,5 @@ fs_node_t* persistfs_create_root(int drive) {
         g_counter.f_ops = &persistfs_counter_fops;
     }
 
-    return g_ready ? &g_root : 0;
+    return g_ready ? &g_root : NULL;
 }
index 79b931b551d5c63ee729dcf3ea9b54db006eb043..df2311423a4b7decd1a160e01033d704f997f30a 100644 (file)
@@ -188,7 +188,7 @@ static uint32_t pty_ptmx_write_fn(fs_node_t* node, uint32_t offset, uint32_t siz
 
 static struct fs_node* pty_pts_finddir(struct fs_node* node, const char* name) {
     (void)node;
-    if (!name || name[0] == 0) return 0;
+    if (!name || name[0] == 0) return NULL;
     int count = pty_pair_count();
     for (int i = 0; i < count; i++) {
         char num[4];
@@ -198,7 +198,7 @@ static struct fs_node* pty_pts_finddir(struct fs_node* node, const char* name) {
             return pty_get_slave_node(i);
         }
     }
-    return 0;
+    return NULL;
 }
 
 static int pty_pts_readdir(struct fs_node* node, uint32_t* inout_index, void* buf, uint32_t buf_len) {
index b3d8db35949b13068f20e82d1f7841f836e71dc9..7edfe9514c2f54c9351516058c514e09efb664c1 100644 (file)
@@ -27,7 +27,7 @@
 struct process* current_process = NULL;
 #endif
 struct process* ready_queue_head = NULL;
-struct process* ready_queue_tail = NULL;
+static struct process* ready_queue_tail = NULL;
 static uint32_t next_pid = 2;  /* PID 1 reserved for init */
 static uint32_t init_pid = 0;  /* PID of the first userspace process ("init") */
 
index d7f42aa3f2fcb7edec7e31b9ebe803dec0ff48ec..89455c08da8bbadab1de73d1b55c24ae2419a3b0 100644 (file)
@@ -27,7 +27,7 @@ void ksem_init(ksem_t* s, int32_t initial_count) {
     s->count = initial_count;
     s->nwaiters = 0;
     for (uint32_t i = 0; i < KSEM_MAX_WAITERS; i++)
-        s->waiters[i] = 0;
+        s->waiters[i] = NULL;
 }
 
 void ksem_wait(ksem_t* s) {
@@ -78,7 +78,7 @@ int ksem_wait_timeout(ksem_t* s, uint32_t timeout_ms) {
             /* We timed out — remove from list */
             for (uint32_t j = i; j + 1 < s->nwaiters; j++)
                 s->waiters[j] = s->waiters[j + 1];
-            s->waiters[--s->nwaiters] = 0;
+            s->waiters[--s->nwaiters] = NULL;
             found = 1;
             break;
         }
@@ -103,7 +103,7 @@ void ksem_signal(ksem_t* s) {
             /* Remove from waiters list */
             for (uint32_t j = i; j + 1 < s->nwaiters; j++)
                 s->waiters[j] = s->waiters[j + 1];
-            s->waiters[--s->nwaiters] = 0;
+            s->waiters[--s->nwaiters] = NULL;
 
             p->state = PROCESS_READY;
             p->wake_at_tick = 0;
@@ -158,7 +158,7 @@ int kmbox_init(kmbox_t* mb, uint32_t size) {
     mb->count = 0;
     mb->capacity = size;
     for (uint32_t i = 0; i < KMBOX_MAX_MSGS; i++)
-        mb->msgs[i] = 0;
+        mb->msgs[i] = NULL;
 
     ksem_init(&mb->not_empty, 0);
     ksem_init(&mb->not_full, (int32_t)size);
@@ -248,7 +248,7 @@ void kcond_init(kcond_t* cv) {
     spinlock_init(&cv->lock);
     cv->nwaiters = 0;
     for (uint32_t i = 0; i < KCOND_MAX_WAITERS; i++)
-        cv->waiters[i] = 0;
+        cv->waiters[i] = NULL;
 }
 
 int kcond_wait(kcond_t* cv, kmutex_t* mtx, uint32_t timeout_ms) {
@@ -287,7 +287,7 @@ int kcond_wait(kcond_t* cv, kmutex_t* mtx, uint32_t timeout_ms) {
         if (cv->waiters[i] == current_process) {
             for (uint32_t j = i; j + 1 < cv->nwaiters; j++)
                 cv->waiters[j] = cv->waiters[j + 1];
-            cv->waiters[--cv->nwaiters] = 0;
+            cv->waiters[--cv->nwaiters] = NULL;
             found = 1;
             break;
         }
@@ -308,7 +308,7 @@ void kcond_signal(kcond_t* cv) {
         if (p && (p->state == PROCESS_BLOCKED || p->state == PROCESS_SLEEPING)) {
             for (uint32_t j = i; j + 1 < cv->nwaiters; j++)
                 cv->waiters[j] = cv->waiters[j + 1];
-            cv->waiters[--cv->nwaiters] = 0;
+            cv->waiters[--cv->nwaiters] = NULL;
 
             p->state = PROCESS_READY;
             p->wake_at_tick = 0;
@@ -338,7 +338,7 @@ void kcond_broadcast(kcond_t* cv) {
             p->state = PROCESS_READY;
             p->wake_at_tick = 0;
             wake_list[wake_count++] = p;
-            cv->waiters[i] = 0;
+            cv->waiters[i] = NULL;
         }
     }
     cv->nwaiters = 0;
index 297f61c38a439dca051b234d02d4213b1015a035..863430640885f442a72a889042d9d1c99dacc0ab 100644 (file)
@@ -4228,7 +4228,7 @@ static void posix_ext_syscall_dispatch(struct registers* regs, uint32_t syscall_
             current_process->state = PROCESS_SLEEPING;
             current_process->wake_at_tick = get_tick_count() + 5000; /* 100s timeout */
             schedule();
-            futex_waiters[slot].proc = 0;
+            futex_waiters[slot].proc = NULL;
             futex_waiters[slot].addr = 0;
             sc_ret(regs) = 0;
             return;
@@ -4241,7 +4241,7 @@ static void posix_ext_syscall_dispatch(struct registers* regs, uint32_t syscall_
             for (int i = 0; i < FUTEX_MAX_WAITERS && woken < max_wake; i++) {
                 if (futex_waiters[i].proc && futex_waiters[i].addr == (uintptr_t)uaddr) {
                     futex_waiters[i].proc->state = PROCESS_READY;
-                    futex_waiters[i].proc = 0;
+                    futex_waiters[i].proc = NULL;
                     futex_waiters[i].addr = 0;
                     woken++;
                 }
index 8077a9ecfb638f0fff0a764a32947b031e204771..dda880d6fe69abeff234963379d9c0895e8298a3 100644 (file)
@@ -168,12 +168,12 @@ static uint32_t tmpfs_write_impl(fs_node_t* node, uint32_t offset, uint32_t size
 }
 
 static struct fs_node* tmpfs_finddir_impl(struct fs_node* node, const char* name) {
-    if (!node || !name) return 0;
-    if (node->flags != FS_DIRECTORY) return 0;
+    if (!node || !name) return NULL;
+    if (node->flags != FS_DIRECTORY) return NULL;
 
     struct tmpfs_node* dir = (struct tmpfs_node*)node;
     struct tmpfs_node* child = tmpfs_child_find(dir, name);
-    if (!child) return 0;
+    if (!child) return NULL;
     return &child->vfs;
 }
 
index 91042aeade396761b82b532d5380730e44ef623c..808c2dcf1be24ce1a2cbbbdf9ae355f4c7dcebd6 100644 (file)
@@ -9,6 +9,10 @@
 
 #include "utils.h"
 
+/* Forward declarations for compiler ABI symbols (not in any header) */
+void* __memcpy_chk(void* dst, const void* src, size_t n, size_t dst_len);
+const unsigned short** __ctype_b_loc(void);
+
 size_t strlen(const char* str) {
     size_t len = 0;
     while (str[len])
index 0f5f2aab6fb077a4af3d3027e6432e29af0d7844..b4405ae90fa425145da1627f548fc98107d9265f 100644 (file)
@@ -15,7 +15,7 @@
 #include "console.h"
 
 static uintptr_t vdso_phys = 0;
-static volatile struct vdso_data* vdso_kptr = 0;
+static volatile struct vdso_data* vdso_kptr = NULL;
 
 void vdso_init(void) {
     void* page = pmm_alloc_page();
index e2bbf609c0614707af5397196802052802c7c281..f3db4eac208fa5d62373d363a91083b59ddab9cf 100644 (file)
@@ -46,7 +46,7 @@ int dns_resolve(const char* hostname, uint32_t* out_ip) {
     dns_done = 0;
     dns_result_ip = 0;
 
-    err_t err = dns_gethostbyname(hostname, &resolved, dns_found_cb, 0);
+    err_t err = dns_gethostbyname(hostname, &resolved, dns_found_cb, NULL);
     if (err == ERR_OK) {
         /* Already cached */
         *out_ip = ip4_addr_get_u32(ip_2_ip4(&resolved));
index d8d48d3e6f10ec436321355df36205733236bdeb..4301452753cf7c0311231c9f8be0040e67fd1fe2 100644 (file)
@@ -14,6 +14,7 @@
  * RX path:  interrupt → e1000_rx_sem → rx_thread → e1000_recv → tcpip_input
  * TX path:  lwIP core → e1000_netif_output → e1000_send (non-blocking)
  */
+#include "net.h"
 #include "lwip/opt.h"
 #include "lwip/netif.h"
 #include "lwip/pbuf.h"