-diff -urNp linux-700/arch/i386/config.in linux-720/arch/i386/config.in
---- linux-700/arch/i386/config.in
-+++ linux-720/arch/i386/config.in
-@@ -9,8 +9,6 @@ define_bool CONFIG_SBUS n
-
- define_bool CONFIG_UID16 y
-
-+define_bool CONFIG_KALLSYMS y
-+
- mainmenu_option next_comment
- comment 'Code maturity level options'
- bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
diff -urNp linux-700/arch/i386/kernel/process.c linux-720/arch/i386/kernel/process.c
--- linux-700/arch/i386/kernel/process.c
+++ linux-720/arch/i386/kernel/process.c
+#endif
+}
diff -urNp linux-700/kernel/Makefile linux-720/kernel/Makefile
---- linux-700/kernel/Makefile 2001-09-17 06:22:40.000000000 +0200
+--- linux-700/kernel/Makefile 2001-09-17 06:22:40.000000000 +0800
+++ linux-720/kernel/Makefile
-@@ -14,7 +14,7 @@ export-objs = signal.o sys.o kmod.o cont
+@@ -14,11 +14,13 @@ export-objs = signal.o sys.o kmod.o cont
obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
module.o exit.o itimer.o info.o time.o softirq.o resource.o \
sysctl.o acct.o capability.o ptrace.o timer.o user.o \
- signal.o sys.o kmod.o context.o
-+ signal.o sys.o kmod.o context.o kksymoops.o
++ signal.o sys.o kmod.o context.o kksymoops.o kallsyms.o
obj-$(CONFIG_UID16) += uid16.o
obj-$(CONFIG_MODULES) += ksyms.o
+ obj-$(CONFIG_PM) += pm.o
++obj-$(CONFIG_KALLSYMS) += kksymoops.o
++obj-$(CONFIG_KALLSYMS) += kallsyms.o
+
+ ifneq ($(CONFIG_IA64),y)
+ # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
+diff -urNp arch/i386/config.in linux-720/arch/i386/config.in
+--- /arch/i386/config.in 2004-06-15 16:58:41.000000000 +0800
++++ /linux-720/arch/i386/config.in
+@@ -8,6 +8,7 @@
+ define_bool CONFIG_SBUS n
+
+ define_bool CONFIG_UID16 y
++define_bool CONFIG_KALLSYMS y
+
+ mainmenu_option next_comment
+ comment 'Code maturity level options'
+diff -urNp include/linux/kallsyms.h linux-700/include/linux/kallsyms.h.orig
+--- /include/linux/kallsyms.h Thu Sep 26 15:27:16 2002
++++ /linux-700/include/linux/kallsyms.h.orig Thu Sep 26 15:27:16 2002
+@@ -0,0 +1,163 @@
++/* kallsyms headers
++ Copyright 2000 Keith Owens <kaos@ocs.com.au>
++
++ This file is part of the Linux modutils. It is exported to kernel
++ space so debuggers can access the kallsyms data.
++
++ The kallsyms data contains all the non-stack symbols from a kernel
++ or a module. The kernel symbols are held between __start___kallsyms
++ and __stop___kallsyms. The symbols for a module are accessed via
++ the struct module chain which is based at module_list.
++
++ This program is free software; you can redistribute it and/or modify it
++ under the terms of the GNU General Public License as published by the
++ Free Software Foundation; either version 2 of the License, or (at your
++ option) any later version.
++
++ This program is distributed in the hope that it will be useful, but
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software Foundation,
++ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++#ident "$Id: kksymoops-2.4.24.vanilla.patch,v 1.3 2004/06/24 03:58:32 houfeng Exp $"
++
++#ifndef MODUTILS_KALLSYMS_H
++#define MODUTILS_KALLSYMS_H 1
++
++/* Have to (re)define these ElfW entries here because external kallsyms
++ * code does not have access to modutils/include/obj.h. This code is
++ * included from user spaces tools (modutils) and kernel, they need
++ * different includes.
++ */
++
++#ifndef ELFCLASS32
++#ifdef __KERNEL__
++#include <linux/elf.h>
++#else /* __KERNEL__ */
++#include <elf.h>
++#endif /* __KERNEL__ */
++#endif /* ELFCLASS32 */
++
++#ifndef ELFCLASSM
++#define ELFCLASSM ELF_CLASS
++#endif
++
++#ifndef ElfW
++# if ELFCLASSM == ELFCLASS32
++# define ElfW(x) Elf32_ ## x
++# define ELFW(x) ELF32_ ## x
++# else
++# define ElfW(x) Elf64_ ## x
++# define ELFW(x) ELF64_ ## x
++# endif
++#endif
++
++/* Format of data in the kallsyms section.
++ * Most of the fields are small numbers but the total size and all
++ * offsets can be large so use the 32/64 bit types for these fields.
++ *
++ * Do not use sizeof() on these structures, modutils may be using extra
++ * fields. Instead use the size fields in the header to access the
++ * other bits of data.
++ */
++
++struct kallsyms_header {
++ int size; /* Size of this header */
++ ElfW(Word) total_size; /* Total size of kallsyms data */
++ int sections; /* Number of section entries */
++ ElfW(Off) section_off; /* Offset to first section entry */
++ int section_size; /* Size of one section entry */
++ int symbols; /* Number of symbol entries */
++ ElfW(Off) symbol_off; /* Offset to first symbol entry */
++ int symbol_size; /* Size of one symbol entry */
++ ElfW(Off) string_off; /* Offset to first string */
++ ElfW(Addr) start; /* Start address of first section */
++ ElfW(Addr) end; /* End address of last section */
++};
++
++struct kallsyms_section {
++ ElfW(Addr) start; /* Start address of section */
++ ElfW(Word) size; /* Size of this section */
++ ElfW(Off) name_off; /* Offset to section name */
++ ElfW(Word) flags; /* Flags from section */
++};
++
++struct kallsyms_symbol {
++ ElfW(Off) section_off; /* Offset to section that owns this symbol */
++ ElfW(Addr) symbol_addr; /* Address of symbol */
++ ElfW(Off) name_off; /* Offset to symbol name */
++};
++
++#define KALLSYMS_SEC_NAME "__kallsyms"
++#define KALLSYMS_IDX 2 /* obj_kallsyms creates kallsyms as section 2 */
++
++#define kallsyms_next_sec(h,s) \
++ ((s) = (struct kallsyms_section *)((char *)(s) + (h)->section_size))
++#define kallsyms_next_sym(h,s) \
++ ((s) = (struct kallsyms_symbol *)((char *)(s) + (h)->symbol_size))
++
++#ifdef CONFIG_KALLSYMS
++
++int kallsyms_symbol_to_address(
++ const char *name, /* Name to lookup */
++ unsigned long *token, /* Which module to start with */
++ const char **mod_name, /* Set to module name or "kernel" */
++ unsigned long *mod_start, /* Set to start address of module */
++ unsigned long *mod_end, /* Set to end address of module */
++ const char **sec_name, /* Set to section name */
++ unsigned long *sec_start, /* Set to start address of section */
++ unsigned long *sec_end, /* Set to end address of section */
++ const char **sym_name, /* Set to full symbol name */
++ unsigned long *sym_start, /* Set to start address of symbol */
++ unsigned long *sym_end /* Set to end address of symbol */
++ );
++
++int kallsyms_address_to_symbol(
++ unsigned long address, /* Address to lookup */
++ const char **mod_name, /* Set to module name */
++ unsigned long *mod_start, /* Set to start address of module */
++ unsigned long *mod_end, /* Set to end address of module */
++ const char **sec_name, /* Set to section name */
++ unsigned long *sec_start, /* Set to start address of section */
++ unsigned long *sec_end, /* Set to end address of section */
++ const char **sym_name, /* Set to full symbol name */
++ unsigned long *sym_start, /* Set to start address of symbol */
++ unsigned long *sym_end /* Set to end address of symbol */
++ );
++
++int kallsyms_sections(void *token,
++ int (*callback)(void *, /* token */
++ const char *, /* module name */
++ const char *, /* section name */
++ ElfW(Addr), /* Section start */
++ ElfW(Addr), /* Section end */
++ ElfW(Word) /* Section flags */
++ )
++ );
++
++#else
++
++static inline int kallsyms_address_to_symbol(
++ unsigned long address, /* Address to lookup */
++ const char **mod_name, /* Set to module name */
++ unsigned long *mod_start, /* Set to start address of module */
++ unsigned long *mod_end, /* Set to end address of module */
++ const char **sec_name, /* Set to section name */
++ unsigned long *sec_start, /* Set to start address of section */
++ unsigned long *sec_end, /* Set to end address of section */
++ const char **sym_name, /* Set to full symbol name */
++ unsigned long *sym_start, /* Set to start address of symbol */
++ unsigned long *sym_end /* Set to end address of symbol */
++ )
++{
++ return -ESRCH;
++}
++
++#endif
++
++#endif /* kallsyms.h */
+--- linux/kernel/kallsyms.c.orig Thu Sep 26 15:27:16 2002
++++ linux/kernel/kallsyms.c Thu Sep 26 15:27:16 2002
+@@ -0,0 +1,227 @@
++/*
++ * kksymoops.c: in-kernel printing of symbolic oopses and stack traces.
++ *
++ * Copyright 2000 Keith Owens <kaos@ocs.com.au> April 2000
++ * Copyright 2002 Arjan van de Ven <arjanv@redhat.com>
++ *
++ This code uses the list of all kernel and module symbols to :-
++
++ * Find any non-stack symbol in a kernel or module. Symbols do
++ not have to be exported for debugging.
++
++ * Convert an address to the module (or kernel) that owns it, the
++ section it is in and the nearest symbol. This finds all non-stack
++ symbols, not just exported ones.
++
++ */
++
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/kallsyms.h>
++
++/* A symbol can appear in more than one module. A token is used to
++ * restart the scan at the next module, set the token to 0 for the
++ * first scan of each symbol.
++ */
++
++int kallsyms_symbol_to_address(
++ const char *name, /* Name to lookup */
++ unsigned long *token, /* Which module to start at */
++ const char **mod_name, /* Set to module name */
++ unsigned long *mod_start, /* Set to start address of module */
++ unsigned long *mod_end, /* Set to end address of module */
++ const char **sec_name, /* Set to section name */
++ unsigned long *sec_start, /* Set to start address of section */
++ unsigned long *sec_end, /* Set to end address of section */
++ const char **sym_name, /* Set to full symbol name */
++ unsigned long *sym_start, /* Set to start address of symbol */
++ unsigned long *sym_end /* Set to end address of symbol */
++ )
++{
++ const struct kallsyms_header *ka_hdr = NULL; /* stupid gcc */
++ const struct kallsyms_section *ka_sec;
++ const struct kallsyms_symbol *ka_sym = NULL;
++ const char *ka_str = NULL;
++ const struct module *m;
++ int i = 0, l;
++ const char *p, *pt_R;
++ char *p2;
++
++ /* Restart? */
++ m = module_list;
++ if (token && *token) {
++ for (; m; m = m->next)
++ if ((unsigned long)m == *token)
++ break;
++ if (m)
++ m = m->next;
++ }
++
++ for (; m; m = m->next) {
++ if (!mod_member_present(m, kallsyms_start) ||
++ !mod_member_present(m, kallsyms_end) ||
++ m->kallsyms_start >= m->kallsyms_end)
++ continue;
++ ka_hdr = (struct kallsyms_header *)m->kallsyms_start;
++ ka_sym = (struct kallsyms_symbol *)
++ ((char *)(ka_hdr) + ka_hdr->symbol_off);
++ ka_str =
++ ((char *)(ka_hdr) + ka_hdr->string_off);
++ for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) {
++ p = ka_str + ka_sym->name_off;
++ if (strcmp(p, name) == 0)
++ break;
++ /* Unversioned requests match versioned names */
++ if (!(pt_R = strstr(p, "_R")))
++ continue;
++ l = strlen(pt_R);
++ if (l < 10)
++ continue; /* Not _R.*xxxxxxxx */
++ (void)simple_strtoul(pt_R+l-8, &p2, 16);
++ if (*p2)
++ continue; /* Not _R.*xxxxxxxx */
++ if (strncmp(p, name, pt_R-p) == 0)
++ break; /* Match with version */
++ }
++ if (i < ka_hdr->symbols)
++ break;
++ }
++
++ if (token)
++ *token = (unsigned long)m;
++ if (!m)
++ return(0); /* not found */
++
++ ka_sec = (const struct kallsyms_section *)
++ ((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off);
++ *mod_name = m->name;
++ *mod_start = ka_hdr->start;
++ *mod_end = ka_hdr->end;
++ *sec_name = ka_sec->name_off + ka_str;
++ *sec_start = ka_sec->start;
++ *sec_end = ka_sec->start + ka_sec->size;
++ *sym_name = ka_sym->name_off + ka_str;
++ *sym_start = ka_sym->symbol_addr;
++ if (i < ka_hdr->symbols-1) {
++ const struct kallsyms_symbol *ka_symn = ka_sym;
++ kallsyms_next_sym(ka_hdr, ka_symn);
++ *sym_end = ka_symn->symbol_addr;
++ }
++ else
++ *sym_end = *sec_end;
++ return(1);
++}
++
++int kallsyms_address_to_symbol(
++ unsigned long address, /* Address to lookup */
++ const char **mod_name, /* Set to module name */
++ unsigned long *mod_start, /* Set to start address of module */
++ unsigned long *mod_end, /* Set to end address of module */
++ const char **sec_name, /* Set to section name */
++ unsigned long *sec_start, /* Set to start address of section */
++ unsigned long *sec_end, /* Set to end address of section */
++ const char **sym_name, /* Set to full symbol name */
++ unsigned long *sym_start, /* Set to start address of symbol */
++ unsigned long *sym_end /* Set to end address of symbol */
++ )
++{
++ const struct kallsyms_header *ka_hdr = NULL; /* stupid gcc */
++ const struct kallsyms_section *ka_sec = NULL;
++ const struct kallsyms_symbol *ka_sym;
++ const char *ka_str;
++ const struct module *m;
++ int i;
++ unsigned long end;
++
++ for (m = module_list; m; m = m->next) {
++
++ if (!mod_member_present(m, kallsyms_start) ||
++ !mod_member_present(m, kallsyms_end) ||
++ m->kallsyms_start >= m->kallsyms_end)
++ continue;
++ ka_hdr = (struct kallsyms_header *)m->kallsyms_start;
++ ka_sec = (const struct kallsyms_section *)
++ ((char *)ka_hdr + ka_hdr->section_off);
++ /* Is the address in any section in this module? */
++ for (i = 0; i < ka_hdr->sections; ++i, kallsyms_next_sec(ka_hdr, ka_sec)) {
++ if (ka_sec->start <= address &&
++ (ka_sec->start + ka_sec->size) > address)
++ break;
++ }
++ if (i < ka_hdr->sections)
++ break; /* Found a matching section */
++ }
++
++ if (!m)
++ return(0); /* not found */
++
++ ka_sym = (struct kallsyms_symbol *)
++ ((char *)(ka_hdr) + ka_hdr->symbol_off);
++ ka_str =
++ ((char *)(ka_hdr) + ka_hdr->string_off);
++ *mod_name = m->name;
++ *mod_start = ka_hdr->start;
++ *mod_end = ka_hdr->end;
++ *sec_name = ka_sec->name_off + ka_str;
++ *sec_start = ka_sec->start;
++ *sec_end = ka_sec->start + ka_sec->size;
++ *sym_name = *sec_name; /* In case we find no matching symbol */
++ *sym_start = *sec_start;
++ *sym_end = *sec_end;
++
++ for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) {
++ if (ka_sym->symbol_addr > address)
++ continue;
++ if (i < ka_hdr->symbols-1) {
++ const struct kallsyms_symbol *ka_symn = ka_sym;
++ kallsyms_next_sym(ka_hdr, ka_symn);
++ end = ka_symn->symbol_addr;
++ }
++ else
++ end = *sec_end;
++ if (end <= address)
++ continue;
++ if ((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off
++ != (char *)ka_sec)
++ continue; /* wrong section */
++ *sym_name = ka_str + ka_sym->name_off;
++ *sym_start = ka_sym->symbol_addr;
++ *sym_end = end;
++ break;
++ }
++ return(1);
++}
++
++/* List all sections in all modules. The callback routine is invoked with
++ * token, module name, section name, section start, section end, section flags.
++ */
++int kallsyms_sections(void *token,
++ int (*callback)(void *, const char *, const char *, ElfW(Addr), ElfW(Addr), ElfW(Word)))
++{
++ const struct kallsyms_header *ka_hdr = NULL; /* stupid gcc */
++ const struct kallsyms_section *ka_sec = NULL;
++ const char *ka_str;
++ const struct module *m;
++ int i;
++
++ for (m = module_list; m; m = m->next) {
++ if (!mod_member_present(m, kallsyms_start) ||
++ !mod_member_present(m, kallsyms_end) ||
++ m->kallsyms_start >= m->kallsyms_end)
++ continue;
++ ka_hdr = (struct kallsyms_header *)m->kallsyms_start;
++ ka_sec = (const struct kallsyms_section *) ((char *)ka_hdr + ka_hdr->section_off);
++ ka_str = ((char *)(ka_hdr) + ka_hdr->string_off);
++ for (i = 0; i < ka_hdr->sections; ++i, kallsyms_next_sec(ka_hdr, ka_sec)) {
++ if (callback(
++ token,
++ *(m->name) ? m->name : "kernel",
++ ka_sec->name_off + ka_str,
++ ka_sec->start,
++ ka_sec->start + ka_sec->size,
++ ka_sec->flags))
++ return(0);
++ }
++ }
++ return(1);
++}
+--- linux/Makefile 2004-06-16 19:25:21.000000000 +0800
++++ linux/Makefile.bak 2004-06-22 11:25:02.000000000 +0800
+@@ -45,6 +45,7 @@
+ MAKEFILES = $(TOPDIR)/.config
+ GENKSYMS = /sbin/genksyms
+ DEPMOD = /sbin/depmod
++KALLSYMS = /sbin/kallsyms
+ MODFLAGS = -DMODULE
+ CFLAGS_KERNEL =
+ PERL = perl
+@@ -211,7 +212,7 @@
+ CLEAN_FILES = \
+ kernel/ksyms.lst include/linux/compile.h \
+ vmlinux System.map \
+- .tmp* \
++ $(TMPPREFIX).tmp* \
+ drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
+ drivers/char/conmakehash \
+ drivers/char/drm/*-mod.c \
+@@ -292,16 +293,42 @@
+ boot: vmlinux
+ @$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot
+
++LD_VMLINUX := $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \
++ --start-group \
++ $(CORE_FILES) \
++ $(DRIVERS) \
++ $(NETWORKS) \
++ $(LIBS) \
++ --end-group
++ifeq ($(CONFIG_KALLSYMS),y)
++LD_VMLINUX_KALLSYMS := $(TMPPREFIX).tmp_kallsyms3.o
++else
++LD_VMLINUX_KALLSYMS :=
++endif
++
+ vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o init/do_mounts.o linuxsubdirs
+- $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \
+- --start-group \
+- $(CORE_FILES) \
+- $(DRIVERS) \
+- $(NETWORKS) \
+- $(LIBS) \
+- --end-group \
+- -o vmlinux
++ @$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" kallsyms
++
++.PHONY: kallsyms
++
++kallsyms:
++ifeq ($(CONFIG_KALLSYMS),y)
++ @echo kallsyms pass 1
++ $(LD_VMLINUX) -o $(TMPPREFIX).tmp_vmlinux1
++ @$(KALLSYMS) $(TMPPREFIX).tmp_vmlinux1 > $(TMPPREFIX).tmp_kallsyms1.o
++ @echo kallsyms pass 2
++ @$(LD_VMLINUX) $(TMPPREFIX).tmp_kallsyms1.o -o $(TMPPREFIX).tmp_vmlinux2
++ @$(KALLSYMS) $(TMPPREFIX).tmp_vmlinux2 > $(TMPPREFIX).tmp_kallsyms2.o
++ @echo kallsyms pass 3
++ @$(LD_VMLINUX) $(TMPPREFIX).tmp_kallsyms2.o -o $(TMPPREFIX).tmp_vmlinux3
++ @$(KALLSYMS) $(TMPPREFIX).tmp_vmlinux3 > $(TMPPREFIX).tmp_kallsyms3.o
++endif
++ $(LD_VMLINUX) $(LD_VMLINUX_KALLSYMS) -o $(TMPPREFIX)vmlinux
++ifneq ($(TMPPREFIX),)
++ mv $(TMPPREFIX)vmlinux vmlinux
++endif
+ $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
++ @rm -f $(TMPPREFIX).tmp_vmlinux* $(TMPPREFIX).tmp_kallsyms*
+
+ symlinks:
+ rm -f include/asm
+--- linux/arch/i386/vmlinux.lds.S 2004-06-16 19:25:26.000000000 +0800
++++ linux/arch/i386/vmlinux.lds.S.bak 2004-06-22 11:23:53.000000000 +0800
+@@ -28,6 +28,11 @@
+ __ksymtab : { *(__ksymtab) }
+ __stop___ksymtab = .;
+
++ __start___kallsyms = .; /* All kernel symbols */
++ __kallsyms : { *(__kallsyms) }
++ __stop___kallsyms = .;
++
++
+ .data : { /* Data */
+ *(.data)
+ CONSTRUCTORS