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; |