941 lines
26 KiB
Diff
941 lines
26 KiB
Diff
diff -up rsyslog-3.14.1/plugins/imklog/ksym.c.symbolLookup rsyslog-3.14.1/plugins/imklog/ksym.c
|
|
--- rsyslog-3.14.1/plugins/imklog/ksym.c.symbolLookup 2008-04-08 12:05:42.000000000 +0200
|
|
+++ rsyslog-3.14.1/plugins/imklog/ksym.c 2008-04-08 12:12:39.000000000 +0200
|
|
@@ -120,16 +120,10 @@
|
|
#include <syslog.h>
|
|
#include "imklog.h"
|
|
#include "ksyms.h"
|
|
+#include "module.h"
|
|
|
|
|
|
-/* Variables static to this module. */
|
|
-struct sym_table
|
|
-{
|
|
- unsigned long value;
|
|
- char *name;
|
|
-};
|
|
-
|
|
-static int num_syms = 0;
|
|
+int num_syms = 0;
|
|
static int i_am_paranoid = 0;
|
|
static char vstring[12];
|
|
static struct sym_table *sym_array = (struct sym_table *) 0;
|
|
@@ -589,38 +583,65 @@ static int AddSymbol(unsigned long addre
|
|
* If a match is found the pointer to the symbolic name most
|
|
* closely matching the address is returned.
|
|
**************************************************************************/
|
|
-char * LookupSymbol(unsigned long value, struct symbol *sym)
|
|
+char * LookupSymbol(value, sym)
|
|
+
|
|
+ unsigned long value;
|
|
+
|
|
+ struct symbol *sym;
|
|
+
|
|
{
|
|
- auto int lp;
|
|
- auto char *last;
|
|
+ auto int lp;
|
|
|
|
- if (!sym_array)
|
|
- return((char *) 0);
|
|
+ auto char *last;
|
|
+ auto char *name;
|
|
|
|
- last = sym_array[0].name;
|
|
- sym->offset = 0;
|
|
- sym->size = 0;
|
|
- if ( value < sym_array[0].value )
|
|
- return((char *) 0);
|
|
-
|
|
- for(lp= 0; lp <= num_syms; ++lp)
|
|
- {
|
|
- if ( sym_array[lp].value > value )
|
|
- {
|
|
- sym->offset = value - sym_array[lp-1].value;
|
|
- sym->size = sym_array[lp].value - \
|
|
- sym_array[lp-1].value;
|
|
- return(last);
|
|
- }
|
|
- last = sym_array[lp].name;
|
|
- }
|
|
+ struct symbol ksym, msym;
|
|
|
|
- if ( (last = LookupModuleSymbol(value, sym)) != (char *) 0 )
|
|
- return(last);
|
|
+ if (!sym_array)
|
|
+ return((char *) 0);
|
|
|
|
- return(NULL);
|
|
-}
|
|
+ last = sym_array[0].name;
|
|
+ ksym.offset = 0;
|
|
+ ksym.size = 0;
|
|
+ if ( value < sym_array[0].value )
|
|
+ return((char *) 0);
|
|
|
|
+ for(lp = 0; lp <= num_syms; ++lp)
|
|
+ {
|
|
+ if ( sym_array[lp].value > value )
|
|
+ {
|
|
+ ksym.offset = value - sym_array[lp-1].value;
|
|
+ ksym.size = sym_array[lp].value - \
|
|
+ sym_array[lp-1].value;
|
|
+ break;
|
|
+ }
|
|
+ last = sym_array[lp].name;
|
|
+ }
|
|
+
|
|
+ name = LookupModuleSymbol(value, &msym);
|
|
+
|
|
+ if ( ksym.offset == 0 && msym.offset == 0 )
|
|
+ {
|
|
+ return((char *) 0);
|
|
+ }
|
|
+
|
|
+ if ( ksym.offset == 0 || msym.offset < 0 ||
|
|
+ (ksym.offset > 0 && ksym.offset < msym.offset) )
|
|
+ {
|
|
+ sym->offset = ksym.offset;
|
|
+ sym->size = ksym.size;
|
|
+ return(last);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ sym->offset = msym.offset;
|
|
+ sym->size = msym.size;
|
|
+ return(name);
|
|
+ }
|
|
+
|
|
+
|
|
+ return((char *) 0);
|
|
+}
|
|
|
|
/**************************************************************************
|
|
* Function: FreeSymbols
|
|
@@ -679,6 +700,9 @@ extern char *ExpandKadds(char *line, cha
|
|
auto unsigned long int value;
|
|
auto struct symbol sym;
|
|
|
|
+ sym.offset = 0;
|
|
+ sym.size = 0;
|
|
+
|
|
/*
|
|
* This is as handy a place to put this as anyplace.
|
|
*
|
|
@@ -819,7 +843,7 @@ extern char *ExpandKadds(char *line, cha
|
|
{
|
|
--value;
|
|
++kp;
|
|
- elp += sprintf(elp, "+%x/%d", sym.offset, sym.size);
|
|
+ elp += sprintf(elp, "+0x%x/0x%02x", sym.offset, sym.size);
|
|
}
|
|
strncat(elp, kp, value);
|
|
elp += value;
|
|
diff -up rsyslog-3.14.1/plugins/imklog/module.h.symbolLookup rsyslog-3.14.1/plugins/imklog/module.h
|
|
--- rsyslog-3.14.1/plugins/imklog/module.h.symbolLookup 2007-12-17 12:52:10.000000000 +0100
|
|
+++ rsyslog-3.14.1/plugins/imklog/module.h 2008-04-08 11:59:49.000000000 +0200
|
|
@@ -19,63 +19,18 @@
|
|
*
|
|
* A copy of the GPL can be found in the file "COPYING" in this distribution.
|
|
*/
|
|
-struct kernel_sym
|
|
-{
|
|
- unsigned long value;
|
|
- char name[60];
|
|
-};
|
|
|
|
-struct module_symbol
|
|
+struct sym_table
|
|
{
|
|
- unsigned long value;
|
|
- const char *name;
|
|
+ unsigned long value;
|
|
+ char *name;
|
|
};
|
|
|
|
-struct module_ref
|
|
+struct Module
|
|
{
|
|
- struct module *dep; /* "parent" pointer */
|
|
- struct module *ref; /* "child" pointer */
|
|
- struct module_ref *next_ref;
|
|
-};
|
|
+ struct sym_table *sym_array;
|
|
+ int num_syms;
|
|
|
|
-struct module_info
|
|
-{
|
|
- unsigned long addr;
|
|
- unsigned long size;
|
|
- unsigned long flags;
|
|
- long usecount;
|
|
+ char *name;
|
|
};
|
|
|
|
-
|
|
-typedef struct { volatile int counter; } atomic_t;
|
|
-
|
|
-struct module
|
|
-{
|
|
- unsigned long size_of_struct; /* == sizeof(module) */
|
|
- struct module *next;
|
|
- const char *name;
|
|
- unsigned long size;
|
|
-
|
|
- union
|
|
- {
|
|
- atomic_t usecount;
|
|
- long pad;
|
|
- } uc; /* Needs to keep its size - so says rth */
|
|
-
|
|
- unsigned long flags; /* AUTOCLEAN et al */
|
|
-
|
|
- unsigned nsyms;
|
|
- unsigned ndeps;
|
|
-
|
|
- struct module_symbol *syms;
|
|
- struct module_ref *deps;
|
|
- struct module_ref *refs;
|
|
- int (*init)(void);
|
|
- void (*cleanup)(void);
|
|
- const struct exception_table_entry *ex_table_start;
|
|
- const struct exception_table_entry *ex_table_end;
|
|
-#ifdef __alpha__
|
|
- unsigned long gp;
|
|
-#endif
|
|
-};
|
|
-
|
|
diff -up rsyslog-3.14.1/plugins/imklog/ksym_mod.c.symbolLookup rsyslog-3.14.1/plugins/imklog/ksym_mod.c
|
|
--- rsyslog-3.14.1/plugins/imklog/ksym_mod.c.symbolLookup 2008-03-19 18:35:09.000000000 +0100
|
|
+++ rsyslog-3.14.1/plugins/imklog/ksym_mod.c 2008-04-08 11:59:49.000000000 +0200
|
|
@@ -86,6 +86,7 @@
|
|
#include "config.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
+#include <ctype.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
#include <string.h>
|
|
@@ -97,8 +98,6 @@
|
|
#include <linux/module.h>
|
|
#else /* __GLIBC__ */
|
|
#include "module.h"
|
|
-extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
|
|
-extern int get_kernel_syms __P ((struct kernel_sym *__table));
|
|
#endif /* __GLIBC__ */
|
|
#include <stdarg.h>
|
|
#include <paths.h>
|
|
@@ -108,42 +107,7 @@ extern int get_kernel_syms __P ((struct
|
|
#include "imklog.h"
|
|
#include "ksyms.h"
|
|
|
|
-
|
|
-#if !defined(__GLIBC__)
|
|
-/*
|
|
- * The following bit uses some kernel/library magic to product what
|
|
- * looks like a function call to user level code. This function is
|
|
- * actually a system call in disguise. The purpose of the getsyms
|
|
- * call is to return a current copy of the in-kernel symbol table.
|
|
- */
|
|
-#define __LIBRARY__
|
|
-#include <linux/unistd.h>
|
|
-#define __NR_getsyms __NR_get_kernel_syms
|
|
-_syscall1(int, getsyms, struct kernel_sym *, syms);
|
|
-#undef __LIBRARY__
|
|
-extern int getsyms(struct kernel_sym *);
|
|
-#else /* __GLIBC__ */
|
|
-#define getsyms get_kernel_syms
|
|
-#endif /* __GLIBC__ */
|
|
-
|
|
-/* Variables static to this module. */
|
|
-struct sym_table
|
|
-{
|
|
- unsigned long value;
|
|
- char *name;
|
|
-};
|
|
-
|
|
-struct Module
|
|
-{
|
|
- struct sym_table *sym_array;
|
|
- int num_syms;
|
|
-
|
|
- char *name;
|
|
- struct module module;
|
|
-#if LINUX_VERSION_CODE >= 0x20112
|
|
- struct module_info module_info;
|
|
-#endif
|
|
-};
|
|
+#define KSYMS "/proc/kallsyms"
|
|
|
|
static int num_modules = 0;
|
|
struct Module *sym_array_modules = (struct Module *) 0;
|
|
@@ -153,10 +117,13 @@ static int have_modules = 0;
|
|
|
|
/* Function prototypes. */
|
|
static void FreeModules(void);
|
|
-static int AddSymbol(struct Module *mp, unsigned long, char *);
|
|
-static int AddModule(unsigned long, char *);
|
|
+static int AddSymbol(const char *);
|
|
+struct Module *AddModule(const char *);
|
|
static int symsort(const void *, const void *);
|
|
|
|
+/* Imported from ksym.c */
|
|
+extern int num_syms;
|
|
+
|
|
|
|
/**************************************************************************
|
|
* Function: InitMsyms
|
|
@@ -175,94 +142,74 @@ static int symsort(const void *, const v
|
|
**************************************************************************/
|
|
extern int InitMsyms(void)
|
|
{
|
|
- auto int rtn,
|
|
- tmp;
|
|
|
|
- auto struct kernel_sym *ksym_table,
|
|
- *p;
|
|
+ auto int rtn,
|
|
+ tmp;
|
|
+
|
|
+ FILE *ksyms;
|
|
|
|
+ char buf[128];
|
|
+ char *p;
|
|
|
|
/* Initialize the kernel module symbol table. */
|
|
FreeModules();
|
|
|
|
+ ksyms = fopen(KSYMS, "r");
|
|
|
|
- /*
|
|
- * The system call which returns the kernel symbol table has
|
|
- * essentialy two modes of operation. Called with a null pointer
|
|
- * the system call returns the number of symbols defined in the
|
|
- * the table.
|
|
- *
|
|
- * The second mode of operation is to pass a valid pointer to
|
|
- * the call which will then load the current symbol table into
|
|
- * the memory provided.
|
|
- *
|
|
- * Returning the symbol table is essentially an all or nothing
|
|
- * proposition so we need to pre-allocate enough memory for the
|
|
- * complete table regardless of how many symbols we need.
|
|
- *
|
|
- * Bummer.
|
|
- */
|
|
- if ( (rtn = getsyms((struct kernel_sym *) 0)) < 0 )
|
|
- {
|
|
- if ( errno == ENOSYS )
|
|
- Syslog(LOG_INFO, "No module symbols loaded - "
|
|
- "kernel modules not enabled.\n");
|
|
- else
|
|
- Syslog(LOG_ERR, "Error loading kernel symbols " \
|
|
- "- %s\n", strerror(errno));
|
|
- return(0);
|
|
- }
|
|
- dbgprintf("Loading kernel module symbols - Size of table: %d\n", rtn);
|
|
-
|
|
- ksym_table = (struct kernel_sym *) malloc(rtn * sizeof(struct kernel_sym));
|
|
- if ( ksym_table == (struct kernel_sym *) 0 )
|
|
- {
|
|
- Syslog(LOG_WARNING, " Failed memory allocation for kernel symbol table.\n");
|
|
- return(0);
|
|
- }
|
|
- if ( (rtn = getsyms(ksym_table)) < 0 )
|
|
- {
|
|
- Syslog(LOG_WARNING, "Error reading kernel symbols - %s\n", strerror(errno));
|
|
- return(0);
|
|
- }
|
|
-
|
|
+ if ( ksyms == NULL )
|
|
+ {
|
|
+ if ( errno == ENOENT )
|
|
+ Syslog(LOG_INFO, "No module symbols loaded - "
|
|
+ "kernel modules not enabled.\n");
|
|
+ else
|
|
+ Syslog(LOG_ERR, "Error loading kernel symbols " \
|
|
+ "- %s\n", strerror(errno));
|
|
+ fclose(ksyms);
|
|
+ return(0);
|
|
+ }
|
|
+
|
|
+ dbgprintf("Loading kernel module symbols - Source: %s\n", KSYMS);
|
|
+
|
|
+ while ( fgets(buf, sizeof(buf), ksyms) != NULL )
|
|
+ {
|
|
+ if (num_syms > 0 && index(buf, '[') == NULL)
|
|
+ continue;
|
|
+
|
|
+ p = index(buf, ' ');
|
|
+
|
|
+ if ( p == NULL )
|
|
+ continue;
|
|
+
|
|
+ if ( buf[strlen(buf)-1] == '\n' )
|
|
+ buf[strlen(buf)-1] = '\0';
|
|
+ /* overlong lines will be ignored above */
|
|
+
|
|
+ AddSymbol(buf);
|
|
+ }
|
|
+
|
|
+ fclose(ksyms);
|
|
+
|
|
+ have_modules = 1;
|
|
+
|
|
+ /* Sort the symbol tables in each module. */
|
|
+ for (rtn = tmp = 0; tmp < num_modules; ++tmp)
|
|
+ {
|
|
+ rtn += sym_array_modules[tmp].num_syms;
|
|
+ if ( sym_array_modules[tmp].num_syms < 2 )
|
|
+ continue;
|
|
+ qsort(sym_array_modules[tmp].sym_array, \
|
|
+ sym_array_modules[tmp].num_syms, \
|
|
+ sizeof(struct sym_table), symsort);
|
|
+ }
|
|
+
|
|
+ if ( rtn == 0 )
|
|
+ Syslog(LOG_INFO, "No module symbols loaded.");
|
|
+ else
|
|
+ Syslog(LOG_INFO, "Loaded %d %s from %d module%s", rtn, \
|
|
+ (rtn == 1) ? "symbol" : "symbols", \
|
|
+ num_modules, (num_modules == 1) ? "." : "s.");
|
|
|
|
- /*
|
|
- * Build a symbol table compatible with the other one used by
|
|
- * klogd.
|
|
- */
|
|
- tmp = rtn;
|
|
- p = ksym_table;
|
|
- while ( tmp-- )
|
|
- {
|
|
- if ( !AddModule(p->value, p->name) )
|
|
- {
|
|
- Syslog(LOG_WARNING, "Error adding kernel module table entry.\n");
|
|
- free(ksym_table);
|
|
- return(0);
|
|
- }
|
|
- ++p;
|
|
- }
|
|
-
|
|
- /* Sort the symbol tables in each module. */
|
|
- for (rtn = tmp= 0; tmp < num_modules; ++tmp)
|
|
- {
|
|
- rtn += sym_array_modules[tmp].num_syms;
|
|
- if ( sym_array_modules[tmp].num_syms < 2 )
|
|
- continue;
|
|
- qsort(sym_array_modules[tmp].sym_array, \
|
|
- sym_array_modules[tmp].num_syms, \
|
|
- sizeof(struct sym_table), symsort);
|
|
- }
|
|
-
|
|
- if ( rtn == 0 )
|
|
- Syslog(LOG_INFO, "No module symbols loaded.");
|
|
- else
|
|
- Syslog(LOG_INFO, "Loaded %d %s from %d module%s", rtn, \
|
|
- (rtn == 1) ? "symbol" : "symbols", \
|
|
- num_modules, (num_modules == 1) ? "." : "s.");
|
|
- free(ksym_table);
|
|
- return(1);
|
|
+ return(1);
|
|
}
|
|
|
|
|
|
@@ -295,134 +242,100 @@ extern void DeinitMsyms(void)
|
|
*
|
|
* Return: void
|
|
**************************************************************************/
|
|
-static void FreeModules(void)
|
|
+static void FreeModules()
|
|
+
|
|
{
|
|
- auto int nmods,
|
|
- nsyms;
|
|
+ auto int nmods,
|
|
+ nsyms;
|
|
|
|
- auto struct Module *mp;
|
|
+ auto struct Module *mp;
|
|
|
|
|
|
- /* Check to see if the module symbol tables need to be cleared. */
|
|
- have_modules = 0;
|
|
- if ( num_modules == 0 )
|
|
- return;
|
|
-
|
|
-
|
|
- for (nmods= 0; nmods < num_modules; ++nmods)
|
|
- {
|
|
- mp = &sym_array_modules[nmods];
|
|
- if ( mp->num_syms == 0 )
|
|
- continue;
|
|
-
|
|
- for (nsyms= 0; nsyms < mp->num_syms; ++nsyms)
|
|
- free(mp->sym_array[nsyms].name);
|
|
- free(mp->sym_array);
|
|
- }
|
|
-
|
|
- free(sym_array_modules);
|
|
- sym_array_modules = (struct Module *) 0;
|
|
- num_modules = 0;
|
|
- return;
|
|
+ /* Check to see if the module symbol tables need to be cleared. */
|
|
+ have_modules = 0;
|
|
+ if ( num_modules == 0 )
|
|
+ return;
|
|
+
|
|
+ if ( sym_array_modules == NULL )
|
|
+ return;
|
|
+
|
|
+ for (nmods = 0; nmods < num_modules; ++nmods)
|
|
+ {
|
|
+ mp = &sym_array_modules[nmods];
|
|
+ if ( mp->num_syms == 0 )
|
|
+ continue;
|
|
+
|
|
+ for (nsyms= 0; nsyms < mp->num_syms; ++nsyms)
|
|
+ free(mp->sym_array[nsyms].name);
|
|
+ free(mp->sym_array);
|
|
+ if ( mp->name != NULL )
|
|
+ free(mp->name);
|
|
+ }
|
|
+
|
|
+ free(sym_array_modules);
|
|
+ sym_array_modules = (struct Module *) 0;
|
|
+ num_modules = 0;
|
|
+ return;
|
|
}
|
|
|
|
-
|
|
/**************************************************************************
|
|
- * Function: AddModule
|
|
- *
|
|
- * Purpose: This function is responsible for adding a module to
|
|
- * the list of currently loaded modules.
|
|
- *
|
|
- * Arguements: (unsigned long) address, (char *) symbol
|
|
- *
|
|
- * address:-> The address of the module.
|
|
- *
|
|
- * symbol:-> The name of the module.
|
|
- *
|
|
- * Return: int
|
|
- **************************************************************************/
|
|
-static int AddModule(unsigned long address, char *symbol)
|
|
-{
|
|
- auto int memfd;
|
|
- auto struct Module *mp;
|
|
+ * * Function: AddModule
|
|
+ * *
|
|
+ * * Purpose: This function is responsible for adding a module to
|
|
+ * * the list of currently loaded modules.
|
|
+ * *
|
|
+ * * Arguments: (const char *) module
|
|
+ * *
|
|
+ * * module:-> The name of the module.
|
|
+ * *
|
|
+ * * Return: struct Module *
|
|
+ * **************************************************************************/
|
|
|
|
+struct Module *AddModule(module)
|
|
|
|
- /* Return if we have loaded the modules. */
|
|
- if ( have_modules )
|
|
- return(1);
|
|
-
|
|
- /*
|
|
- * The following section of code is responsible for determining
|
|
- * whether or not we are done reading the list of modules.
|
|
- */
|
|
- if ( symbol[0] == '#' )
|
|
- {
|
|
-
|
|
- if ( symbol[1] == '\0' )
|
|
- {
|
|
- /*
|
|
- * A symbol which consists of a # sign only
|
|
- * signifies a a resident kernel segment. When we
|
|
- * hit one of these we are done reading the
|
|
- * module list.
|
|
- */
|
|
- have_modules = 1;
|
|
- return(1);
|
|
- }
|
|
- /* Allocate space for the module. */
|
|
- sym_array_modules = (struct Module *) \
|
|
- realloc(sym_array_modules, \
|
|
- (num_modules+1) * sizeof(struct Module));
|
|
- if ( sym_array_modules == (struct Module *) 0 )
|
|
- {
|
|
- Syslog(LOG_WARNING, "Cannot allocate Module array.\n");
|
|
- return(0);
|
|
- }
|
|
- mp = &sym_array_modules[num_modules];
|
|
-
|
|
- if ( (memfd = open("/dev/kmem", O_RDONLY)) < 0 )
|
|
- {
|
|
- Syslog(LOG_WARNING, "Error opening /dev/kmem\n");
|
|
- return(0);
|
|
- }
|
|
- if ( lseek64(memfd, address, SEEK_SET) < 0 )
|
|
- {
|
|
- Syslog(LOG_WARNING, "Error seeking in /dev/kmem\n");
|
|
- Syslog(LOG_WARNING, "Symbol %s, value %08lx\n", symbol,
|
|
- (unsigned long) address);
|
|
- return(0);
|
|
- }
|
|
- if ( read(memfd, \
|
|
- (char *)&sym_array_modules[num_modules].module, \
|
|
- sizeof(struct module)) < 0 )
|
|
- {
|
|
- Syslog(LOG_WARNING, "Error reading module "
|
|
- "descriptor.\n");
|
|
- return(0);
|
|
- }
|
|
- close(memfd);
|
|
-
|
|
- /* Save the module name. */
|
|
- mp->name = (char *) malloc(strlen(&symbol[1]) + 1);
|
|
- if ( mp->name == (char *) 0 )
|
|
- return(0);
|
|
- strcpy(mp->name, &symbol[1]);
|
|
-
|
|
- mp->num_syms = 0;
|
|
- mp->sym_array = (struct sym_table *) 0;
|
|
- ++num_modules;
|
|
- return(1);
|
|
- }
|
|
- else
|
|
- {
|
|
- if (num_modules > 0)
|
|
- mp = &sym_array_modules[num_modules - 1];
|
|
- else
|
|
- mp = &sym_array_modules[0];
|
|
- AddSymbol(mp, address, symbol);
|
|
- }
|
|
+ const char *module;
|
|
|
|
- return(1);
|
|
+{
|
|
+ struct Module *mp;
|
|
+
|
|
+ if ( num_modules == 0 )
|
|
+ {
|
|
+ sym_array_modules = (struct Module *)malloc(sizeof(struct Module));
|
|
+
|
|
+ if ( sym_array_modules == NULL )
|
|
+ {
|
|
+ Syslog(LOG_WARNING, "Cannot allocate Module array.\n");
|
|
+ return NULL;
|
|
+ }
|
|
+ mp = sym_array_modules;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ /* Allocate space for the module. */
|
|
+ mp = (struct Module *) \
|
|
+ realloc(sym_array_modules, \
|
|
+ (num_modules+1) * sizeof(struct Module));
|
|
+
|
|
+ if ( mp == NULL )
|
|
+ {
|
|
+ Syslog(LOG_WARNING, "Cannot allocate Module array.\n");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ sym_array_modules = mp;
|
|
+ mp = &sym_array_modules[num_modules];
|
|
+ }
|
|
+
|
|
+ num_modules++;
|
|
+ mp->sym_array = NULL;
|
|
+ mp->num_syms = 0;
|
|
+
|
|
+ if ( module != NULL )
|
|
+ mp->name = strdup(module);
|
|
+ else
|
|
+ mp->name = NULL;
|
|
+
|
|
+ return mp;
|
|
}
|
|
|
|
|
|
@@ -432,49 +345,85 @@ static int AddModule(unsigned long addre
|
|
* Purpose: This function is responsible for adding a symbol name
|
|
* and its address to the symbol table.
|
|
*
|
|
- * Arguements: (struct Module *) mp, (unsigned long) address, (char *) symbol
|
|
- *
|
|
- * mp:-> A pointer to the module which the symbol is
|
|
- * to be added to.
|
|
- *
|
|
- * address:-> The address of the symbol.
|
|
- *
|
|
- * symbol:-> The name of the symbol.
|
|
+ * Arguements: const char *
|
|
*
|
|
* Return: int
|
|
*
|
|
* A boolean value is assumed. True if the addition is
|
|
* successful. False if not.
|
|
**************************************************************************/
|
|
-static int AddSymbol(struct Module *mp, unsigned long address, char *symbol)
|
|
+static int AddSymbol(line)
|
|
+
|
|
+ const char *line;
|
|
+
|
|
{
|
|
- auto int tmp;
|
|
+ char *module;
|
|
+ unsigned long address;
|
|
+ char *p;
|
|
+ static char *lastmodule = NULL;
|
|
+ struct Module *mp;
|
|
|
|
- /* Allocate space for the symbol table entry. */
|
|
- mp->sym_array = (struct sym_table *) realloc(mp->sym_array, \
|
|
- (mp->num_syms+1) * sizeof(struct sym_table));
|
|
- if ( mp->sym_array == (struct sym_table *) 0 )
|
|
- return(0);
|
|
+ module = index(line, '[');
|
|
|
|
- /* Then the space for the symbol. */
|
|
- tmp = strlen(symbol);
|
|
- tmp += (strlen(mp->name) + 1);
|
|
- mp->sym_array[mp->num_syms].name = (char *) malloc(tmp + 1);
|
|
- if ( mp->sym_array[mp->num_syms].name == (char *) 0 )
|
|
- return(0);
|
|
- memset(mp->sym_array[mp->num_syms].name, '\0', tmp + 1);
|
|
-
|
|
- /* Stuff interesting information into the module. */
|
|
- mp->sym_array[mp->num_syms].value = address;
|
|
- strcpy(mp->sym_array[mp->num_syms].name, mp->name);
|
|
- strcat(mp->sym_array[mp->num_syms].name, ":");
|
|
- strcat(mp->sym_array[mp->num_syms].name, symbol);
|
|
- ++mp->num_syms;
|
|
+ if ( module != NULL )
|
|
+ {
|
|
+ p = index(module, ']');
|
|
|
|
- return(1);
|
|
+ if ( p != NULL )
|
|
+ *p = '\0';
|
|
+
|
|
+ p = module++;
|
|
+
|
|
+ while ( isspace(*(--p)) );
|
|
+ *(++p) = '\0';
|
|
+ }
|
|
+
|
|
+ p = index(line, ' ');
|
|
+
|
|
+ if ( p == NULL )
|
|
+ return(0);
|
|
+
|
|
+ *p = '\0';
|
|
+
|
|
+ address = strtoul(line, (char **) 0, 16);
|
|
+
|
|
+ p += 3;
|
|
+
|
|
+ if ( num_modules == 0 ||
|
|
+ ( lastmodule == NULL && module != NULL ) ||
|
|
+ ( module == NULL && lastmodule != NULL) ||
|
|
+ ( module != NULL && strcmp(module, lastmodule)))
|
|
+ {
|
|
+ mp = AddModule(module);
|
|
+
|
|
+ if ( mp == NULL )
|
|
+ return(0);
|
|
+ }
|
|
+ else
|
|
+ mp = &sym_array_modules[num_modules-1];
|
|
+
|
|
+ lastmodule = mp->name;
|
|
+
|
|
+ /* Allocate space for the symbol table entry. */
|
|
+ mp->sym_array = (struct sym_table *) realloc(mp->sym_array, \
|
|
+ (mp->num_syms+1) * sizeof(struct sym_table));
|
|
+
|
|
+ if ( mp->sym_array == (struct sym_table *) 0 )
|
|
+ return(0);
|
|
+
|
|
+ mp->sym_array[mp->num_syms].name = strdup(p);
|
|
+ if ( mp->sym_array[mp->num_syms].name == (char *) 0 )
|
|
+ return(0);
|
|
+
|
|
+ /* Stuff interesting information into the module. */
|
|
+ mp->sym_array[mp->num_syms].value = address;
|
|
+ ++mp->num_syms;
|
|
+
|
|
+ return(1);
|
|
}
|
|
|
|
|
|
+
|
|
/**************************************************************************
|
|
* Function: LookupModuleSymbol
|
|
*
|
|
@@ -494,103 +443,68 @@ static int AddSymbol(struct Module *mp,
|
|
* If a match is found the pointer to the symbolic name most
|
|
* closely matching the address is returned.
|
|
**************************************************************************/
|
|
-extern char * LookupModuleSymbol(unsigned long value, struct symbol *sym)
|
|
+extern char * LookupModuleSymbol(value, sym)
|
|
+
|
|
+ unsigned long value;
|
|
+
|
|
+ struct symbol *sym;
|
|
+
|
|
{
|
|
- auto int nmod,
|
|
- nsym;
|
|
- auto struct sym_table *last;
|
|
- auto struct Module *mp;
|
|
-
|
|
-
|
|
- sym->size = 0;
|
|
- sym->offset = 0;
|
|
- if ( num_modules == 0 )
|
|
- return((char *) 0);
|
|
-
|
|
- for(nmod= 0; nmod < num_modules; ++nmod)
|
|
- {
|
|
- mp = &sym_array_modules[nmod];
|
|
+ auto int nmod,
|
|
+ nsym;
|
|
|
|
- /*
|
|
+ auto struct sym_table *last;
|
|
+
|
|
+ auto struct Module *mp;
|
|
+
|
|
+ static char ret[100];
|
|
+
|
|
+
|
|
+ sym->size = 0;
|
|
+ sym->offset = 0;
|
|
+ if ( num_modules == 0 )
|
|
+ return((char *) 0);
|
|
+
|
|
+ for (nmod = 0; nmod < num_modules; ++nmod)
|
|
+ {
|
|
+ mp = &sym_array_modules[nmod];
|
|
+
|
|
+ /*
|
|
* Run through the list of symbols in this module and
|
|
- * see if the address can be resolved.
|
|
+ * see if the address can be resolved.
|
|
*/
|
|
- for(nsym= 1, last = &mp->sym_array[0];
|
|
- nsym < mp->num_syms;
|
|
- ++nsym)
|
|
- {
|
|
- if ( mp->sym_array[nsym].value > value )
|
|
- {
|
|
- sym->offset = value - last->value;
|
|
- sym->size = mp->sym_array[nsym].value - \
|
|
- last->value;
|
|
- return(last->name);
|
|
- }
|
|
- last = &mp->sym_array[nsym];
|
|
- }
|
|
-
|
|
- /*
|
|
- * At this stage of the game we still cannot give up the
|
|
- * ghost. There is the possibility that the address is
|
|
- * from a module which has no symbols registered with
|
|
- * the kernel. The solution is to compare the address
|
|
- * against the starting address and extant of the module
|
|
- * If it is in this range we can at least return the
|
|
- * name of the module.
|
|
- */
|
|
-#if LINUX_VERSION_CODE < 0x20112
|
|
- if ( (void *) value >= mp->module.addr &&
|
|
- (void *) value <= (mp->module.addr + \
|
|
- mp->module.size * 4096) )
|
|
-#else
|
|
- if ( value >= mp->module_info.addr &&
|
|
- value <= (mp->module_info.addr + \
|
|
- mp->module.size * 4096) )
|
|
-#endif
|
|
- {
|
|
- /*
|
|
- * A special case needs to be checked for. The above
|
|
- * conditional tells us that we are within the
|
|
- * extant of this module but symbol lookup has
|
|
- * failed.
|
|
- *
|
|
- * We need to check to see if any symbols have
|
|
- * been defined in this module. If there have been
|
|
- * symbols defined the assumption must be made that
|
|
- * the faulting address lies somewhere beyond the
|
|
- * last symbol. About the only thing we can do
|
|
- * at this point is use an offset from this
|
|
- * symbol.
|
|
- */
|
|
- if ( mp->num_syms > 0 )
|
|
- {
|
|
- last = &mp->sym_array[mp->num_syms - 1];
|
|
-#if LINUX_VERSION_CODE < 0x20112
|
|
- sym->size = (int) mp->module.addr + \
|
|
- (mp->module.size * 4096) - value;
|
|
-#else
|
|
- sym->size = (int) mp->module_info.addr + \
|
|
- (mp->module.size * 4096) - value;
|
|
-#endif
|
|
- sym->offset = value - last->value;
|
|
- return(last->name);
|
|
- }
|
|
-
|
|
- /*
|
|
- * There were no symbols defined for this module.
|
|
- * Return the module name and the offset of the
|
|
- * faulting address in the module.
|
|
- */
|
|
- sym->size = mp->module.size * 4096;
|
|
-#if LINUX_VERSION_CODE < 0x20112
|
|
- sym->offset = (void *) value - mp->module.addr;
|
|
-#else
|
|
- sym->offset = value - mp->module_info.addr;
|
|
-#endif
|
|
- return(mp->name);
|
|
- }
|
|
- }
|
|
+ for(nsym = 1, last = &mp->sym_array[0];
|
|
+ nsym < mp->num_syms;
|
|
+ ++nsym)
|
|
+ {
|
|
+ if ( mp->sym_array[nsym].value > value )
|
|
+ {
|
|
+ if ( sym->size == 0 ||
|
|
+ (value - last->value) < sym->offset ||
|
|
+ ( (sym->offset == (value - last->value)) &&
|
|
+ (mp->sym_array[nsym].value-last->value) < sym->size ) )
|
|
+ {
|
|
+ sym->offset = value - last->value;
|
|
+ sym->size = mp->sym_array[nsym].value - \
|
|
+ last->value;
|
|
+ ret[sizeof(ret)-1] = '\0';
|
|
+ if ( mp->name == NULL )
|
|
+ snprintf(ret, sizeof(ret)-1,
|
|
+ "%s", last->name);
|
|
+ else
|
|
+ snprintf(ret, sizeof(ret)-1,
|
|
+ "%s:%s", mp->name, last->name);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ last = &mp->sym_array[nsym];
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if ( sym->size > 0 )
|
|
+ return(ret);
|
|
|
|
- /* It has been a hopeless exercise. */
|
|
- return(NULL);
|
|
+ /* It has been a hopeless exercise. */
|
|
+ return((char *) 0);
|
|
}
|
|
+
|