Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 109671 | Differences between
and this patch

Collapse All | Expand All

(-)sysklogd-1.4.1-orig/ksym_mod.c (-121 / +148 lines)
Lines 128-133 Link Here
128
#define getsyms get_kernel_syms
128
#define getsyms get_kernel_syms
129
#endif /* __GLIBC__ */
129
#endif /* __GLIBC__ */
130
130
131
extern int query_module(const char *, int, void *, size_t, size_t *);
132
131
/* Variables static to this module. */
133
/* Variables static to this module. */
132
struct sym_table
134
struct sym_table
133
{
135
{
Lines 148-154 Link Here
148
};
150
};
149
151
150
static int num_modules = 0;
152
static int num_modules = 0;
151
struct Module *sym_array_modules = (struct Module *) 0;
153
struct Module *sym_array_modules = NULL;
152
154
153
static int have_modules = 0;
155
static int have_modules = 0;
154
156
Lines 161-168 Link Here
161
163
162
/* Function prototypes. */
164
/* Function prototypes. */
163
static void FreeModules(void);
165
static void FreeModules(void);
164
static int AddSymbol(struct Module *mp, unsigned long, char *);
166
static int AddSymbol(struct Module *mp, unsigned long, const char *);
165
static int AddModule(unsigned long, char *);
167
static int AddModule(char *);
166
static int symsort(const void *, const void *);
168
static int symsort(const void *, const void *);
167
169
168
170
Lines 185-265 Link Here
185
extern int InitMsyms()
187
extern int InitMsyms()
186
188
187
{
189
{
188
	auto int	rtn,
190
	auto size_t	rtn;
189
			tmp;
191
	auto int	tmp;
192
193
	auto char	**mod_table;
194
195
	char			*modbuf = NULL,
196
				*newbuf;
190
197
191
	auto struct kernel_sym	*ksym_table,
198
	int			 modsize = 32,
192
				*p;
199
				 result;
193
200
194
201
195
	/* Initialize the kernel module symbol table. */
202
	/* Initialize the kernel module symbol table. */
196
	FreeModules();
203
	FreeModules();
197
204
205
	/*
206
	 * New style symbol table parser.  This uses the newer query_module
207
	 * function rather than the old obsolete hack of stepping thru
208
	 * /dev/kmem.
209
	 */
198
210
199
	/*
211
	/*
200
	 * The system call which returns the kernel symbol table has
212
	 * First, we query for the list of loaded modules.  We may
201
	 * essentialy two modes of operation.  Called with a null pointer
213
	 * have to grow our buffer in size.
202
	 * the system call returns the number of symbols defined in the
203
	 * the table.
204
	 *
205
	 * The second mode of operation is to pass a valid pointer to
206
	 * the call which will then load the current symbol table into
207
	 * the memory provided.
208
	 *
209
	 * Returning the symbol table is essentially an all or nothing
210
	 * proposition so we need to pre-allocate enough memory for the
211
	 * complete table regardless of how many symbols we need.
212
	 *
213
	 * Bummer.
214
	 */
214
	 */
215
	if ( (rtn = getsyms((struct kernel_sym *) 0)) < 0 )
215
	do {
216
	{
216
		modsize+=modsize;
217
		if ( errno == ENOSYS )
217
		newbuf=realloc(modbuf, modsize);
218
			Syslog(LOG_INFO, "No module symbols loaded - "
218
219
			       "kernel modules not enabled.\n");
219
		if (newbuf==NULL) {
220
		else
220
			/* Well, that sucks. */
221
			Syslog(LOG_ERR, "Error loading kernel symbols " \
221
			Syslog(LOG_ERR, "Error loading kernel symbols " \
222
			       "- %s\n", strerror(errno));
222
			       "- %s\n", strerror(errno));
223
			if (modbuf!=NULL) free(modbuf);
224
			return(0);
225
		}
226
227
		modbuf=newbuf;
228
229
		result=query_module(NULL, QM_MODULES, modbuf, modsize, &rtn);
230
231
		if (result<0 && errno!=ENOSPC) {
232
			Syslog(LOG_ERR, "Error querying loaded modules " \
233
			       "- %s\n", strerror(errno));
234
			free(modbuf);
235
			return(0);
236
		}
237
	} while (result<0);
238
239
	if ( rtn <= 0 ) {
240
		/* No modules??? */
241
		Syslog(LOG_INFO, "No module symbols loaded - "
242
		       "modules disabled?\n");
243
		free(modbuf);
223
		return(0);
244
		return(0);
224
	}
245
	}
225
	if ( debugging )
246
	if ( debugging )
226
		fprintf(stderr, "Loading kernel module symbols - "
247
		fprintf(stderr, "Loading kernel module symbols - "
227
			"Size of table: %d\n", rtn);
248
			"Size of table: %d\n", rtn);
228
249
229
	ksym_table = (struct kernel_sym *) malloc(rtn * \
250
	mod_table = (char **) malloc(rtn * sizeof(char *));
230
						  sizeof(struct kernel_sym));
251
	if ( mod_table == NULL )
231
	if ( ksym_table == (struct kernel_sym *) 0 )
232
	{
252
	{
233
		Syslog(LOG_WARNING, " Failed memory allocation for kernel " \
253
		Syslog(LOG_WARNING, " Failed memory allocation for kernel " \
234
		       "symbol table.\n");
254
		       "symbol table.\n");
255
		free(modbuf);
235
		return(0);
256
		return(0);
236
	}
257
	}
237
	if ( (rtn = getsyms(ksym_table)) < 0 )
258
259
	sym_array_modules = (struct Module *) malloc(rtn * sizeof(struct Module));
260
	if ( sym_array_modules == NULL )
238
	{
261
	{
239
		Syslog(LOG_WARNING, "Error reading kernel symbols - %s\n", \
262
		Syslog(LOG_WARNING, " Failed memory allocation for kernel " \
240
		       strerror(errno));
263
		       "symbol table.\n");
264
		free(mod_table);
265
		free(modbuf);
241
		return(0);
266
		return(0);
242
	}
267
	}
243
268
244
245
	/*
269
	/*
246
	 * Build a symbol table compatible with the other one used by
270
	 * Build a symbol table compatible with the other one used by
247
	 * klogd.
271
	 * klogd.
248
	 */
272
	 */
249
	tmp = rtn;
273
	newbuf=modbuf;
250
	p = ksym_table;
274
	for (tmp=rtn-1; tmp>=0; tmp--)
251
	while ( tmp-- )
252
	{
275
	{
253
 		if ( !AddModule(p->value, p->name) )
276
		mod_table[tmp]=newbuf;
277
		newbuf+=(strlen(newbuf)+1);
278
 		if ( !AddModule(mod_table[tmp]) )
254
		{
279
		{
255
			Syslog(LOG_WARNING, "Error adding kernel module table "
280
			Syslog(LOG_WARNING, "Error adding kernel module table "
256
				"entry.\n");
281
				"entry.\n");
257
			free(ksym_table);
282
			free(mod_table);
283
			free(modbuf);
258
			return(0);
284
			return(0);
259
		}
285
		}
260
		++p;
261
	}
286
	}
262
287
288
	have_modules = 1;
289
263
	/* Sort the symbol tables in each module. */
290
	/* Sort the symbol tables in each module. */
264
	for (rtn = tmp= 0; tmp < num_modules; ++tmp)
291
	for (rtn = tmp= 0; tmp < num_modules; ++tmp)
265
	{
292
	{
Lines 277-283 Link Here
277
		Syslog(LOG_INFO, "Loaded %d %s from %d module%s", rtn, \
304
		Syslog(LOG_INFO, "Loaded %d %s from %d module%s", rtn, \
278
		       (rtn == 1) ? "symbol" : "symbols", \
305
		       (rtn == 1) ? "symbol" : "symbols", \
279
		       num_modules, (num_modules == 1) ? "." : "s.");
306
		       num_modules, (num_modules == 1) ? "." : "s.");
280
	free(ksym_table);
307
	free(mod_table);
308
	free(modbuf);
281
	return(1);
309
	return(1);
282
}
310
}
283
311
Lines 322-344 Link Here
322
350
323
	/* Check to see if the module symbol tables need to be cleared. */
351
	/* Check to see if the module symbol tables need to be cleared. */
324
	have_modules = 0;
352
	have_modules = 0;
325
	if ( num_modules == 0 )
326
		return;
327
328
353
329
	for (nmods= 0; nmods < num_modules; ++nmods)
354
	if (sym_array_modules != NULL) {
330
	{
355
		for (nmods= 0; nmods < num_modules; ++nmods)
331
		mp = &sym_array_modules[nmods];
356
		{
332
		if ( mp->num_syms == 0 )
357
			mp = &sym_array_modules[nmods];
333
			continue;
358
			if ( mp->num_syms == 0 )
359
				continue;
334
	       
360
	       
335
		for (nsyms= 0; nsyms < mp->num_syms; ++nsyms)
361
			for (nsyms= 0; nsyms < mp->num_syms; ++nsyms)
336
			free(mp->sym_array[nsyms].name);
362
				free(mp->sym_array[nsyms].name);
337
		free(mp->sym_array);
363
			free(mp->sym_array);
364
		}
365
366
		free(sym_array_modules);
367
		sym_array_modules = NULL;
338
	}
368
	}
339
369
340
	free(sym_array_modules);
341
	sym_array_modules = (struct Module *) 0;
342
	num_modules = 0;
370
	num_modules = 0;
343
	return;
371
	return;
344
}
372
}
Lines 350-372 Link Here
350
 * Purpose:	This function is responsible for adding a module to
