Whamcloud - gitweb
b=10651
[fs/lustre-release.git] / lustre / kernel_patches / patches / kallsyms-2.4.29.patch
1 Index: linux-2.4.29/arch/arm/vmlinux-armo.lds.in
2 ===================================================================
3 --- linux-2.4.29.orig/arch/arm/vmlinux-armo.lds.in      2005-05-08 23:06:26.916055656 +0300
4 +++ linux-2.4.29/arch/arm/vmlinux-armo.lds.in   2005-05-08 23:07:11.214321296 +0300
5 @@ -62,6 +62,10 @@
6                         *(__ksymtab)
7                 __stop___ksymtab = .;
8  
9 +               __start___kallsyms = .; /* All kernel symbols */
10 +                       *(__kallsyms)
11 +               __stop___kallsyms = .;
12 +
13                 *(.got)                 /* Global offset table          */
14  
15                 _etext = .;             /* End of text section          */
16 Index: linux-2.4.29/arch/arm/vmlinux-armv.lds.in
17 ===================================================================
18 --- linux-2.4.29.orig/arch/arm/vmlinux-armv.lds.in      2005-05-08 23:06:26.917055504 +0300
19 +++ linux-2.4.29/arch/arm/vmlinux-armv.lds.in   2005-05-08 23:07:11.215321144 +0300
20 @@ -67,6 +67,12 @@
21                 __stop___ksymtab = .;
22         }
23  
24 +       __kallsyms : {                  /* Kernel debugging table       */
25 +               __start___kallsyms = .; /* All kernel symbols */
26 +                       *(__kallsyms)
27 +               __stop___kallsyms = .;
28 +       }
29 +
30         . = ALIGN(8192);
31  
32         .data : {
33 Index: linux-2.4.29/arch/ppc/config.in
34 ===================================================================
35 --- linux-2.4.29.orig/arch/ppc/config.in        2005-05-08 23:06:26.933053072 +0300
36 +++ linux-2.4.29/arch/ppc/config.in     2005-05-08 23:07:11.216320992 +0300
37 @@ -655,6 +655,7 @@
38      fi
39    fi
40  fi
41 +bool 'Load all symbols for debugging/kksymoops' CONFIG_KALLSYMS
42  
43  if [ "$CONFIG_ALL_PPC" = "y" ]; then
44    bool 'Support for early boot text console (BootX or OpenFirmware only)' CONFIG_BOOTX_TEXT
45 Index: linux-2.4.29/arch/ppc/vmlinux.lds
46 ===================================================================
47 --- linux-2.4.29.orig/arch/ppc/vmlinux.lds      2005-05-08 23:06:26.934052920 +0300
48 +++ linux-2.4.29/arch/ppc/vmlinux.lds   2005-05-08 23:07:11.217320840 +0300
49 @@ -74,6 +74,10 @@
50    __ksymtab : { *(__ksymtab) }
51    __stop___ksymtab = .;
52  
53 +  __start___kallsyms = .;     /* All kernel symbols */
54 +  __kallsyms : { *(__kallsyms) }
55 +  __stop___kallsyms = .;
56 +
57    . = ALIGN(8);
58    __start___ftr_fixup = .;
59    __ftr_fixup : { *(__ftr_fixup) }
60 Index: linux-2.4.29/arch/i386/config.in
61 ===================================================================
62 --- linux-2.4.29.orig/arch/i386/config.in       2005-05-08 23:07:09.946514032 +0300
63 +++ linux-2.4.29/arch/i386/config.in    2005-05-08 23:33:00.395809912 +0300
64 @@ -512,6 +512,7 @@
65     bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
66     bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
67     bool '  Compile the kernel with frame pointers' CONFIG_FRAME_POINTER
68 +   bool '  Load all symbols for debugging/kksymoops' CONFIG_KALLSYMS
69  fi
70  
71  int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
72 Index: linux-2.4.29/arch/ia64/config.in
73 ===================================================================
74 --- linux-2.4.29.orig/arch/ia64/config.in       2005-05-08 23:06:26.936052616 +0300
75 +++ linux-2.4.29/arch/ia64/config.in    2005-05-08 23:07:11.219320536 +0300
76 @@ -318,4 +318,6 @@
77  
78  int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
79  
80 +bool '  Load all symbols for debugging/kksymoops' CONFIG_KALLSYMS
81 +
82  endmenu
83 Index: linux-2.4.29/arch/alpha/vmlinux.lds.in
84 ===================================================================
85 --- linux-2.4.29.orig/arch/alpha/vmlinux.lds.in 2005-05-08 23:06:26.937052464 +0300
86 +++ linux-2.4.29/arch/alpha/vmlinux.lds.in      2005-05-08 23:07:11.220320384 +0300
87 @@ -28,6 +28,10 @@
88    __stop___ksymtab = .;
89    .kstrtab : { *(.kstrtab) }
90  
91 +  __start___kallsyms = .;       /* All kernel symbols */
92 +  __kallsyms : { *(__kallsyms) }
93 +  __stop___kallsyms = .;
94 +
95    /* Startup code */
96    . = ALIGN(8192);
97    __init_begin = .;
98 Index: linux-2.4.29/Makefile
99 ===================================================================
100 --- linux-2.4.29.orig/Makefile  2005-05-08 22:59:19.203077912 +0300
101 +++ linux-2.4.29/Makefile       2005-05-08 23:07:11.222320080 +0300
102 @@ -37,6 +37,7 @@
103  MAKEFILES      = $(TOPDIR)/.config
104  GENKSYMS       = /sbin/genksyms
105  DEPMOD         = /sbin/depmod
106 +KALLSYMS       = /sbin/kallsyms
107  MODFLAGS       = -DMODULE
108  CFLAGS_KERNEL  =
109  PERL           = perl
110 @@ -44,6 +45,8 @@
111  RPM            := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
112                         else echo rpm; fi)
113  
114 +TMPPREFIX      = 
115 +
116  export VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \
117         CONFIG_SHELL TOPDIR HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
118         CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES GENKSYMS MODFLAGS PERL AWK
119 @@ -202,7 +205,7 @@
120  CLEAN_FILES = \
121         kernel/ksyms.lst include/linux/compile.h \
122         vmlinux System.map \
123 -       .tmp* \
124 +       $(TMPPREFIX).tmp* \
125         drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
126         drivers/char/conmakehash \
127         drivers/char/drm/*-mod.c \
128 @@ -285,16 +288,39 @@
129  boot: vmlinux
130         @$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot
131  
132 +LD_VMLINUX     := $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \
133 +                       --start-group \
134 +                       $(CORE_FILES) \
135 +                       $(DRIVERS) \
136 +                       $(NETWORKS) \
137 +                       $(LIBS) \
138 +                       --end-group
139 +ifeq ($(CONFIG_KALLSYMS),y)
140 +LD_VMLINUX_KALLSYMS    := $(TMPPREFIX).tmp_kallsyms3.o
141 +else
142 +LD_VMLINUX_KALLSYMS    :=
143 +endif
144 +
145  vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o init/do_mounts.o linuxsubdirs
146 -       $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \
147 -               --start-group \
148 -               $(CORE_FILES) \
149 -               $(DRIVERS) \
150 -               $(NETWORKS) \
151 -               $(LIBS) \
152 -               --end-group \
153 -               -o vmlinux
154 +       @$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" kallsyms
155 +
156 +.PHONY:        kallsyms
157 +
158 +kallsyms:
159 +ifeq ($(CONFIG_KALLSYMS),y)
160 +       @echo kallsyms pass 1
161 +       $(LD_VMLINUX) -o $(TMPPREFIX).tmp_vmlinux1
162 +       @$(KALLSYMS) $(TMPPREFIX).tmp_vmlinux1 > $(TMPPREFIX).tmp_kallsyms1.o
163 +       @echo kallsyms pass 2
164 +       @$(LD_VMLINUX) $(TMPPREFIX).tmp_kallsyms1.o -o $(TMPPREFIX).tmp_vmlinux2
165 +       @$(KALLSYMS) $(TMPPREFIX).tmp_vmlinux2 > $(TMPPREFIX).tmp_kallsyms2.o
166 +       @echo kallsyms pass 3
167 +       @$(LD_VMLINUX) $(TMPPREFIX).tmp_kallsyms2.o -o $(TMPPREFIX).tmp_vmlinux3
168 +       @$(KALLSYMS) $(TMPPREFIX).tmp_vmlinux3 > $(TMPPREFIX).tmp_kallsyms3.o
169 +endif
170 +       $(LD_VMLINUX) $(LD_VMLINUX_KALLSYMS) -o vmlinux
171         $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
172 +       @rm -f $(TMPPREFIX).tmp_vmlinux* $(TMPPREFIX).tmp_kallsyms*
173  
174  symlinks:
175         rm -f include/asm
176 Index: linux-2.4.29/kernel/Makefile
177 ===================================================================
178 --- linux-2.4.29.orig/kernel/Makefile   2005-05-08 23:06:26.939052160 +0300
179 +++ linux-2.4.29/kernel/Makefile        2005-05-08 23:07:11.223319928 +0300
180 @@ -19,6 +19,7 @@
181  obj-$(CONFIG_UID16) += uid16.o
182  obj-$(CONFIG_MODULES) += ksyms.o
183  obj-$(CONFIG_PM) += pm.o
184 +obj-$(CONFIG_KALLSYMS) += kallsyms.o
185  
186  ifneq ($(CONFIG_IA64),y)
187  # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
188 Index: linux-2.4.29/kernel/ksyms.c
189 ===================================================================
190 --- linux-2.4.29.orig/kernel/ksyms.c    2005-05-08 23:07:10.878372368 +0300
191 +++ linux-2.4.29/kernel/ksyms.c 2005-05-08 23:07:11.224319776 +0300
192 @@ -59,6 +59,9 @@
193  #ifdef CONFIG_KMOD
194  #include <linux/kmod.h>
195  #endif
196 +#ifdef CONFIG_KALLSYMS
197 +#include <linux/kallsyms.h>
198 +#endif
199  
200  extern void set_device_ro(kdev_t dev,int flag);
201  
202 @@ -87,6 +90,15 @@
203  EXPORT_SYMBOL(inter_module_put);
204  EXPORT_SYMBOL(try_inc_mod_count);
205  
206 +#ifdef CONFIG_KALLSYMS
207 +extern const char __start___kallsyms[];
208 +extern const char __stop___kallsyms[];
209 +EXPORT_SYMBOL(__start___kallsyms);
210 +EXPORT_SYMBOL(__stop___kallsyms);
211 +
212 +
213 +#endif
214 +
215  /* process memory management */
216  EXPORT_SYMBOL(do_mmap_pgoff);
217  EXPORT_SYMBOL(do_munmap);
218 Index: linux-2.4.29/kernel/kallsyms.c
219 ===================================================================
220 --- linux-2.4.29.orig/kernel/kallsyms.c 2005-05-08 23:07:11.196324032 +0300
221 +++ linux-2.4.29/kernel/kallsyms.c      2005-05-08 23:07:11.226319472 +0300
222 @@ -0,0 +1,306 @@
223 +/* An example of using kallsyms data in a kernel debugger.
224 +
225 +   Copyright 2000 Keith Owens <kaos@ocs.com.au> April 2000
226 +
227 +   This file is part of the Linux modutils.
228 +
229 +   This program is free software; you can redistribute it and/or modify it
230 +   under the terms of the GNU General Public License as published by the
231 +   Free Software Foundation; either version 2 of the License, or (at your
232 +   option) any later version.
233 +
234 +   This program is distributed in the hope that it will be useful, but
235 +   WITHOUT ANY WARRANTY; without even the implied warranty of
236 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
237 +   General Public License for more details.
238 +
239 +   You should have received a copy of the GNU General Public License
240 +   along with this program; if not, write to the Free Software Foundation,
241 +   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
242 +  */
243 +
244 +#ident "$Id: kallsyms-2.4-bgl.patch,v 1.1.20.1 2005/03/24 22:50:28 jacob Exp $"
245 +
246 +/*
247 +   This code uses the list of all kernel and module symbols to :-
248 +
249 +   * Find any non-stack symbol in a kernel or module.  Symbols do
250 +     not have to be exported for debugging.
251 +
252 +   * Convert an address to the module (or kernel) that owns it, the
253 +     section it is in and the nearest symbol.  This finds all non-stack
254 +     symbols, not just exported ones.
255 +
256 +   You need modutils >= 2.3.11 and a kernel with the kallsyms patch
257 +   which was compiled with CONFIG_KALLSYMS.
258 + */
259 +
260 +#include <linux/elf.h>
261 +#include <linux/kernel.h>
262 +#include <linux/module.h>
263 +#include <linux/string.h>
264 +#include <linux/kallsyms.h>
265 +
266 +/* These external symbols are only set on kernels compiled with
267 + * CONFIG_KALLSYMS.
268 + */
269 +
270 +extern const char __start___kallsyms[];
271 +extern const char __stop___kallsyms[];
272 +
273 +static struct module **kallsyms_module_list;
274 +
275 +static void kallsyms_get_module_list(void)
276 +{
277 +       const struct kallsyms_header    *ka_hdr;
278 +       const struct kallsyms_section   *ka_sec;
279 +       const struct kallsyms_symbol    *ka_sym;
280 +       const char                      *ka_str;
281 +       int i;
282 +       const char *p;
283 +
284 +       if (__start___kallsyms >= __stop___kallsyms)
285 +               return;
286 +       ka_hdr = (struct kallsyms_header *)__start___kallsyms;
287 +       ka_sec = (struct kallsyms_section *)
288 +               ((char *)(ka_hdr) + ka_hdr->section_off);
289 +       ka_sym = (struct kallsyms_symbol *)
290 +               ((char *)(ka_hdr) + ka_hdr->symbol_off);
291 +       ka_str = 
292 +               ((char *)(ka_hdr) + ka_hdr->string_off);
293 +
294 +       for (i = 0; i < ka_hdr->symbols; kallsyms_next_sym(ka_hdr, ka_sym), ++i) {
295 +               p = ka_str + ka_sym->name_off;
296 +               if (strcmp(p, "module_list") == 0) {
297 +                       if (ka_sym->symbol_addr)
298 +                               kallsyms_module_list = (struct module **)(ka_sym->symbol_addr);
299 +                       break;
300 +               }
301 +       }
302 +}
303 +
304 +static inline void kallsyms_do_first_time(void)
305 +{
306 +       static int first_time = 1;
307 +       if (first_time)
308 +               kallsyms_get_module_list();
309 +       first_time = 0;
310 +}
311 +
312 +/* A symbol can appear in more than one module.  A token is used to
313 + * restart the scan at the next module, set the token to 0 for the
314 + * first scan of each symbol.
315 + */
316 +
317 +int kallsyms_symbol_to_address(
318 +       const char       *name,         /* Name to lookup */
319 +       unsigned long    *token,        /* Which module to start at */
320 +       const char      **mod_name,     /* Set to module name */
321 +       unsigned long    *mod_start,    /* Set to start address of module */
322 +       unsigned long    *mod_end,      /* Set to end address of module */
323 +       const char      **sec_name,     /* Set to section name */
324 +       unsigned long    *sec_start,    /* Set to start address of section */
325 +       unsigned long    *sec_end,      /* Set to end address of section */
326 +       const char      **sym_name,     /* Set to full symbol name */
327 +       unsigned long    *sym_start,    /* Set to start address of symbol */
328 +       unsigned long    *sym_end       /* Set to end address of symbol */
329 +       )
330 +{
331 +       const struct kallsyms_header    *ka_hdr = NULL; /* stupid gcc */
332 +       const struct kallsyms_section   *ka_sec;
333 +       const struct kallsyms_symbol    *ka_sym = NULL;
334 +       const char                      *ka_str = NULL;
335 +       const struct module *m;
336 +       int i = 0, l;
337 +       const char *p, *pt_R;
338 +       char *p2;
339 +
340 +       kallsyms_do_first_time();
341 +       if (!kallsyms_module_list)
342 +               return(0);
343 +
344 +       /* Restart? */
345 +       m = *kallsyms_module_list;
346 +       if (token && *token) {
347 +               for (; m; m = m->next)
348 +                       if ((unsigned long)m == *token)
349 +                               break;
350 +               if (m)
351 +                       m = m->next;
352 +       }
353 +
354 +       for (; m; m = m->next) {
355 +               if (!mod_member_present(m, kallsyms_start) || 
356 +                   !mod_member_present(m, kallsyms_end) ||
357 +                   m->kallsyms_start >= m->kallsyms_end)
358 +                       continue;
359 +               ka_hdr = (struct kallsyms_header *)m->kallsyms_start;
360 +               ka_sym = (struct kallsyms_symbol *)
361 +                       ((char *)(ka_hdr) + ka_hdr->symbol_off);
362 +               ka_str = 
363 +                       ((char *)(ka_hdr) + ka_hdr->string_off);
364 +               for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) {
365 +                       p = ka_str + ka_sym->name_off;
366 +                       if (strcmp(p, name) == 0)
367 +                               break;
368 +                       /* Unversioned requests match versioned names */
369 +                       if (!(pt_R = strstr(p, "_R")))
370 +                               continue;
371 +                       l = strlen(pt_R);
372 +                       if (l < 10)
373 +                               continue;       /* Not _R.*xxxxxxxx */
374 +                       (void)simple_strtoul(pt_R+l-8, &p2, 16);
375 +                       if (*p2)
376 +                               continue;       /* Not _R.*xxxxxxxx */
377 +                       if (strncmp(p, name, pt_R-p) == 0)
378 +                               break;  /* Match with version */
379 +               }
380 +               if (i < ka_hdr->symbols)
381 +                       break;
382 +       }
383 +
384 +       if (token)
385 +               *token = (unsigned long)m;
386 +       if (!m)
387 +               return(0);      /* not found */
388 +
389 +       ka_sec = (const struct kallsyms_section *)
390 +               ((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off);
391 +       *mod_name = *(m->name) ? m->name : "kernel";
392 +       *mod_start = ka_hdr->start;
393 +       *mod_end = ka_hdr->end;
394 +       *sec_name = ka_sec->name_off + ka_str;
395 +       *sec_start = ka_sec->start;
396 +       *sec_end = ka_sec->start + ka_sec->size;
397 +       *sym_name = ka_sym->name_off + ka_str;
398 +       *sym_start = ka_sym->symbol_addr;
399 +       if (i < ka_hdr->symbols-1) {
400 +               const struct kallsyms_symbol *ka_symn = ka_sym;
401 +               kallsyms_next_sym(ka_hdr, ka_symn);
402 +               *sym_end = ka_symn->symbol_addr;
403 +       }
404 +       else
405 +               *sym_end = *sec_end;
406 +       return(1);
407 +}
408 +
409 +int kallsyms_address_to_symbol(
410 +       unsigned long     address,      /* Address to lookup */
411 +       const char      **mod_name,     /* Set to module name */
412 +       unsigned long    *mod_start,    /* Set to start address of module */
413 +       unsigned long    *mod_end,      /* Set to end address of module */
414 +       const char      **sec_name,     /* Set to section name */
415 +       unsigned long    *sec_start,    /* Set to start address of section */
416 +       unsigned long    *sec_end,      /* Set to end address of section */
417 +       const char      **sym_name,     /* Set to full symbol name */
418 +       unsigned long    *sym_start,    /* Set to start address of symbol */
419 +       unsigned long    *sym_end       /* Set to end address of symbol */
420 +       )
421 +{
422 +       const struct kallsyms_header    *ka_hdr = NULL; /* stupid gcc */
423 +       const struct kallsyms_section   *ka_sec = NULL;
424 +       const struct kallsyms_symbol    *ka_sym;
425 +       const char                      *ka_str;
426 +       const struct module *m;
427 +       int i;
428 +       unsigned long end;
429 +
430 +       kallsyms_do_first_time();
431 +       if (!kallsyms_module_list)
432 +               return(0);
433 +
434 +       for (m = *kallsyms_module_list; m; m = m->next) {
435 +               if (!mod_member_present(m, kallsyms_start) || 
436 +                   !mod_member_present(m, kallsyms_end) ||
437 +                   m->kallsyms_start >= m->kallsyms_end)
438 +                       continue;
439 +               ka_hdr = (struct kallsyms_header *)m->kallsyms_start;
440 +               ka_sec = (const struct kallsyms_section *)
441 +                       ((char *)ka_hdr + ka_hdr->section_off);
442 +               /* Is the address in any section in this module? */
443 +               for (i = 0; i < ka_hdr->sections; ++i, kallsyms_next_sec(ka_hdr, ka_sec)) {
444 +                       if (ka_sec->start <= address &&
445 +                           (ka_sec->start + ka_sec->size) > address)
446 +                               break;
447 +               }
448 +               if (i < ka_hdr->sections)
449 +                       break;  /* Found a matching section */
450 +       }
451 +
452 +       if (!m)
453 +               return(0);      /* not found */
454 +
455 +       ka_sym = (struct kallsyms_symbol *)
456 +               ((char *)(ka_hdr) + ka_hdr->symbol_off);
457 +       ka_str = 
458 +               ((char *)(ka_hdr) + ka_hdr->string_off);
459 +       *mod_name = *(m->name) ? m->name : "kernel";
460 +       *mod_start = ka_hdr->start;
461 +       *mod_end = ka_hdr->end;
462 +       *sec_name = ka_sec->name_off + ka_str;
463 +       *sec_start = ka_sec->start;
464 +       *sec_end = ka_sec->start + ka_sec->size;
465 +       *sym_name = *sec_name;          /* In case we find no matching symbol */
466 +       *sym_start = *sec_start;
467 +       *sym_end = *sec_end;
468 +
469 +       for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) {
470 +               if (ka_sym->symbol_addr > address)
471 +                       continue;
472 +               if (i < ka_hdr->symbols-1) {
473 +                       const struct kallsyms_symbol *ka_symn = ka_sym;
474 +                       kallsyms_next_sym(ka_hdr, ka_symn);
475 +                       end = ka_symn->symbol_addr;
476 +               }
477 +               else
478 +                       end = *sec_end;
479 +               if (end <= address)
480 +                       continue;
481 +               if ((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off
482 +                   != (char *)ka_sec)
483 +                       continue;       /* wrong section */
484 +               *sym_name = ka_str + ka_sym->name_off;
485 +               *sym_start = ka_sym->symbol_addr;
486 +               *sym_end = end;
487 +               break;
488 +       }
489 +       return(1);
490 +}
491 +
492 +/* List all sections in all modules.  The callback routine is invoked with
493 + * token, module name, section name, section start, section end, section flags.
494 + */
495 +int kallsyms_sections(void *token,
496 +                     int (*callback)(void *, const char *, const char *, ElfW(Addr), ElfW(Addr), ElfW(Word)))
497 +{
498 +       const struct kallsyms_header    *ka_hdr = NULL; /* stupid gcc */
499 +       const struct kallsyms_section   *ka_sec = NULL;
500 +       const char                      *ka_str;
501 +       const struct module *m;
502 +       int i;
503 +
504 +       kallsyms_do_first_time();
505 +       if (!kallsyms_module_list)
506 +               return(0);
507 +
508 +       for (m = *kallsyms_module_list; m; m = m->next) {
509 +               if (!mod_member_present(m, kallsyms_start) || 
510 +                   !mod_member_present(m, kallsyms_end) ||
511 +                   m->kallsyms_start >= m->kallsyms_end)
512 +                       continue;
513 +               ka_hdr = (struct kallsyms_header *)m->kallsyms_start;
514 +               ka_sec = (const struct kallsyms_section *) ((char *)ka_hdr + ka_hdr->section_off);
515 +               ka_str = ((char *)(ka_hdr) + ka_hdr->string_off);
516 +               for (i = 0; i < ka_hdr->sections; ++i, kallsyms_next_sec(ka_hdr, ka_sec)) {
517 +                       if (callback(
518 +                               token,
519 +                               *(m->name) ? m->name : "kernel",
520 +                               ka_sec->name_off + ka_str,
521 +                               ka_sec->start,
522 +                               ka_sec->start + ka_sec->size,
523 +                               ka_sec->flags))
524 +                               return(0);
525 +               }
526 +       }
527 +       return(1);
528 +}
529 Index: linux-2.4.29/include/linux/kallsyms.h
530 ===================================================================
531 --- linux-2.4.29.orig/include/linux/kallsyms.h  2005-05-08 23:07:11.196324032 +0300
532 +++ linux-2.4.29/include/linux/kallsyms.h       2005-05-08 23:08:04.316248576 +0300
533 @@ -0,0 +1,141 @@
534 +/* kallsyms headers
535 +   Copyright 2000 Keith Owens <kaos@ocs.com.au>
536 +
537 +   This file is part of the Linux modutils.  It is exported to kernel
538 +   space so debuggers can access the kallsyms data.
539 +
540 +   The kallsyms data contains all the non-stack symbols from a kernel
541 +   or a module.  The kernel symbols are held between __start___kallsyms
542 +   and __stop___kallsyms.  The symbols for a module are accessed via
543 +   the struct module chain which is based at module_list.
544 +
545 +   This program is free software; you can redistribute it and/or modify it
546 +   under the terms of the GNU General Public License as published by the
547 +   Free Software Foundation; either version 2 of the License, or (at your
548 +   option) any later version.
549 +
550 +   This program is distributed in the hope that it will be useful, but
551 +   WITHOUT ANY WARRANTY; without even the implied warranty of
552 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
553 +   General Public License for more details.
554 +
555 +   You should have received a copy of the GNU General Public License
556 +   along with this program; if not, write to the Free Software Foundation,
557 +   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
558 + */
559 +
560 +#ident "$Id: kallsyms-2.4-bgl.patch,v 1.1.20.1 2005/03/24 22:50:28 jacob Exp $"
561 +
562 +#ifndef MODUTILS_KALLSYMS_H
563 +#define MODUTILS_KALLSYMS_H 1
564 +
565 +/* Have to (re)define these ElfW entries here because external kallsyms
566 + * code does not have access to modutils/include/obj.h.  This code is
567 + * included from user spaces tools (modutils) and kernel, they need
568 + * different includes.
569 + */
570 +
571 +#ifndef ELFCLASS32
572 +#ifdef __KERNEL__
573 +#include <linux/elf.h>
574 +#else  /* __KERNEL__ */
575 +#include <elf.h>
576 +#endif /* __KERNEL__ */
577 +#endif /* ELFCLASS32 */
578 +
579 +#ifndef ELFCLASSM
580 +#define ELFCLASSM ELF_CLASS
581 +#endif
582 +
583 +#ifndef ElfW
584 +# if ELFCLASSM == ELFCLASS32
585 +#  define ElfW(x)  Elf32_ ## x
586 +#  define ELFW(x)  ELF32_ ## x
587 +# else
588 +#  define ElfW(x)  Elf64_ ## x
589 +#  define ELFW(x)  ELF64_ ## x
590 +# endif
591 +#endif
592 +
593 +/* Format of data in the kallsyms section.
594 + * Most of the fields are small numbers but the total size and all
595 + * offsets can be large so use the 32/64 bit types for these fields.
596 + *
597 + * Do not use sizeof() on these structures, modutils may be using extra
598 + * fields.  Instead use the size fields in the header to access the
599 + * other bits of data.
600 + */  
601 +
602 +struct kallsyms_header {
603 +       int             size;           /* Size of this header */
604 +       ElfW(Word)      total_size;     /* Total size of kallsyms data */
605 +       int             sections;       /* Number of section entries */
606 +       ElfW(Off)       section_off;    /* Offset to first section entry */
607 +       int             section_size;   /* Size of one section entry */
608 +       int             symbols;        /* Number of symbol entries */
609 +       ElfW(Off)       symbol_off;     /* Offset to first symbol entry */
610 +       int             symbol_size;    /* Size of one symbol entry */
611 +       ElfW(Off)       string_off;     /* Offset to first string */
612 +       ElfW(Addr)      start;          /* Start address of first section */
613 +       ElfW(Addr)      end;            /* End address of last section */
614 +};
615 +
616 +struct kallsyms_section {
617 +       ElfW(Addr)      start;          /* Start address of section */
618 +       ElfW(Word)      size;           /* Size of this section */
619 +       ElfW(Off)       name_off;       /* Offset to section name */
620 +       ElfW(Word)      flags;          /* Flags from section */
621 +};
622 +
623 +struct kallsyms_symbol {
624 +       ElfW(Off)       section_off;    /* Offset to section that owns this symbol */
625 +       ElfW(Addr)      symbol_addr;    /* Address of symbol */
626 +       ElfW(Off)       name_off;       /* Offset to symbol name */
627 +};
628 +
629 +#define KALLSYMS_SEC_NAME "__kallsyms"
630 +#define KALLSYMS_IDX 2                 /* obj_kallsyms creates kallsyms as section 2 */
631 +
632 +#define kallsyms_next_sec(h,s) \
633 +       ((s) = (struct kallsyms_section *)((char *)(s) + (h)->section_size))
634 +#define kallsyms_next_sym(h,s) \
635 +       ((s) = (struct kallsyms_symbol *)((char *)(s) + (h)->symbol_size))
636 +
637 +int kallsyms_symbol_to_address(
638 +       const char       *name,                 /* Name to lookup */
639 +       unsigned long    *token,                /* Which module to start with */
640 +       const char      **mod_name,             /* Set to module name or "kernel" */
641 +       unsigned long    *mod_start,            /* Set to start address of module */
642 +       unsigned long    *mod_end,              /* Set to end address of module */
643 +       const char      **sec_name,             /* Set to section name */
644 +       unsigned long    *sec_start,            /* Set to start address of section */
645 +       unsigned long    *sec_end,              /* Set to end address of section */
646 +       const char      **sym_name,             /* Set to full symbol name */
647 +       unsigned long    *sym_start,            /* Set to start address of symbol */
648 +       unsigned long    *sym_end               /* Set to end address of symbol */
649 +       );
650 +
651 +int kallsyms_address_to_symbol(
652 +       unsigned long     address,              /* Address to lookup */
653 +       const char      **mod_name,             /* Set to module name */
654 +       unsigned long    *mod_start,            /* Set to start address of module */
655 +       unsigned long    *mod_end,              /* Set to end address of module */
656 +       const char      **sec_name,             /* Set to section name */
657 +       unsigned long    *sec_start,            /* Set to start address of section */
658 +       unsigned long    *sec_end,              /* Set to end address of section */
659 +       const char      **sym_name,             /* Set to full symbol name */
660 +       unsigned long    *sym_start,            /* Set to start address of symbol */
661 +       unsigned long    *sym_end               /* Set to end address of symbol */
662 +       );
663 +
664 +int kallsyms_sections(void *token,
665 +                     int (*callback)(void *,   /* token */
666 +                       const char *,           /* module name */
667 +                       const char *,           /* section name */
668 +                       ElfW(Addr),             /* Section start */
669 +                       ElfW(Addr),             /* Section end */
670 +                       ElfW(Word)              /* Section flags */
671 +                     )
672 +               );
673 +
674 +#endif /* kallsyms.h */
675 Index: linux-2.4.29/arch/i386/vmlinux.lds.S
676 ===================================================================
677 --- linux-2.4.29.orig/arch/i386/vmlinux.lds.S   2005-05-08 23:07:09.948513728 +0300
678 +++ linux-2.4.29/arch/i386/vmlinux.lds.S        2005-05-08 23:14:24.128508336 +0300
679 @@ -28,6 +28,10 @@
680    __ksymtab : { *(__ksymtab) }
681    __stop___ksymtab = .;
682  
683 +  __start___kallsyms = .; /* All kernel symbols */
684 +  __kallsyms : { *(__kallsyms) }
685 +  __stop___kallsyms = .;
686 +
687    .data : {                    /* Data */
688         *(.data)
689         CONSTRUCTORS