Whamcloud - gitweb
add linux/kallsyms.h kernel/kallsyms.c
[fs/lustre-release.git] / lustre / kernel_patches / patches / kksymoops-2.4.24.vanilla.patch
index dd76be4..7fe1b4e 100644 (file)
@@ -1,15 +1,3 @@
-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       
@@ -207,14 +195,512 @@ diff -urNp linux-700/kernel/kksymoops.c linux-720/kernel/kksymoops.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