378
 * Purpose:	This function is responsible for adding a module to
351
 *		the list of currently loaded modules.
379
 *		the list of currently loaded modules.
352
 *
380
 *
353
 * Arguements:	(unsigned long) address, (char *) symbol
381
 * Arguements:	(char *) symbol
354
 *
355
 *		address:->	The address of the module.
356
 *
382
 *
357
 *		symbol:->	The name of the module.
383
 *		symbol:->	The name of the module.
358
 *
384
 *
359
 * Return:	int
385
 * Return:	int
360
 **************************************************************************/
386
 **************************************************************************/
361
387
362
static int AddModule(address, symbol)
388
static int AddModule(symbol)
363
364
     unsigned long address;
365
389
366
     char *symbol;
390
     char *symbol;
367
391
368
{
392
{
369
	auto int memfd;
393
	size_t rtn;
394
	size_t i;
395
	const char *cbuf;
396
	int symsize=128;
397
	int result;
398
	struct module_symbol *symbuf=NULL,
399
			     *newbuf;
370
400
371
	auto struct Module *mp;
401
	auto struct Module *mp;
372
402
Lines 374-451 Link Here
374
	/* Return if we have loaded the modules. */
404
	/* Return if we have loaded the modules. */
375
	if ( have_modules )
405
	if ( have_modules )
376
		return(1);
406
		return(1);
407
	
408
	/* We already have space for the module. */
409
	mp = &sym_array_modules[num_modules];
410
411
	if (query_module(symbol, QM_INFO, &sym_array_modules[num_modules].module,
412
			 sizeof(struct module), &rtn)<0)
413
	{
414
		Syslog(LOG_WARNING, "Error reading module info for %s.\n",
415
		       symbol);
416
		return(0);
417
	}
418
419
	/* Save the module name. */
420
	mp->name = strdup(symbol);
421
	if ( mp->name == NULL )
422
		return(0);
423
424
	mp->num_syms = 0;
425
	mp->sym_array = NULL;
426
	++num_modules;
377
427
378
	/*
428
	/*
379
	 * The following section of code is responsible for determining
429
	 * First, we query for the list of exported symbols.  We may
380
	 * whether or not we are done reading the list of modules.
430
	 * have to grow our buffer in size.
381
	 */
431
	 */
382
	if ( symbol[0] == '#' )
432
	do {
383
	{
433
		symsize+=symsize;
434
		newbuf=realloc(symbuf, symsize);
384
435
385
		if ( symbol[1] == '\0' )
436
		if (newbuf==NULL) {
386
		{
437
			/* Well, that sucks. */
387
			/*
438
			Syslog(LOG_ERR, "Error loading kernel symbols " \
388
			 * A symbol which consists of a # sign only
439
			       "- %s\n", strerror(errno));
389
			 * signifies a a resident kernel segment.  When we
440
			if (symbuf!=NULL) free(symbuf);
390
			 * hit one of these we are done reading the
391
			 * module list.
392
			 */
393
			have_modules = 1;
394
			return(1);
395
		}
396
		/* Allocate space for the module. */
397
		sym_array_modules = (struct Module *) \
398
			realloc(sym_array_modules, \
399
				(num_modules+1) * sizeof(struct Module));
400
		if ( sym_array_modules == (struct Module *) 0 )
401
		{
402
			Syslog(LOG_WARNING, "Cannot allocate Module array.\n");
403
			return(0);
441
			return(0);
404
		}
442
		}
405
		mp = &sym_array_modules[num_modules];
406
443
407
		if ( (memfd = open("/dev/kmem", O_RDONLY)) < 0 )
444
		symbuf=newbuf;
408
		{
445
409
			Syslog(LOG_WARNING, "Error opening /dev/kmem\n");
446
		result=query_module(symbol, QM_SYMBOLS, symbuf, symsize, &rtn);
410
			return(0);
411
		}
412
		if ( lseek64(memfd, address, SEEK_SET) < 0 )
413
		{
414
			Syslog(LOG_WARNING, "Error seeking in /dev/kmem\n");
415
			Syslog(LOG_WARNING, "Symbol %s, value %08x\n", symbol, address);
416
			return(0);
417
		}
418
		if ( read(memfd, \
419
			  (char *)&sym_array_modules[num_modules].module,  \
420
			  sizeof(struct module)) < 0 )
421
		{
422
			Syslog(LOG_WARNING, "Error reading module "
423
			       "descriptor.\n");
424
			return(0);
425
		}
426
		close(memfd);
427
447
428
		/* Save the module name. */
448
		if (result<0 && errno!=ENOSPC) {
429
		mp->name = (char *) malloc(strlen(&symbol[1]) + 1);
449
			Syslog(LOG_ERR, "Error querying symbol list for %s " \
430
		if ( mp->name == (char *) 0 )
450
			       "- %s\n", symbol, strerror(errno));
451
			free(symbuf);
431
			return(0);
452
			return(0);
432
		strcpy(mp->name, &symbol[1]);
453
		}
454
	} while (result<0);
433
455
434
		mp->num_syms = 0;
456
	if ( rtn < 0 ) {
435
		mp->sym_array = (struct sym_table *) 0;
457
		/* No symbols??? */
436
		++num_modules;
458
		Syslog(LOG_INFO, "No module symbols loaded - unknown error.\n");
437
		return(1);
459
		free(symbuf);
438
	}
460
		return(0);
439
	else
440
	{
441
	    if (num_modules > 0)
442
		mp = &sym_array_modules[num_modules - 1];
443
	    else
444
		mp = &sym_array_modules[0];
445
		AddSymbol(mp, address, symbol);
446
	}
461
	}
447
462
463
	cbuf=(char *)symbuf;
464
465
	for (i=0; i<rtn; i++) {
466
		if (num_modules > 0)
467
			mp = &sym_array_modules[num_modules - 1];
468
		else
469
			mp = &sym_array_modules[0];
470
471
		AddSymbol(mp, symbuf[i].value,
472
			  cbuf+(unsigned long)(symbuf[i].name));
473
	}
448
474
475
	free(symbuf);
449
	return(1);
476
	return(1);
450
}
477
}
451
478
Lines 477-483 Link Here
477
504
478
	unsigned long address;
505
	unsigned long address;
479
	
506
	
480
	char *symbol;
507
	const char *symbol;
481
	
508
	
482
{
509
{
483
	auto int tmp;
510
	auto int tmp;
(-)sysklogd-1.4.1-orig/module.h (+13 lines)
Lines 38-48 Link Here
38
	char name[MODULE_NAME_LEN];
38
	char name[MODULE_NAME_LEN];
39
};
39
};
40
40
41
struct module_symbol
42
{
43
	unsigned long value;
44
	const char *name;
45
};
41
46
42
struct list_head {
47
struct list_head {
43
	struct list_head *next, *prev;
48
	struct list_head *next, *prev;
44
};
49
};
45
50
51
/* Values for query_module's which.  */
52
53
#define QM_MODULES		1
54
#define QM_DEPS			2
55
#define QM_REFS			3
56
#define QM_SYMBOLS		4
57
#define QM_INFO			5
58
46
59
47
struct module_info
60
struct module_info
48
{
61
{

Return to bug 109671