summaryrefslogtreecommitdiff
path: root/plugins/imklog
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2008-04-10 00:42:31 +0200
committerMichael Biebl <biebl@debian.org>2008-04-10 00:42:31 +0200
commitd7b2091ccb935f85ad5ad43e8fb1d467ff63f979 (patch)
tree9b39fc20e68ed8850daa8fea2fa658c3a510e2cf /plugins/imklog
parent85df627b6c1cfc388a70ef5b01681d5d952a9dd7 (diff)
downloadrsyslog-d7b2091ccb935f85ad5ad43e8fb1d467ff63f979.tar.gz
Imported Upstream version 3.14.2upstream/3.14.2
Diffstat (limited to 'plugins/imklog')
-rw-r--r--plugins/imklog/imklog.h3
-rw-r--r--plugins/imklog/ksym.c186
-rw-r--r--plugins/imklog/ksym_mod.c623
-rw-r--r--plugins/imklog/ksyms.h15
-rw-r--r--plugins/imklog/module.h68
5 files changed, 357 insertions, 538 deletions
diff --git a/plugins/imklog/imklog.h b/plugins/imklog/imklog.h
index 2db7500..71525a7 100644
--- a/plugins/imklog/imklog.h
+++ b/plugins/imklog/imklog.h
@@ -42,6 +42,5 @@ extern void vsyslog(int pri, const char *fmt, va_list ap);
rsRetVal Syslog(int priority, char *fmt, ...) __attribute__((format(printf,2, 3)));
#endif /* #ifndef IMKLOG_H_INCLUDED */
-/*
- * vi:set ai:
+/* vi:set ai:
*/
diff --git a/plugins/imklog/ksym.c b/plugins/imklog/ksym.c
index c9fd714..b7d5903 100644
--- a/plugins/imklog/ksym.c
+++ b/plugins/imklog/ksym.c
@@ -1,8 +1,9 @@
-/*
- ksym.c - functions for kernel address->symbol translation
- Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
- Copyright (c) 1996 Enjellic Systems Development
-
+/* ksym.c - functions for kernel address->symbol translation
+ * Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
+ * Copyright (c) 1996 Enjellic Systems Development
+ * Copyright (c) 1998-2007 Martin Schulze <joey@infodrom.org>
+ * Copyright (C) 2007-2008 Rainer Gerhards <rgerhards@adiscon.com>
+ *
* This file is part of rsyslog.
*
* Rsyslog is free software: you can redistribute it and/or modify
@@ -120,16 +121,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;
@@ -187,26 +182,20 @@ extern int InitKsyms(char *mapfile)
/*
* Search for and open the file containing the kernel symbols.
*/
- if ( mapfile != (char *) 0 )
- {
+ if ( mapfile != (char *) 0 ) {
if ( (sym_file = fopen(mapfile, "r")) == (FILE *) 0 )
{
- Syslog(LOG_WARNING, "Cannot open map file: %s.", \
- mapfile);
+ Syslog(LOG_WARNING, "Cannot open map file: %s.", mapfile);
return(0);
}
- }
- else
- {
- if ( (mapfile = FindSymbolFile()) == (char *) 0 )
- {
+ } else {
+ if ( (mapfile = FindSymbolFile()) == (char *) 0 ) {
Syslog(LOG_WARNING, "Cannot find map file.");
dbgprintf("Cannot find map file.\n");
return(0);
}
- if ( (sym_file = fopen(mapfile, "r")) == (FILE *) 0 )
- {
+ if ( (sym_file = fopen(mapfile, "r")) == (FILE *) 0 ) {
Syslog(LOG_WARNING, "Cannot open map file.");
dbgprintf("Cannot open map file.\n");
return(0);
@@ -222,11 +211,8 @@ extern int InitKsyms(char *mapfile)
* e-mail me a diff containing a parser with suitable political
* correctness -- GW.
*/
- while ( !feof(sym_file) )
- {
- if ( fscanf(sym_file, "%lx %c %s\n", &address, &type, sym)
- != 3 )
- {
+ while ( !feof(sym_file) ) {
+ if ( fscanf(sym_file, "%lx %c %s\n", &address, &type, sym) != 3 ) {
Syslog(LOG_ERR, "Error in symbol table input (#1).");
fclose(sym_file);
return(0);
@@ -234,8 +220,7 @@ extern int InitKsyms(char *mapfile)
if(dbgPrintSymbols)
dbgprintf("Address: %lx, Type: %c, Symbol: %s\n", address, type, sym);
- if ( AddSymbol(address, sym) == 0 )
- {
+ if ( AddSymbol(address, sym) == 0 ) {
Syslog(LOG_ERR, "Error adding symbol - %s.", sym);
fclose(sym_file);
return(0);
@@ -247,16 +232,14 @@ extern int InitKsyms(char *mapfile)
Syslog(LOG_INFO, "Loaded %d symbols from %s.", num_syms, mapfile);
- switch ( version )
- {
+ switch(version) {
case -1:
Syslog(LOG_WARNING, "Symbols do not match kernel version.");
num_syms = 0;
break;
case 0:
- Syslog(LOG_WARNING, "Cannot verify that symbols match " \
- "kernel version.");
+ Syslog(LOG_WARNING, "Cannot verify that symbols match kernel version.");
break;
case 1:
@@ -317,18 +300,16 @@ static char *FindSymbolFile(void)
auto FILE *sym_file = (FILE *) 0;
- if ( uname(&utsname) < 0 )
- {
+ if ( uname(&utsname) < 0 ) {
Syslog(LOG_ERR, "Cannot get kernel version information.");
return(0);
}
dbgprintf("Searching for symbol map.\n");
- for (mf = system_maps; *mf != (char *) 0 && file == (char *) 0; ++mf)
- {
+ for(mf = system_maps; *mf != (char *) 0 && file == (char *) 0; ++mf) {
- sprintf (symfile, "%s-%s", *mf, utsname.release);
+ snprintf(symfile, sizeof(symfile), "%s-%s", *mf, utsname.release);
dbgprintf("Trying %s.\n", symfile);
if ( (sym_file = fopen(symfile, "r")) != (FILE *) 0 ) {
if (CheckMapVersion(symfile) == 1)
@@ -347,10 +328,7 @@ static char *FindSymbolFile(void)
}
- /*
- * At this stage of the game we are at the end of the symbol
- * tables.
- */
+ /* At this stage of the game we are at the end of the symbol tables. */
dbgprintf("End of search list encountered.\n");
return(file);
}
@@ -413,8 +391,7 @@ static int CheckVersion(char *version)
return(0);
- /*
- * Since the symbol looks like a kernel version we can start
+ /* Since the symbol looks like a kernel version we can start
* things out by decoding the version string into its component
* parts.
*/
@@ -426,24 +403,20 @@ static int CheckVersion(char *version)
strlen(prefix), major, minor, patch);
sprintf(vstring, "%d.%d.%d", major, minor, patch);
- /*
- * We should now have the version string in the vstring variable in
+ /* We should now have the version string in the vstring variable in
* the same format that it is stored in by the kernel. We now
* ask the kernel for its version information and compare the two
* values to determine if our system map matches the kernel
* version level.
*/
- if ( uname(&utsname) < 0 )
- {
+ if ( uname(&utsname) < 0 ) {
Syslog(LOG_ERR, "Cannot get kernel version information.");
return(0);
}
dbgprintf("Comparing kernel %s with symbol table %s.\n", utsname.release, vstring);
- if ( sscanf (utsname.release, "%d.%d.%d", &major, &minor, &patch) < 3 )
- {
- Syslog(LOG_ERR, "Kernel send bogus release string `%s'.",
- utsname.release);
+ if ( sscanf (utsname.release, "%d.%d.%d", &major, &minor, &patch) < 3 ) {
+ Syslog(LOG_ERR, "Kernel send bogus release string `%s'.", utsname.release);
return(0);
}
@@ -500,11 +473,8 @@ static int CheckMapVersion(char *fname)
Syslog(LOG_INFO, "Inspecting %s", fname);
version = 0;
- while ( !feof(sym_file) && (version == 0) )
- {
- if ( fscanf(sym_file, "%lx %c %s\n", &address, \
- &type, sym) != 3 )
- {
+ while ( !feof(sym_file) && (version == 0) ) {
+ if ( fscanf(sym_file, "%lx %c %s\n", &address, &type, sym) != 3 ) {
Syslog(LOG_ERR, "Error in symbol table input (#2).");
fclose(sym_file);
return(0);
@@ -515,11 +485,9 @@ static int CheckMapVersion(char *fname)
}
fclose(sym_file);
- switch ( version )
- {
+ switch ( version ) {
case -1:
- Syslog(LOG_ERR, "Symbol table has incorrect " \
- "version number.\n");
+ Syslog(LOG_ERR, "Symbol table has incorrect version number.\n");
break;
case 0:
dbgprintf("No version information found.\n");
@@ -552,14 +520,13 @@ static int CheckMapVersion(char *fname)
static int AddSymbol(unsigned long address, char *symbol)
{
/* Allocate the the symbol table entry. */
- sym_array = (struct sym_table *) realloc(sym_array, (num_syms+1) * \
+ sym_array = (struct sym_table *) realloc(sym_array, (num_syms+1) *
sizeof(struct sym_table));
if ( sym_array == (struct sym_table *) 0 )
return(0);
/* Then the space for the symbol. */
- sym_array[num_syms].name = (char *) malloc(strlen(symbol)*sizeof(char)\
- + 1);
+ sym_array[num_syms].name = (char *) malloc(strlen(symbol)*sizeof(char) + 1);
if ( sym_array[num_syms].name == (char *) 0 )
return(0);
@@ -591,37 +558,53 @@ static int AddSymbol(unsigned long address, char *symbol)
**************************************************************************/
char * LookupSymbol(unsigned long value, struct symbol *sym)
{
- auto int lp;
- auto char *last;
+ auto int lp;
+
+ auto char *last;
+ auto char *name;
+
+ struct symbol ksym, msym;
+
+ if (!sym_array)
+ return((char *) 0);
+
+ 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;
+ }
- if (!sym_array)
- return((char *) 0);
+ name = LookupModuleSymbol(value, &msym);
- 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;
- }
+ 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);
+ }
- if ( (last = LookupModuleSymbol(value, sym)) != (char *) 0 )
- return(last);
- return(NULL);
+ return((char *) 0);
}
-
/**************************************************************************
* Function: FreeSymbols
*
@@ -679,6 +662,9 @@ extern char *ExpandKadds(char *line, char *el)
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.
*
@@ -706,12 +692,10 @@ extern char *ExpandKadds(char *line, char *el)
* messages in this line.
*/
if ( (num_syms == 0) ||
- (kp = strstr(line, "[<")) == (char *) 0 )
- {
+ (kp = strstr(line, "[<")) == (char *) 0 ) {
#ifdef __sparc__
if (num_syms) {
- /*
- * On SPARC, register dumps do not have the [< >] characters in it.
+ /* On SPARC, register dumps do not have the [< >] characters in it.
*/
static struct sparc_tests {
char *str;
@@ -791,14 +775,12 @@ extern char *ExpandKadds(char *line, char *el)
}
/* Loop through and expand all kernel messages. */
- do
- {
+ do {
while ( sl < kp+1 )
*elp++ = *sl++;
/* Now poised at a kernel delimiter. */
- if ( (kp = strstr(sl, ">]")) == (char *) 0 )
- {
+ if ( (kp = strstr(sl, ">]")) == (char *) 0 ) {
strcpy(el, sl);
return(el);
}
@@ -815,11 +797,10 @@ extern char *ExpandKadds(char *line, char *el)
(sym.size==0) ? symbol+1 : symbol, sym.offset, sym.size);
value = 2;
- if ( sym.size != 0 )
- {
+ if ( sym.size != 0 ) {
--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;
@@ -847,7 +828,6 @@ extern char *ExpandKadds(char *line, char *el)
* present when resolving kernel exceptions.
* Return: void
**************************************************************************/
-
extern void SetParanoiaLevel(int level)
{
i_am_paranoid = level;
diff --git a/plugins/imklog/ksym_mod.c b/plugins/imklog/ksym_mod.c
index 3c7e0e4..11535a5 100644
--- a/plugins/imklog/ksym_mod.c
+++ b/plugins/imklog/ksym_mod.c
@@ -1,8 +1,10 @@
/*
- ksym_mod.c - functions for building symbol lookup tables for klogd
- Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
- Copyright (c) 1996 Enjellic Systems Development
-
+ * ksym_mod.c - functions for building symbol lookup tables for klogd
+ * Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
+ * Copyright (c) 1996 Enjellic Systems Development
+ * Copyright (c) 1998-2007 Martin Schulze <joey@infodrom.org>
+ * Copyright (C) 2007-2008 Rainer Gerhards <rgerhards@adiscon.com>
+ *
* This file is part of rsyslog.
*
* Rsyslog is free software: you can redistribute it and/or modify
@@ -86,6 +88,7 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
+#include <ctype.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
@@ -97,8 +100,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 +109,7 @@ extern int get_kernel_syms __P ((struct kernel_sym *__table));
#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 +119,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 +144,70 @@ static int symsort(const void *, const void *);
**************************************************************************/
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);
+ 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);
+ }
- 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);
- }
-
-
- /*
- * 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);
+ 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);
+ }
+
+ if(ksyms != NULL)
+ 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.");
+
+ return(1);
}
@@ -295,134 +240,92 @@ extern void DeinitMsyms(void)
*
* Return: void
**************************************************************************/
-static void FreeModules(void)
+static void FreeModules()
{
- auto int nmods,
- nsyms;
-
- 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;
+ auto int nmods,
+ nsyms;
+ auto struct Module *mp;
+
+ /* 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.
+ * Function: AddModule
*
- * Arguements: (unsigned long) address, (char *) symbol
+ * Purpose: This function is responsible for adding a module to
+ * the list of currently loaded modules.
*
- * address:-> The address of the module.
+ * Arguments: (const char *) module
*
- * symbol:-> The name of the module.
+ * module:-> The name of the module.
*
- * Return: int
+ * Return: struct Module *
**************************************************************************/
-static int AddModule(unsigned long address, char *symbol)
-{
- auto int memfd;
- auto struct Module *mp;
-
-
- /* 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);
- }
- return(1);
+struct Module *AddModule(module)
+ const char *module;
+{
+ 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 +335,78 @@ static int AddModule(unsigned long address, char *symbol)
* 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, ']');
+ if ( p != NULL )
+ *p = '\0';
+ p = module++;
+ while ( isspace(*(--p)) )
+ /*SKIP*/;
+ *(++p) = '\0';
+ }
- return(1);
+ 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 +426,58 @@ static int AddSymbol(struct Module *mp, unsigned long address, char *symbol)
* 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.
- */
- 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.
+ * see if the address can be resolved.
*/
-#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);
- }
- }
-
- /* It has been a hopeless exercise. */
- return(NULL);
+ 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((char *) 0);
}
diff --git a/plugins/imklog/ksyms.h b/plugins/imklog/ksyms.h
index 316950a..b5362ff 100644
--- a/plugins/imklog/ksyms.h
+++ b/plugins/imklog/ksyms.h
@@ -1,10 +1,9 @@
-/*
- ksym.h - Definitions for symbol table utilities.
- Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
- Copyright (c) 1996 Enjellic Systems Development
-
- This file is part of the sysklogd package, a kernel and system log daemon.
-
+/* ksym.h - Definitions for symbol table utilities.
+ * Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
+ * Copyright (c) 1996 Enjellic Systems Development
+ * Copyright (c) 2004-7 Martin Schulze <joey@infodrom.org>
+ * Copyright (c) 2007-2008 Rainer Gerhards <rgerhards@adiscon.com>
+ *
* This file is part of rsyslog.
*
* Rsyslog is free software: you can redistribute it and/or modify
@@ -21,7 +20,7 @@
* along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
*
* A copy of the GPL can be found in the file "COPYING" in this distribution.
-*/
+ */
/* Variables, structures and type definitions static to this module. */
diff --git a/plugins/imklog/module.h b/plugins/imklog/module.h
index 71eac2c..38a26fe 100644
--- a/plugins/imklog/module.h
+++ b/plugins/imklog/module.h
@@ -1,6 +1,7 @@
-/* Module definitions for klogd's module support
- *
- * Copyright 2007 by Rainer Gerhards and others
+/* module.h - Miscellaneous module definitions
+ * Copyright (c) 1996 Richard Henderson <rth@tamu.edu>
+ * Copyright (c) 2004-7 Martin Schulze <joey@infodrom.org>
+ * Copyright (c) 2007-2008 Rainer Gerhards <rgerhards@adiscon.com>
*
* This file is part of rsyslog.
*
@@ -19,63 +20,16 @@
*
* 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;
-};
-
-
-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
+ char *name;
};
-