make BUG preserve registers
PATCH 1/1 make BUG preserve registers
Final version (I hope) of the BUG patch. It still will offend the disassembler (sorry, Hugh).
CONFIG_DEBUG_BUGVERBOSE has disappeared again.
include/asm-i386/page.h +9 -7
@@ -91,16 +91,18 @@ typedef struct { unsigned long pgprot; }/* * Tell the user there is some problem. Beep too, so we can * see^H^H^Hhear bugs in early bootup as well! +* The offending file and line are encoded after the "officially +* undefined" opcode for parsing in the trap handler. */ -#ifdef CONFIG_DEBUG_BUGVERBOSE -extern void do_BUG (const char *file,int line); -#define BUG () do { \ - do_BUG(__FILE__, __LINE__); \ - __asm__ __volatile__("ud2"); \ -} while (0) +#if 1 /* Set to zero for a slightly smaller kernel */ +#define BUG () \ + __asm__ __volatile__( "ud2\n" \ + "\t.word %c0\n" \ + "\t.long %c1\n" \ + : : "i" (__LINE__), "i" (__FILE__))#else -#define BUG () __asm__ __volatile__(".byte 0x0f,0x0b") +#define BUG () __asm__ __volatile__("ud2\n")#endif #define PAGE_BUG (page) do { \
arch/i386/kernel/traps.c +36 -0
@@ -237,6 +237,41 @@ bad:printk ("\n" ); } +static void handle_BUG (struct pt_regs *regs) +{ +unsigned short ud2; +unsigned short line; +char *file; +char c; +unsigned long eip; + +if (regs->xcs &3 ) + goto no_bug;/* Not in kernel */ + + eip = regs->eip; + +if (eip <PAGE_OFFSET ) + goto no_bug; +if (__get_user (ud2, (unsigned short *)eip)) + goto no_bug; +if (ud2 !=0x0b0f ) + goto no_bug; +if (__get_user (line, (unsigned short *)(eip +2 ))) + goto bug; +if (__get_user (file, (char **)(eip +4 )) || + (unsigned long )file <PAGE_OFFSET ||__get_user (c, file)) + file ="<bad filename>" ; + +printk ("kernel BUG at %s:%d!\n" , file, line); + +no_bug: +return ; + +/* Here we know it was a BUG but file-n-line is unavailable */ +bug: +printk ("Kernel BUG\n" ); +} +spinlock_t die_lock =SPIN_LOCK_UNLOCKED ;void die (const char * str,struct pt_regs * regs,long err)
@@ -244,6 +279,7 @@ void die(const char * str, struct pt_regconsole_verbose ();spin_lock_irq (&die_lock);bust_spinlocks (1 ); +handle_BUG (regs);printk ("%s: %04lx\n" , str, err &0xffff );show_registers (regs);bust_spinlocks (0 );
arch/i386/kernel/i386_ksyms.c +0 -4
@@ -168,9 +168,5 @@ EXPORT_SYMBOL_NOVERS(memset);EXPORT_SYMBOL (atomic_dec_and_lock);#endif -#ifdef CONFIG_DEBUG_BUGVERBOSE -EXPORT_SYMBOL (do_BUG); -#endif -extern int is_sony_vaio_laptop;EXPORT_SYMBOL (is_sony_vaio_laptop);
arch/i386/config.in +0 -1
@@ -421,7 +421,6 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; th bool ' Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK - bool ' Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE fi endmenu
arch/i386/mm/fault.c +0 -6
@@ -125,12 +125,6 @@ void bust_spinlocks(int yes) } } -void do_BUG (const char *file,int line) -{ -bust_spinlocks (1 ); -printk ("kernel BUG at %s:%d!\n" , file, line); -} - asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);extern unsigned long idt;
-