From 218af2f340009e624603253ca8a35c884f31ab5a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 26 Sep 2002 03:31:07 -0700 Subject: [PATCH] kksymoops-2.5.38-C9 Make the kernel print out symbolic bactraces if symbol table information is available (CONFIG_KALLSYMS) --- include/linux/kallsyms.h | 163 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/module.h | 27 +++++++- include/linux/sched.h | 6 ++ 3 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 include/linux/kallsyms.h (limited to 'include/linux') diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h new file mode 100644 index 000000000000..52226e6e158a --- /dev/null +++ b/include/linux/kallsyms.h @@ -0,0 +1,163 @@ +/* kallsyms headers + Copyright 2000 Keith Owens + + 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: linux-2.4.9-kallsyms.patch,v 1.8 2002/02/11 18:34:53 arjanv 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 +#else /* __KERNEL__ */ +#include +#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 */ diff --git a/include/linux/module.h b/include/linux/module.h index 9a47e8926bfd..c71778e38536 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -316,8 +317,6 @@ static const struct gtype##_id * __module_##gtype##_table \ #define MOD_DEC_USE_COUNT do { } while (0) #define MOD_IN_USE 1 -extern struct module *module_list; - #endif /* !__GENKSYMS__ */ #endif /* MODULE */ @@ -506,4 +505,28 @@ __asm__(".section __ksymtab,\"a\"\n.previous"); #define SET_MODULE_OWNER(some_struct) do { } while (0) #endif +extern void print_modules(void); + +#if defined(CONFIG_MODULES) || defined(CONFIG_KALLSYMS) + +extern struct module *module_list; + +/* + * print_symbols takes a format string containing one %s. + * If support for resolving symbols is compiled in, the %s will + * be replaced by the closest symbol to the address and the entire + * string is printk()ed. Otherwise, nothing is printed. + */ +extern void print_symbol(const char *fmt, unsigned long address); + +#else + +static inline int +print_symbol(const char *fmt, unsigned long address) +{ + return -ESRCH; +} + +#endif + #endif /* _LINUX_MODULE_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 471dcb9c108d..6e535c5b6ebc 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -152,7 +152,13 @@ typedef struct task_struct task_t; extern void sched_init(void); extern void init_idle(task_t *idle, int cpu); + extern void show_state(void); +extern void show_trace(unsigned long *stack); +extern void show_stack(unsigned long *stack); +extern void show_regs(struct pt_regs *); + + extern void cpu_init (void); extern void trap_init(void); extern void update_process_times(int user); -- cgit v1.2.3