--- /dev/null
+Index: linux-2.4.29/arch/arm/vmlinux-armo.lds.in
+===================================================================
+--- linux-2.4.29.orig/arch/arm/vmlinux-armo.lds.in 2005-05-08 23:06:26.916055656 +0300
++++ linux-2.4.29/arch/arm/vmlinux-armo.lds.in 2005-05-08 23:07:11.214321296 +0300
+@@ -62,6 +62,10 @@
+ *(__ksymtab)
+ __stop___ksymtab = .;
+
++ __start___kallsyms = .; /* All kernel symbols */
++ *(__kallsyms)
++ __stop___kallsyms = .;
++
+ *(.got) /* Global offset table */
+
+ _etext = .; /* End of text section */
+Index: linux-2.4.29/arch/arm/vmlinux-armv.lds.in
+===================================================================
+--- linux-2.4.29.orig/arch/arm/vmlinux-armv.lds.in 2005-05-08 23:06:26.917055504 +0300
++++ linux-2.4.29/arch/arm/vmlinux-armv.lds.in 2005-05-08 23:07:11.215321144 +0300
+@@ -67,6 +67,12 @@
+ __stop___ksymtab = .;
+ }
+
++ __kallsyms : { /* Kernel debugging table */
++ __start___kallsyms = .; /* All kernel symbols */
++ *(__kallsyms)
++ __stop___kallsyms = .;
++ }
++
+ . = ALIGN(8192);
+
+ .data : {
+Index: linux-2.4.29/arch/ppc/config.in
+===================================================================
+--- linux-2.4.29.orig/arch/ppc/config.in 2005-05-08 23:06:26.933053072 +0300
++++ linux-2.4.29/arch/ppc/config.in 2005-05-08 23:07:11.216320992 +0300
+@@ -655,6 +655,7 @@
+ fi
+ fi
+ fi
++bool 'Load all symbols for debugging/kksymoops' CONFIG_KALLSYMS
+
+ if [ "$CONFIG_ALL_PPC" = "y" ]; then
+ bool 'Support for early boot text console (BootX or OpenFirmware only)' CONFIG_BOOTX_TEXT
+Index: linux-2.4.29/arch/ppc/vmlinux.lds
+===================================================================
+--- linux-2.4.29.orig/arch/ppc/vmlinux.lds 2005-05-08 23:06:26.934052920 +0300
++++ linux-2.4.29/arch/ppc/vmlinux.lds 2005-05-08 23:07:11.217320840 +0300
+@@ -74,6 +74,10 @@
+ __ksymtab : { *(__ksymtab) }
+ __stop___ksymtab = .;
+
++ __start___kallsyms = .; /* All kernel symbols */
++ __kallsyms : { *(__kallsyms) }
++ __stop___kallsyms = .;
++
+ . = ALIGN(8);
+ __start___ftr_fixup = .;
+ __ftr_fixup : { *(__ftr_fixup) }
+Index: linux-2.4.29/arch/i386/config.in
+===================================================================
+--- linux-2.4.29.orig/arch/i386/config.in 2005-05-08 23:07:09.946514032 +0300
++++ linux-2.4.29/arch/i386/config.in 2005-05-08 23:07:11.218320688 +0300
+@@ -449,6 +449,7 @@
+ if [ "$CONFIG_ISDN" != "n" ]; then
+ source drivers/isdn/Config.in
+ fi
++ bool ' Load all symbols for debugging/kksymoops' CONFIG_KALLSYMS
+ fi
+ endmenu
+
+Index: linux-2.4.29/arch/ia64/config.in
+===================================================================
+--- linux-2.4.29.orig/arch/ia64/config.in 2005-05-08 23:06:26.936052616 +0300
++++ linux-2.4.29/arch/ia64/config.in 2005-05-08 23:07:11.219320536 +0300
+@@ -318,4 +318,6 @@
+
+ int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
+
++bool ' Load all symbols for debugging/kksymoops' CONFIG_KALLSYMS
++
+ endmenu
+Index: linux-2.4.29/arch/alpha/vmlinux.lds.in
+===================================================================
+--- linux-2.4.29.orig/arch/alpha/vmlinux.lds.in 2005-05-08 23:06:26.937052464 +0300
++++ linux-2.4.29/arch/alpha/vmlinux.lds.in 2005-05-08 23:07:11.220320384 +0300
+@@ -28,6 +28,10 @@
+ __stop___ksymtab = .;
+ .kstrtab : { *(.kstrtab) }
+
++ __start___kallsyms = .; /* All kernel symbols */
++ __kallsyms : { *(__kallsyms) }
++ __stop___kallsyms = .;
++
+ /* Startup code */
+ . = ALIGN(8192);
+ __init_begin = .;
+Index: linux-2.4.29/Makefile
+===================================================================
+--- linux-2.4.29.orig/Makefile 2005-05-08 22:59:19.203077912 +0300
++++ linux-2.4.29/Makefile 2005-05-08 23:07:11.222320080 +0300
+@@ -37,6 +37,7 @@
+ MAKEFILES = $(TOPDIR)/.config
+ GENKSYMS = /sbin/genksyms
+ DEPMOD = /sbin/depmod
++KALLSYMS = /sbin/kallsyms
+ MODFLAGS = -DMODULE
+ CFLAGS_KERNEL =
+ PERL = perl
+@@ -44,6 +45,8 @@
+ RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
+ else echo rpm; fi)
+
++TMPPREFIX =
++
+ export VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \
+ CONFIG_SHELL TOPDIR HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
+ CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES GENKSYMS MODFLAGS PERL AWK
+@@ -202,7 +205,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 \
+@@ -285,16 +288,39 @@
+ 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 vmlinux
+ $(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
+Index: linux-2.4.29/kernel/Makefile
+===================================================================
+--- linux-2.4.29.orig/kernel/Makefile 2005-05-08 23:06:26.939052160 +0300
++++ linux-2.4.29/kernel/Makefile 2005-05-08 23:07:11.223319928 +0300
+@@ -19,6 +19,7 @@
+ obj-$(CONFIG_UID16) += uid16.o
+ obj-$(CONFIG_MODULES) += ksyms.o
+ obj-$(CONFIG_PM) += pm.o
++obj-$(CONFIG_KALLSYMS) += kallsyms.o
+
+ ifneq ($(CONFIG_IA64),y)
+ # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
+Index: linux-2.4.29/kernel/ksyms.c
+===================================================================
+--- linux-2.4.29.orig/kernel/ksyms.c 2005-05-08 23:07:10.878372368 +0300
++++ linux-2.4.29/kernel/ksyms.c 2005-05-08 23:07:11.224319776 +0300
+@@ -59,6 +59,9 @@
+ #ifdef CONFIG_KMOD
+ #include <linux/kmod.h>
+ #endif
++#ifdef CONFIG_KALLSYMS
++#include <linux/kallsyms.h>
++#endif
+
+ extern void set_device_ro(kdev_t dev,int flag);
+
+@@ -87,6 +90,15 @@
+ EXPORT_SYMBOL(inter_module_put);
+ EXPORT_SYMBOL(try_inc_mod_count);
+
++#ifdef CONFIG_KALLSYMS
++extern const char __start___kallsyms[];
++extern const char __stop___kallsyms[];
++EXPORT_SYMBOL(__start___kallsyms);
++EXPORT_SYMBOL(__stop___kallsyms);
++
++
++#endif
++
+ /* process memory management */
+ EXPORT_SYMBOL(do_mmap_pgoff);
+ EXPORT_SYMBOL(do_munmap);
+Index: linux-2.4.29/kernel/kallsyms.c
+===================================================================
+--- linux-2.4.29.orig/kernel/kallsyms.c 2005-05-08 23:07:11.196324032 +0300
++++ linux-2.4.29/kernel/kallsyms.c 2005-05-08 23:07:11.226319472 +0300
+@@ -0,0 +1,306 @@
++/* An example of using kallsyms data in a kernel debugger.
++
++ Copyright 2000 Keith Owens <kaos@ocs.com.au> April 2000
++
++ This file is part of the Linux modutils.
++
++ 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: kallsyms-2.4-bgl.patch,v 1.1.20.1 2005/03/24 22:50:28 jacob Exp $"
++
++/*
++ 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.
++
++ You need modutils >= 2.3.11 and a kernel with the kallsyms patch
++ which was compiled with CONFIG_KALLSYMS.
++ */
++
++#include <linux/elf.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/kallsyms.h>
++
++/* These external symbols are only set on kernels compiled with
++ * CONFIG_KALLSYMS.
++ */
++
++extern const char __start___kallsyms[];
++extern const char __stop___kallsyms[];
++
++static struct module **kallsyms_module_list;
++
++static void kallsyms_get_module_list(void)
++{
++ const struct kallsyms_header *ka_hdr;
++ const struct kallsyms_section *ka_sec;
++ const struct kallsyms_symbol *ka_sym;
++ const char *ka_str;
++ int i;
++ const char *p;
++
++ if (__start___kallsyms >= __stop___kallsyms)
++ return;
++ ka_hdr = (struct kallsyms_header *)__start___kallsyms;
++ ka_sec = (struct kallsyms_section *)
++ ((char *)(ka_hdr) + ka_hdr->section_off);
++ 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; kallsyms_next_sym(ka_hdr, ka_sym), ++i) {
++ p = ka_str + ka_sym->name_off;
++ if (strcmp(p, "module_list") == 0) {
++ if (ka_sym->symbol_addr)
++ kallsyms_module_list = (struct module **)(ka_sym->symbol_addr);
++ break;
++ }
++ }
++}
++
++static inline void kallsyms_do_first_time(void)
++{
++ static int first_time = 1;
++ if (first_time)
++ kallsyms_get_module_list();
++ first_time = 0;
++}
++
++/* 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;
++
++ kallsyms_do_first_time();
++ if (!kallsyms_module_list)
++ return(0);
++
++ /* Restart? */
++ m = *kallsyms_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) ? m->name : "kernel";
++ *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;
++
++ kallsyms_do_first_time();
++ if (!kallsyms_module_list)
++ return(0);
++
++ for (m = *kallsyms_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) ? m->name : "kernel";
++ *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;
++
++ kallsyms_do_first_time();
++ if (!kallsyms_module_list)
++ return(0);
++
++ for (m = *kallsyms_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);
++}
+Index: linux-2.4.29/include/linux/kallsyms.h
+===================================================================
+--- linux-2.4.29.orig/include/linux/kallsyms.h 2005-05-08 23:07:11.196324032 +0300
++++ linux-2.4.29/include/linux/kallsyms.h 2005-05-08 23:08:04.316248576 +0300
+@@ -0,0 +1,141 @@
++/* 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: kallsyms-2.4-bgl.patch,v 1.1.20.1 2005/03/24 22:50:28 jacob 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))
++
++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 */
++ )
++ );
++
++#endif /* kallsyms.h */
+Index: linux-2.4.29/arch/i386/vmlinux.lds.S
+===================================================================
+--- linux-2.4.29.orig/arch/i386/vmlinux.lds.S 2005-05-08 23:07:09.948513728 +0300
++++ linux-2.4.29/arch/i386/vmlinux.lds.S 2005-05-08 23:14:24.128508336 +0300
+@@ -28,6 +28,10 @@
+ __ksymtab : { *(__ksymtab) }
+ __stop___ksymtab = .;
+
++ __start___kallsyms = .; /* All kernel symbols */
++ __kallsyms : { *(__kallsyms) }
++ __stop___kallsyms = .;
++
+ .data : { /* Data */
+ *(.data)
+ CONSTRUCTORS