⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ksym_mod.c

📁 linux下记录系统日志代码以及记录内核日志代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    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    This file is part of the sysklogd package, a kernel and system log daemon.    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., 675 Mass Ave, Cambridge, MA 02139, USA.*//* * This file implements functions which are useful for building * a symbol lookup table based on the in kernel symbol table * maintained by the Linux kernel. * * Proper logging of kernel panics generated by loadable modules * tends to be difficult.  Since the modules are loaded dynamically * their addresses are not known at kernel load time.  A general * protection fault (Oops) cannot be properly deciphered with  * classic methods using the static symbol map produced at link time. * * One solution to this problem is to have klogd attempt to translate * addresses from module when the fault occurs.  By referencing the * the kernel symbol table proper resolution of these symbols is made * possible. * * At least that is the plan. * * Wed Aug 21 09:20:09 CDT 1996:  Dr. Wettstein *	The situation where no module support has been compiled into a *	kernel is now detected.  An informative message is output indicating *	that the kernel has no loadable module support whenever kernel *	module symbols are loaded. * *	An informative message is printed indicating the number of kernel *	modules and the number of symbols loaded from these modules. * * Sun Jun 15 16:23:29 MET DST 1997: Michael Alan Dorman *	Some more glibc patches made by <mdorman@debian.org>. * * Sat Jan 10 15:00:18 CET 1998: Martin Schulze <joey@infodrom.north.de> *	Fixed problem with klogd not being able to be built on a kernel *	newer than 2.1.18.  It was caused by modified structures *	inside the kernel that were included.  I have worked in a *	patch from Alessandro Suardi <asuardi@uninetcom.it>. * * Sun Jan 25 20:57:34 CET 1998: Martin Schulze <joey@infodrom.north.de> *	Another patch for Linux/alpha by Christopher C Chimelis *	<chris@classnet.med.miami.edu>. * * Thu Mar 19 23:39:29 CET 1998: Manuel Rodrigues <pmanuel@cindy.fe.up.pt> *	Changed lseek() to llseek() in order to support > 2GB address *	space which provided by kernels > 2.1.70. * * Mon Apr 13 18:18:45 CEST 1998: Martin Schulze <joey@infodrom.north.de> *	Removed <sys/module.h> as it's no longer part of recent glibc *	versions.  Added prototyp for llseek() which has been *	forgotton in <unistd.h> from glibc.  Added more log *	information if problems occurred while reading a system map *	file, by submission from Mark Simon Phillips <M.S.Phillips@nortel.co.uk>. * * Sun Jan  3 18:38:03 CET 1999: Martin Schulze <joey@infodrom.north.de> *	Corrected return value of AddModule if /dev/kmem can't be *	loaded.  This will prevent klogd from segfaulting if /dev/kmem *	is not available.  Patch from Topi Miettinen <tom@medialab.sonera.net>. * * Tue Sep 12 23:11:13 CEST 2000: Martin Schulze <joey@infodrom.ffis.de> *	Changed llseek() to lseek64() in order to skip a libc warning. *//* Includes. */#include <stdlib.h>#include <malloc.h>#include <unistd.h>#include <signal.h>#include <errno.h>#include <sys/fcntl.h>#include <sys/stat.h>#if !defined(__GLIBC__)#include <linux/time.h>#include <linux/module.h>#else /* __GLIBC__ */#include <linux/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>#include <linux/version.h>#include "klogd.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};static int num_modules = 0;struct Module *sym_array_modules = (struct Module *) 0;static int have_modules = 0;#if defined(TEST)static int debugging = 1;#elseextern int debugging;#endif/* Function prototypes. */static void FreeModules(void);static int AddSymbol(struct Module *mp, unsigned long, char *);static int AddModule(unsigned long, char *);static int symsort(const void *, const void *);/************************************************************************** * Function:	InitMsyms * * Purpose:	This function is responsible for building a symbol *		table which can be used to resolve addresses for *		loadable modules. * * Arguements:	Void * * Return:	A boolean return value is assumed. * *		A false value indicates that something went wrong. * *		True if loading is successful. **************************************************************************/extern int InitMsyms(){	auto int	rtn,			tmp;	auto struct kernel_sym	*ksym_table,				*p;	/* Initialize the kernel module symbol table. */	FreeModules();	/*	 * 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);	}	if ( debugging )		fprintf(stderr, "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);	}	/*	 * 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);}static int symsort(p1, p2)     const void *p1;     const void *p2;{	auto const struct sym_table	*sym1 = p1,					*sym2 = p2;	if ( sym1->value < sym2->value )		return(-1);	if ( sym1->value == sym2->value )		return(0);	return(1);}/************************************************************************** * Function:	FreeModules * * Purpose:	This function is used to free all memory which has been *		allocated for the modules and their symbols. * * Arguements:	None specified. * * Return:	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;}/************************************************************************** * 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.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -