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

📄 ksym.c

📁 linux下记录系统日志代码以及记录内核日志代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	/*	 * 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 )	{		Syslog(LOG_ERR, "Cannot get kernel version information.");		return(0);	}	if ( debugging )		fprintf(stderr, "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);		return(0);	}	/* Compute the version code from data sent by the kernel */	kvnum = (major << 16) | (minor << 8) | patch;	/* Failure. */	if ( vnum != kvnum )		return(-1);	/* Success. */#endif	return(1);}/************************************************************************** * Function:	CheckMapVersion * * Purpose:	This function is responsible for determining whether or *		the system map being loaded matches the version of the *		currently running kernel.  It uses CheckVersion as *		backend. * * Arguements:	(char *) fname * *			fname:->	A pointer to the string which *					references the system map file to *					be used. * * Return:	int * *		       -1:->	The currently running kernel version does *				not match the version in the given file. * *			0:->	No system map file or no version information. * *			1:->	The executing kernel is of the same version *				as the version of the map file. **************************************************************************/static int CheckMapVersion(fname)	char *fname;	{	int	version;	FILE	*sym_file;	auto unsigned long int address;	auto char	type,			sym[512];	if ( (sym_file = fopen(fname, "r")) != (FILE *) 0 ) {		/*		 * At this point a map file was successfully opened.  We		 * now need to search this file and look for version		 * information.		 */		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 )			{				Syslog(LOG_ERR, "Error in symbol table input (#2).");				fclose(sym_file);				return(0);			}			if ( VERBOSE_DEBUGGING && debugging )				fprintf(stderr, "Address: %lx, Type: %c, " \				    "Symbol: %s\n", address, type, sym);			version = CheckVersion(sym);		}		fclose(sym_file);		switch ( version )		{		    case -1:			Syslog(LOG_ERR, "Symbol table has incorrect " \				"version number.\n");			break;					    case 0:			if ( debugging )				fprintf(stderr, "No version information " \					"found.\n");			break;		    case 1:			if ( debugging )				fprintf(stderr, "Found table with " \					"matching version number.\n");			break;		}		return(version);	}	return(0);}	/************************************************************************** * Function:	AddSymbol * * Purpose:	This function is responsible for adding a symbol name *		and its address to the symbol table. * * Arguements:	(unsigned long) address, (char *) symbol * * Return:	int * *		A boolean value is assumed.  True if the addition is *		successful.  False if not. **************************************************************************/static int AddSymbol(address, symbol)	unsigned long address;		char *symbol;	{	/* Allocate the the symbol table entry. */	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);	if ( sym_array[num_syms].name == (char *) 0 )		return(0);		sym_array[num_syms].value = address;	strcpy(sym_array[num_syms].name, symbol);	++num_syms;	return(1);}/************************************************************************** * Function:	LookupSymbol * * Purpose:	Find the symbol which is related to the given kernel *		address. * * Arguements:	(long int) value, (struct symbol *) sym * *		value:->	The address to be located. *  *		sym:->		A pointer to a structure which will be *				loaded with the symbol's parameters. * * Return:	(char *) * *		If a match cannot be found a diagnostic string is printed. *		If a match is found the pointer to the symbolic name most *		closely matching the address is returned. **************************************************************************/char * LookupSymbol(value, sym)	unsigned long value;	struct symbol *sym;	{	auto int lp;		auto char *last;	if (!sym_array)		return((char *) 0);	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 ( (last = LookupModuleSymbol(value, sym)) != (char *) 0 )		return(last);	return((char *) 0);}/************************************************************************** * Function:	FreeSymbols * * Purpose:	This function is responsible for freeing all memory which *		has been allocated to hold the static symbol table.  It *		also initializes the symbol count and in general prepares *		for a re-read of a static symbol table. * * Arguements:  void * * Return:	void **************************************************************************/static void FreeSymbols(){	auto int lp;	/* Free each piece of memory allocated for symbol names. */	for(lp= 0; lp < num_syms; ++lp)		free(sym_array[lp].name);	/* Whack the entire array and initialize everything. */	free(sym_array);	sym_array = (struct sym_table *) 0;	num_syms = 0;	return;}/************************************************************************** * Function:	LogExpanded * * Purpose:	This function is responsible for logging a kernel message *		line after all potential numeric kernel addresses have *		been resolved symolically. * * Arguements:	(char *) line, (char *) el * *		line:->	A pointer to the buffer containing the kernel *			message to be expanded and logged. * *		el:->	A pointer to the buffer into which the expanded *			kernel line will be written. * * Return:	void **************************************************************************/extern char * ExpandKadds(line, el)	char *line;	char *el;	{	auto char	dlm,			*kp,			*sl = line,			*elp = el,			*symbol;	char num[15];	auto unsigned long int value;	auto struct symbol sym;	/*	 * This is as handy a place to put this as anyplace.	 *	 * Since the insertion of kernel modules can occur in a somewhat	 * dynamic fashion we need some mechanism to insure that the	 * kernel symbol tables get read just prior to when they are	 * needed.	 *	 * To accomplish this we look for the Oops string and use its	 * presence as a signal to load the module symbols.	 *	 * This is not the best solution of course, especially if the	 * kernel is rapidly going out to lunch.  What really needs to	 * be done is to somehow generate a callback from the	 * kernel whenever a module is loaded or unloaded.  I am	 * open for patches.	 */	if ( i_am_paranoid &&	     (strstr(line, "Oops:") != (char *) 0) && !InitMsyms() )		Syslog(LOG_WARNING, "Cannot load kernel module symbols.\n");		/*	 * Early return if there do not appear to be any kernel	 * messages in this line.	 */	if ( (num_syms == 0) ||	     (kp = strstr(line, "[<")) == (char *) 0 )	{		strcpy(el, line);		return(el);	}	/* Loop through and expand all kernel messages. */	do	{		while ( sl < kp+1 )			*elp++ = *sl++;		/* Now poised at a kernel delimiter. */	        if ( (kp = strstr(sl, ">]")) == (char *) 0 )		{			strcpy(el, sl);			return(el);		}		dlm = *kp;		strncpy(num,sl+1,kp-sl-1);		num[kp-sl-1] = '\0';		value = strtoul(num, (char **) 0, 16);		if ( (symbol = LookupSymbol(value, &sym)) == (char *) 0 )			symbol = sl;					strcat(elp, symbol);		elp += strlen(symbol);		if ( debugging )			fprintf(stderr, "Symbol: %s = %lx = %s, %x/%d\n", \				sl+1, value, \				(sym.size==0) ? symbol+1 : symbol, \				sym.offset, sym.size);		value = 2;		if ( sym.size != 0 )		{			--value;			++kp;			elp += sprintf(elp, "+%x/%d", sym.offset, sym.size);		}		strncat(elp, kp, value);		elp += value;		sl = kp + value;		if ( (kp = strstr(sl, "[<")) == (char *) 0 )			strcat(elp, sl);	}	while ( kp != (char *) 0);			if ( debugging )		fprintf(stderr, "Expanded line: %s\n", el);	return(el);}/************************************************************************** * Function:	SetParanoiaLevel * * Purpose:	This function is an interface function for setting the *		mode of loadable module symbol lookups.  Probably overkill *		but it does slay another global variable. * * Arguements:	(int) level * *		level:->	The amount of paranoia which is to be *				present when resolving kernel exceptions. * Return:	void **************************************************************************/extern void SetParanoiaLevel(level)	int level;{	i_am_paranoid = level;	return;}/* * Setting the -DTEST define enables the following code fragment to * be compiled.  This produces a small standalone program which will * echo the standard input of the process to stdout while translating * all numeric kernel addresses into their symbolic equivalent. */#if defined(TEST)#include <stdarg.h>extern int main(int, char **);extern int main(int argc, char *argv[]){	auto char line[1024], eline[2048];	debugging = 1;			if ( !InitKsyms((char *) 0) )	{		fputs("ksym: Error loading system map.\n", stderr);		return(1);	}	while ( !feof(stdin) )	{		fgets(line, sizeof(line), stdin);		if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0'; /* Trash NL char */		memset(eline, '\0', sizeof(eline));		ExpandKadds(line, eline);		fprintf(stdout, "%s\n", eline);	}		return(0);}extern void Syslog(int priority, char *fmt, ...){	va_list ap;	va_start(ap, fmt);	fprintf(stdout, "Pr: %d, ", priority);	vfprintf(stdout, fmt, ap);	va_end(ap);	fputc('\n', stdout);	return;}#endif

⌨️ 快捷键说明

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