#include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/bug.h>
 
 #if 0
 #define DEBUGP printk
                apply_paravirt(pseg, pseg + para->sh_size);
        }
 
-       return 0;
+       return module_bug_finalize(hdr, sechdrs, me);
 }
 
 void module_arch_cleanup(struct module *mod)
 {
        alternatives_smp_module_del(mod);
+       module_bug_cleanup(mod);
 }
 
 #include <linux/unwind.h>
 #include <linux/uaccess.h>
 #include <linux/nmi.h>
+#include <linux/bug.h>
 
 #ifdef CONFIG_EISA
 #include <linux/ioport.h>
        printk("\n");
 }      
 
-static void handle_BUG(struct pt_regs *regs)
+int is_valid_bugaddr(unsigned long eip)
 {
-       unsigned long eip = regs->eip;
        unsigned short ud2;
 
        if (eip < PAGE_OFFSET)
-               return;
+               return 0;
        if (probe_kernel_address((unsigned short *)eip, ud2))
-               return;
-       if (ud2 != 0x0b0f)
-               return;
-
-       printk(KERN_EMERG "------------[ cut here ]------------\n");
-
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-       do {
-               unsigned short line;
-               char *file;
-               char c;
-
-               if (probe_kernel_address((unsigned short *)(eip + 2), line))
-                       break;
-               if (probe_kernel_address((char **)(eip + 4), file) ||
-                   (unsigned long)file < PAGE_OFFSET ||
-                       probe_kernel_address(file, c))
-                       file = "<bad filename>";
+               return 0;
 
-               printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
-               return;
-       } while (0);
-#endif
-       printk(KERN_EMERG "Kernel BUG at [verbose debug info unavailable]\n");
+       return ud2 == 0x0b0f;
 }
 
-/* This is gone through when something in the kernel
- * has done something bad and is about to be terminated.
-*/
+/*
+ * This is gone through when something in the kernel has done something bad and
+ * is about to be terminated.
+ */
 void die(const char * str, struct pt_regs * regs, long err)
 {
        static struct {
                unsigned long esp;
                unsigned short ss;
 
-               handle_BUG(regs);
+               report_bug(regs->eip);
+
                printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
 #ifdef CONFIG_PREEMPT
                printk(KERN_EMERG "PREEMPT ");
 
 
 /*
  * Tell the user there is some problem.
- * The offending file and line are encoded after the "officially
- * undefined" opcode for parsing in the trap handler.
+ * The offending file and line are encoded encoded in the __bug_table section.
  */
 
 #ifdef CONFIG_BUG
 #define HAVE_ARCH_BUG
+
 #ifdef CONFIG_DEBUG_BUGVERBOSE
-#define BUG()                          \
- __asm__ __volatile__( "ud2\n"         \
-                       "\t.word %c0\n" \
-                       "\t.long %c1\n" \
-                        : : "i" (__LINE__), "i" (__FILE__))
+#define BUG()                                                          \
+       do {                                                            \
+               asm volatile("1:\tud2\n"                                \
+                            ".pushsection __bug_table,\"a\"\n"         \
+                            "2:\t.long 1b, %c0\n"                      \
+                            "\t.word %c1, 0\n"                         \
+                            "\t.org 2b+%c2\n"                          \
+                            ".popsection"                              \
+                            : : "i" (__FILE__), "i" (__LINE__),        \
+                            "i" (sizeof(struct bug_entry)));           \
+               for(;;) ;                                               \
+       } while(0)
+
 #else
-#define BUG() __asm__ __volatile__("ud2\n")
+#define BUG()                                                          \
+       do {                                                            \
+               asm volatile("ud2");                                    \
+               for(;;) ;                                               \
+       } while(0)
 #endif
 #endif
 
 
 config DEBUG_BUGVERBOSE
        bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
        depends on BUG
-       depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || X86_32 || FRV || SUPERH || GENERIC_BUG
+       depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || FRV || SUPERH || GENERIC_BUG
        default !EMBEDDED
        help
          Say Y here to make BUG() panics output the file name and line number