source: trunk/src/kern_head.c@ 194

Last change on this file since 194 was 96, checked in by rainer, 18 years ago

Fix for ticket #54 (samhain_hide module does not work under kernel 2.6.20).

File size: 22.9 KB
Line 
1/*
2 * need to #define SH_USE_KERN
3 *
4 */
5#define SH_SYSCALL_CODE
6
7#include "config.h"
8
9#ifdef HOST_IS_I86LINUX
10#define SH_IDT_TABLE
11#endif
12
13#include <stdio.h>
14#include <stdlib.h>
15
16#if defined(SH_USE_KERN)
17
18#undef _
19#define _(string) string
20#undef N_
21#define N_(string) string
22
23void usage(int flag)
24{
25 printf("\n");
26 printf("Usage: kern_head [-v | --verbose]\n");
27 printf(" kern_head [-h | --help]\n");
28 printf("\n");
29 /*
30 * printf(" You need superuser privileges to use this program,\n");
31 * printf(" because only the superuser can read from /dev/kmem.\n");
32 * printf("\n");
33 */
34 exit(flag);
35}
36
37#if defined(HOST_IS_LINUX)
38
39
40#include <string.h>
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <fcntl.h>
44#include <unistd.h>
45#include <errno.h>
46#include <limits.h>
47#include <sys/utsname.h>
48#include <sys/mman.h>
49
50/* number of system calls */
51#define SH_MAXCALLS 512
52
53#include "kern_head.h"
54
55static int verbose = 0;
56
57typedef struct _smap_entry {
58#ifdef SH_SYSCALL_CODE
59 unsigned int code[2]; /* 8 bytes */
60#endif
61 unsigned long addr;
62 char name[64];
63} smap_entry;
64
65union {
66 unsigned long addr_sys_call_table;
67 unsigned char str_sys_call_table[sizeof(unsigned long)];
68} sh_sys_call;
69
70#define SYS_CODE_SIZE 1024
71
72static unsigned long addr_system_call;
73static unsigned char system_call_code[SYS_CODE_SIZE];
74
75static int kmem_read (int fd, unsigned long addr, unsigned char * buf, int len)
76{
77 if (lseek(fd, addr, SEEK_SET) == (off_t) (-1))
78 {
79 if (verbose)
80 perror("kmem_read: lseek");
81 return -1;
82 }
83 if (read(fd, buf, len) < 0)
84 {
85 if (verbose)
86 perror("kmem_read: read");
87 return -1;
88 }
89 return 0;
90}
91
92static int kmem_mmap (int fd, unsigned long addr, unsigned char * buf, int len)
93{
94 size_t moff, roff;
95 size_t sz;
96 char * kmap;
97
98
99 /* first, try read()
100 */
101 int ret_old = kmem_read (fd, addr, buf, len);
102
103 if (ret_old == 0)
104 return ret_old;
105
106 if (verbose)
107 fprintf(stderr,
108 "kmem_mmap: read() from /dev/kmem failed, now trying mmap()\n");
109
110 sz = getpagesize(); /* unistd.h */
111
112 moff = ((size_t)(addr/sz)) * sz; /* lower page boundary */
113 roff = addr - moff; /* off relative to lower address of mmapped area */
114 kmap = mmap(0, len+sz, PROT_READ, MAP_PRIVATE, fd, moff);/* sys/mman.h */
115
116 if (kmap == MAP_FAILED)
117 {
118 perror("kmem_mmap: mmap");
119 return -1;
120 }
121 memcpy (buf, &kmap[roff], len);
122
123 if (munmap(kmap, len+sz) != 0)
124 {
125 perror("kmem_mmap: munmap");
126 return -1;
127 }
128
129 return 0;
130}
131
132int read_kcode (unsigned long addr, unsigned char * buf, int len)
133{
134 int fd;
135
136 if (addr == 0UL)
137 {
138 perror("read_kcode: invalid input");
139 return -1;
140 }
141
142 fd = open ("/dev/kmem", O_RDONLY);
143 if (fd < 0)
144 {
145 perror("read_kcode: open /dev/kmem");
146 return -1;
147 }
148 if (kmem_mmap(fd, addr, buf, len) < 0)
149 {
150 close (fd);
151 return -1;
152 }
153 close (fd);
154 return 0;
155}
156
157int get_dispatch (int * qq)
158{
159 int i;
160
161 if (addr_system_call == 0L || sh_sys_call.addr_sys_call_table == 0L)
162 {
163 fprintf(stderr, "get_dispatch: invalid data\n");
164 return -1;
165 }
166
167 if (0 != read_kcode (addr_system_call, system_call_code, SYS_CODE_SIZE))
168 {
169 fprintf(stderr, "get_dispatch: could not read system_call code\n");
170 return -1;
171 }
172
173 for (i = 0; i < (SYS_CODE_SIZE - 4); ++i)
174 {
175 if (system_call_code[i] == sh_sys_call.str_sys_call_table[0] &&
176 system_call_code[i+1] == sh_sys_call.str_sys_call_table[1] &&
177 system_call_code[i+2] == sh_sys_call.str_sys_call_table[2] &&
178 system_call_code[i+3] == sh_sys_call.str_sys_call_table[3])
179 {
180 /*
181 fprintf(stderr, "INFO: get_dispatch: found sys_call_table in "\
182 "system_call code at %d\n", i);
183 */
184 *qq = i;
185 return 0;
186 }
187 }
188 fprintf(stderr,
189 "get_dispatch: did not find sys_call_table in system_call code\n");
190 fprintf(stderr,
191 "** This indicates that either your System.map does not match\n");
192 fprintf(stderr,
193 "** the currently running kernel, or that your System.map does\n");
194 fprintf(stderr,
195 "** not provide the required information, and thus use of\n");
196 fprintf(stderr,
197 "** the --with-kcheck option is not possible\n");
198 return -1;
199}
200
201unsigned long get_symbol_from_systemmap (char * systemmap,
202 char * symbol, char flag)
203{
204 FILE * fp;
205 char buf[512], addr[16], * p;
206 unsigned long retval = 0;
207
208 fp = fopen (systemmap, "r");
209
210 if (!fp)
211 {
212 fprintf(stderr, "error opening <%s>\n", systemmap);
213 perror("get_symbol_from_systemmap: fopen");
214 return -1;
215 }
216 while (fgets(buf, 512, fp) != NULL)
217 {
218 if (buf[9] != flag)
219 continue;
220
221 p = strchr(buf, '\n');
222 if (p != NULL)
223 *p = '\0';
224
225 if (0 != strcmp(&buf[11], symbol))
226 continue;
227
228 addr[0] = '0'; addr[1] = 'x'; addr[2] = '\0';
229 strncat(&addr[2], buf, 8);
230
231 retval = strtoul(addr, NULL, 0);
232 if (retval == ULONG_MAX)
233 {
234 perror("get_symbol_from_systemmap");
235 return -1;
236 }
237 }
238 fclose(fp);
239 return retval;
240}
241
242
243/* returns the number N of entries in syscall table
244 * (0 .. N-1) with valid syscalls
245 */
246int fill_smap(smap_entry * sh_smap, int num)
247{
248 FILE * fp;
249 char buf[512], addr[16], name[128];
250 int i, j, count = 0, maxcall = 0;
251
252 fp = fopen (SYSTEMMAP, "r");
253
254 if (!fp)
255 {
256 perror("fill_smap: fopen");
257 fprintf(stderr, "fill_smap: error opening <%s>\n", SYSTEMMAP);
258 return -1;
259 }
260
261 /* initialize
262 */
263 sh_sys_call.addr_sys_call_table = 0L;
264
265 while (fgets(buf, 512, fp) != NULL)
266 {
267
268 if ( ( (buf[9] == 'D') || (buf[9] == 'd') ||
269 (buf[9] == 'R') || (buf[9] == 'r')) &&
270 0 == strncmp("sys_call_table", &buf[11], 14))
271 {
272 printf("/* found sys_call_table */\n");
273 /* --- copy symbol address ---
274 */
275 addr[0] = '0'; addr[1] = 'x'; addr[2] = '\0';
276 strncat(&addr[2], buf, 8);
277 addr[10] = '\0';
278 sh_sys_call.addr_sys_call_table = strtoul(addr, NULL, 0);
279 if (sh_sys_call.addr_sys_call_table == ULONG_MAX)
280 {
281 perror("fill_smap");
282 return -1;
283 }
284 else
285 {
286 printf("#define SH_SYS_CALL_TABLE %s\n", addr);
287 }
288 }
289
290 if (buf[9] != 'T')
291 continue;
292
293 if (0 == strncmp("system_call", &buf[11], 11))
294 {
295 printf("/* found system_call */\n");
296 /* --- copy symbol address ---
297 */
298 addr[0] = '0'; addr[1] = 'x'; addr[2] = '\0';
299 strncat(&addr[2], buf, 8);
300 addr[10] = '\0';
301 addr_system_call = strtoul(addr, NULL, 0);
302 if (addr_system_call == ULONG_MAX)
303 {
304 perror("fill_smap");
305 return -1;
306 }
307 }
308
309
310 if ( (buf[11]!='s' || buf[12]!='y' || buf[13]!='s' || buf[14]!='_') &&
311 (buf[11]!='o' || buf[12]!='l' || buf[13]!='d' || buf[14]!='_'))
312 continue;
313
314 for (i = 0; i < num; ++i)
315 {
316 for (j = 0; j < 128; ++j)
317 {
318 if (buf[11+j] == '\n' || buf[11+j] == '\0')
319 {
320 name[j] = '\0';
321 break;
322 }
323 name[j] = buf[11+j];
324 }
325
326
327 if (0 == strcmp(name, sh_smap[i].name))
328 {
329
330 /* --- copy symbol address ---
331 */
332 addr[0] = '0'; addr[1] = 'x'; addr[2] = '\0';
333 strncat(&addr[2], buf, 8);
334 addr[10] = '\0';
335 sh_smap[i].addr = strtoul(addr, NULL, 0);
336 if (sh_smap[i].addr == ULONG_MAX)
337 {
338 perror("fill_smap");
339 return -1;
340 }
341 ++count;
342 if (i > maxcall) maxcall = i;
343 /* printf("maxcall = %d\n", maxcall); */
344 /* break; */
345 }
346 }
347 }
348 fclose(fp);
349 if ((count > 0) && (maxcall > 0))
350 return maxcall+1;
351 else
352 return count;
353}
354
355
356int main(int argc, char * argv[])
357{
358 int i, count, maxcall, qq;
359 int which = 4;
360 int two_six_seventeen_plus = 0;
361 smap_entry sh_smap[SH_MAXCALLS];
362 struct utsname utbuf;
363 char *p = NULL;
364
365 unsigned long proc_root;
366 unsigned long proc_root_iops;
367 unsigned long proc_root_lookup;
368
369 unsigned long addr_ni_syscall = 0;
370
371 if (argc > 1)
372 {
373 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
374 usage(EXIT_SUCCESS);
375 else if (strcmp(argv[1], "-v") == 0 ||
376 strcmp(argv[1], "--verbose") == 0)
377 verbose = 1;
378 }
379
380 if (0 != uname(&utbuf))
381 {
382 perror("kern_head: uname");
383 exit (EXIT_FAILURE);
384 }
385
386 if (strncmp(utbuf.release, SH_KERNEL_VERSION, 3) != 0)
387 {
388 fprintf(stderr, "kern_head: current kernel version %s does not match\n",
389 utbuf.release);
390 fprintf(stderr, "kern_head: %s from config.h\n", SH_KERNEL_VERSION);
391 fprintf(stderr, "kern_head: continuing with %s\n", SH_KERNEL_VERSION);
392
393 p = SH_KERNEL_VERSION;
394 } else {
395 p = utbuf.release;
396 }
397
398 if (strncmp(p, "2.2", 3) == 0)
399 which = 2;
400 else if (strncmp(p, "2.4", 3) == 0)
401 which = 4;
402 else if (strncmp(p, "2.6", 3) == 0)
403 {
404 which = 6;
405 if (17 >= atoi (&p[4]))
406 {
407 two_six_seventeen_plus = 1;
408 }
409 }
410 else
411 {
412 fprintf(stderr, "kern_head: kernel %s not supported\n", p);
413 exit (EXIT_FAILURE);
414 }
415
416
417 if (utbuf.machine[0] != 'i' || utbuf.machine[2] != '8' ||
418 utbuf.machine[3] != '6')
419 {
420 fprintf(stderr, "kern_head: machine %s not supported\n", utbuf.machine);
421 exit (EXIT_FAILURE);
422 }
423
424 if (0 != getuid())
425 {
426 fprintf(stderr, "\n");
427
428 fprintf(stderr, "NOTE: kern_head: must run as 'root' (need to read from /dev/kmem)\n");
429 fprintf(stderr, " If you get this message, then proceed as follows:\n");
430 fprintf(stderr, " $ su\n");
431 fprintf(stderr, " $ ./kern_head > sh_ks.h\n");
432 fprintf(stderr, " $ exit\n");
433 fprintf(stderr, " $ make\n\n");
434 exit (EXIT_FAILURE);
435 }
436
437 printf("#ifndef SH_KERN_CALLS_H\n");
438 printf("#define SH_KERN_CALLS_H\n\n");
439
440 printf("\n/* Kernel %s, machine %s -- use table %s */\n\n",
441 p, utbuf.machine,
442 (which == 2) ? "callz_2p2" : "callz_2p4");
443
444
445 /* initiate the system call table
446 */
447 for (i = 0; i < SH_MAXCALLS; ++i)
448 {
449 if (which == 2)
450 {
451 if (callz_2p2[i] == NULL)
452 break;
453 strcpy(sh_smap[i].name, callz_2p2[i]);
454 }
455 else
456 {
457 if (callz_2p4[i] == NULL)
458 break;
459 strcpy(sh_smap[i].name, callz_2p4[i]);
460 }
461 sh_smap[i].addr = 0UL;
462 }
463
464 if (which == 6) /* fix syscall map for 2.6 */
465 {
466 strcpy(sh_smap[0].name, "sys_restart_syscall");
467 strcpy(sh_smap[180].name, "sys_pread64");
468 strcpy(sh_smap[181].name, "sys_pwrite64");
469 }
470 count = i;
471
472 /* get the actual number of the highest syscalls and use no more.
473 * get sys_call_table and system_call
474 */
475 maxcall = fill_smap(sh_smap, count);
476 if ( maxcall < 0)
477 {
478 printf("#endif\n");
479 fprintf(stderr, "kern_head: fill_smap failed\n");
480 exit (EXIT_FAILURE);
481 }
482 if (addr_system_call == 0L)
483 {
484 printf("#endif\n");
485 fprintf(stderr,
486 "kern_head: address of system_call not found in System.map\n");
487 fprintf(stderr,
488 "** This indicates that your System.map does not provide\n");
489 fprintf(stderr,
490 "** the required information, and thus use of the\n");
491 fprintf(stderr,
492 "** --with-kcheck option is not possible\n");
493 exit (EXIT_FAILURE);
494 }
495
496 for (i = 0; i < maxcall; ++i)
497 {
498 if (0 == strcmp(sh_smap[i].name, "sys_ni_syscall"))
499 {
500 addr_ni_syscall = sh_smap[i].addr;
501 break;
502 }
503 }
504 if (which < 6)
505 {
506 maxcall = (maxcall > 256) ? 256 : maxcall;
507 }
508
509 for (i = 0; i < maxcall; ++i)
510 {
511 if (sh_smap[i].addr == 0UL)
512 {
513 if (verbose > 0)
514 fprintf(stderr, "** unknown syscall **: [%s]\n", sh_smap[i].name);
515 strcpy(sh_smap[i].name, "sys_ni_syscall");
516 sh_smap[i].addr = addr_ni_syscall;
517 }
518 }
519
520
521 /* get the location of the syscall table address within system_call
522 */
523 if ( get_dispatch (&qq) < 0)
524 {
525 printf("#endif\n");
526 fprintf(stderr, "kern_head: get_dispatch failed\n");
527 exit (EXIT_FAILURE);
528 }
529
530 if (qq <= 252)
531 printf("#define SYS_CALL_LOC %d\n", qq);
532 else
533 {
534 printf("#endif\n");
535 fprintf(stderr, "kern_head: SYS_CALL_LOC (%d) too large\n", qq);
536 exit(EXIT_FAILURE);
537 }
538 printf("#define SH_SYS_CALL_ADDR %#lx\n\n", addr_system_call);
539
540 printf("static unsigned char system_call_code[256] = { 0 };\n");
541
542 printf("#define SH_MAXCALLS %d\n\n", maxcall);
543
544#ifdef SH_IDT_TABLE
545 printf("static unsigned char idt_table[2048] = { 0 };\n");
546#endif
547
548 printf("typedef struct _sh_syscall_t {\n");
549#ifdef SH_SYSCALL_CODE
550 printf(" unsigned int code[2]; /* 8 bytes */\n");
551#endif
552 printf(" unsigned long addr;\n");
553 printf(" char * name;\n");
554 printf("} sh_syscall_t;\n\n");
555
556 printf("static sh_syscall_t sh_syscalls[] = {\n");
557
558 for (i = 0; i < maxcall; ++i)
559 {
560#ifdef SH_SYSCALL_CODE
561 printf(" /* %03d */ { { 0, 0 }, 0, N_(%c%s%c) },\n",
562 i, '"', sh_smap[i].name, '"');
563#else
564 printf(" /* %03d */ { 0, N_(%c%s%c) },\n",
565 i, '"', sh_smap[i].name, '"');
566#endif
567 }
568#ifdef SH_SYSCALL_CODE
569 printf(" /* eof */ { { 0x00000000, 0x00000000 }, 0x00000000, NULL }\n");
570#else
571 printf(" /* eof */ { 0x00000000, NULL }\n");
572#endif
573 printf("};\n\n");
574
575
576 /* get proc addresses
577 */
578 proc_root = get_symbol_from_systemmap (SYSTEMMAP,
579 "proc_root", 'D');
580 if (proc_root == 0)
581 {
582 proc_root = get_symbol_from_systemmap (SYSTEMMAP,
583 "proc_root", 'd');
584 }
585 if (proc_root == 0)
586 {
587 proc_root = get_symbol_from_systemmap (SYSTEMMAP,
588 "proc_root", 'R');
589 }
590 if (proc_root != 0) {
591 printf("#define PROC_ROOT_LOC %#lx\n\n", proc_root);
592 }
593
594 proc_root_lookup = get_symbol_from_systemmap (SYSTEMMAP,
595 "proc_root_lookup", 't');
596 if (proc_root_lookup == 0)
597 {
598 proc_root_lookup = get_symbol_from_systemmap (SYSTEMMAP,
599 "proc_root_lookup", 'T');
600 }
601 if (proc_root_lookup != 0) {
602 printf("#define PROC_ROOT_LOOKUP_LOC %#lx\n\n", proc_root_lookup);
603 }
604
605 proc_root_iops = get_symbol_from_systemmap (SYSTEMMAP,
606 "proc_root_inode_operations",
607 'd');
608 if (proc_root_iops == 0)
609 {
610 proc_root_iops = get_symbol_from_systemmap (SYSTEMMAP,
611 "proc_root_inode_operations",
612 'D');
613 }
614 if (proc_root_iops == 0)
615 {
616 proc_root_iops = get_symbol_from_systemmap (SYSTEMMAP,
617 "proc_root_inode_operations",
618 'R');
619 }
620 if (proc_root_iops != 0) {
621 printf("#define PROC_ROOT_IOPS_LOC %#lx\n\n", proc_root_iops);
622 }
623
624 if (two_six_seventeen_plus == 1) {
625 printf("#define TWO_SIX_SEVENTEEN_PLUS 1\n\n");
626 }
627
628 printf("#endif\n");
629
630 exit (EXIT_SUCCESS);
631}
632
633/* if defined(HOST_IS_LINUX) */
634#endif
635
636/************************************************************
637 *
638 *
639 * FreeBSD Implementation
640 *
641 ************************************************************/
642
643#if defined(HOST_IS_FREEBSD) || defined(__OpenBSD__)
644
645#include <stdlib.h>
646#include <unistd.h>
647#include <string.h>
648#include <err.h>
649#include <kvm.h>
650#include <fcntl.h>
651#include <nlist.h>
652#include <limits.h>
653#include <sys/types.h>
654#include <sys/utsname.h>
655
656#ifdef __FreeBSD__
657#include <sys/sysent.h>
658#endif
659
660#include <sys/syscall.h>
661
662#ifndef SYS_MAXSYSCALL
663#define SYS_MAXSYSCALL 512
664#endif
665
666/* number of system calls */
667#define SH_MAXCALLS 512
668#include "kern_head.h"
669static int verbose = 0;
670
671#ifdef __OpenBSD__
672struct proc;
673struct sysent {
674 short sy_narg;
675 short sy_argsize;
676 int (*sy_call)(struct proc *, void *, register_t *);
677};
678#endif
679
680typedef struct _smap_entry {
681 unsigned int code[2]; /* 8 bytes */
682 unsigned long addr;
683 char name[64];
684} smap_entry;
685
686union {
687 unsigned long addr_sys_call_table;
688 unsigned char str_sys_call_table[sizeof(unsigned long)];
689} sh_sys_call;
690
691struct nlist sys_list[SYS_MAXSYSCALL+1];
692
693struct nlist list[2];
694
695
696int main(int argc, char * argv[])
697{
698 int i, count, which;
699 smap_entry sh_smap[SYS_MAXSYSCALL];
700 struct utsname utbuf;
701 char errbuf[_POSIX2_LINE_MAX];
702
703 struct sysent sy;
704 unsigned long offset = 0L;
705 kvm_t *kd;
706
707 list[0].n_name = "_sysent";
708 list[1].n_name = NULL;
709
710 if (argc > 1)
711 {
712 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
713 usage(EXIT_SUCCESS);
714 else if (strcmp(argv[1], "-v") == 0 ||
715 strcmp(argv[1], "--verbose") == 0)
716 verbose = 1;
717 }
718
719 if (0 != uname(&utbuf))
720 {
721 perror("kern_head: uname");
722 exit (EXIT_FAILURE);
723 }
724
725#ifdef __OpenBSD__
726 if (utbuf.release[0] == '3')
727 which = 38;
728 else if (utbuf.release[0] == '4')
729 which = 40;
730#else
731 if (utbuf.release[0] == '4')
732 which = 4;
733 else if (utbuf.release[0] == '5')
734 which = 5;
735 else if (utbuf.release[0] == '6')
736 which = 5;
737#endif
738 else
739 {
740 fprintf(stderr, "kern_head: kernel %s not supported\n", utbuf.release);
741 exit (EXIT_FAILURE);
742 }
743
744 if (utbuf.machine[0] != 'i' || utbuf.machine[2] != '8' ||
745 utbuf.machine[3] != '6')
746 {
747 fprintf(stderr, "kern_head: machine %s not supported\n", utbuf.machine);
748 exit (EXIT_FAILURE);
749 }
750
751 if (0 != getuid())
752 {
753 fprintf(stderr, "\n");
754 fprintf(stderr, "NOTE: kern_head: must run as 'root' ");
755 fprintf(stderr, "(need to read from kernel)\n");
756 fprintf(stderr, " If you get this message, then proceed ");
757 fprintf(stderr, "as follows:\n");
758 fprintf(stderr, " $ su\n");
759 fprintf(stderr, " $ ./kern_head > sh_ks.h\n");
760 fprintf(stderr, " $ exit\n");
761 fprintf(stderr, " $ make\n\n");
762 exit (EXIT_FAILURE);
763 }
764
765 kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
766 if (!kd)
767 {
768 fprintf(stderr, "check_sysent: kvm_openfiles: %s\n", errbuf);
769 exit(EXIT_FAILURE);
770 }
771
772 i = kvm_nlist(kd, list);
773 if (i == -1)
774 {
775 fprintf(stderr, "check_sysent: kvm_nlist: %s\n", kvm_geterr(kd));
776 exit(EXIT_FAILURE);
777 }
778 else if (i == 1)
779 {
780 fprintf(stderr, "check_sysent: kvm_nlist: _sysent not found\n");
781 exit(EXIT_FAILURE);
782 }
783 else if (list[0].n_value == 0)
784 {
785 fprintf(stderr, "check_sysent: kvm_nlist: zero address for _sysent\n");
786 exit(EXIT_FAILURE);
787 }
788
789 if (which == 4)
790 printf("\n/* Kernel %s, machine %s -- use table %s */\n\n",
791 utbuf.release, utbuf.machine, "callz_fbsd");
792 else if (which == 5 || which == 6)
793 printf("\n/* Kernel %s, machine %s -- use table %s */\n\n",
794 utbuf.release, utbuf.machine, "callz_fbsd5");
795 else if (which == 38 || which == 40)
796 printf("\n/* Kernel %s, machine %s -- use table %s */\n\n",
797 utbuf.release, utbuf.machine, "callz_obsd");
798
799
800 i = 0;
801 if (which == 4) {
802 while ((callz_fbsd[i] != NULL) && (i < SYS_MAXSYSCALL))
803 {
804 sys_list[i].n_name = callz_fbsd[i];
805 /* fprintf(stderr, "sys_list[%d] = %s\n", i, sys_list[i].n_name); */
806 ++i;
807 }
808 if ((utbuf.release[1] == '.') && (utbuf.release[2] == '1') &&
809 (utbuf.release[3] == '0'))
810 {
811 sys_list[336].n_name = callz_fbsd[151]; /* sendfile -> nosys */
812 }
813 } else if (which == 5 || which == 6) {
814 while ((callz_fbsd5[i] != NULL) && (i < SYS_MAXSYSCALL))
815 {
816 sys_list[i].n_name = callz_fbsd5[i];
817 /* fprintf(stderr, "sys_list[%d] = %s\n", i, sys_list[i].n_name); */
818 ++i;
819 }
820 }
821 else if (which == 38 || which == 40) {
822 while ((callz_obsd[i] != NULL) && (i < SYS_MAXSYSCALL))
823 {
824 sys_list[i].n_name = callz_obsd[i];
825 /* fprintf(stderr, "sys_list[%d] = %s\n", i, sys_list[i].n_name); */
826 ++i;
827 }
828 }
829
830 count = i;
831 sys_list[i].n_name = NULL;
832
833 i = kvm_nlist(kd, sys_list);
834 if (i == -1)
835 {
836 fprintf(stderr, "check_sysent: kvm_nlist: %s\n", kvm_geterr(kd));
837 /* exit(EXIT_FAILURE); */
838 }
839 else if (i != 0 && verbose != 0)
840 {
841 fprintf(stderr, "check_sysent: kvm_nlist: %d out of %d invalid.\n",
842 i, count);
843 fprintf(stderr, " Probably the table in kern_head.h\n");
844 fprintf(stderr, " is not for your kernel version.\n");
845 fprintf(stderr, " (No reason to worry, kcheck will "\
846 "work anyway)\n\n");
847 }
848
849 for (i = 0; i < count /* SYS_MAXSYSCALL */; i++)
850 {
851 if (NULL == sys_list[i].n_name)
852 break;
853 if (!sys_list[i].n_value && 0 != strcmp(sys_list[i].n_name, "_nosys")
854 && verbose != 0)
855 {
856 fprintf(stderr,"check_sysent: not found: slot %03d [%s]\n",
857 i, sys_list[i].n_name);
858 /* exit(EXIT_FAILURE); */
859 }
860 offset = list[0].n_value + (i*sizeof(struct sysent));
861 if (kvm_read(kd, offset, &sy, sizeof(struct sysent)) < 0)
862 {
863 fprintf(stderr,"check_sysent: kvm_read: %s\n", kvm_geterr(kd));
864 exit(EXIT_FAILURE);
865 }
866
867 if (verbose > 0)
868 fprintf(stderr, "(kvm_nlist) %#lx %#lx (sysent[%03d]) %03d [%s]\n",
869 (unsigned long) sys_list[i].n_value,
870 (unsigned long) sy.sy_call,
871 i, i, sys_list[i].n_name);
872
873 if((unsigned long)sy.sy_call != sys_list[i].n_value &&
874 sys_list[i].n_value != 0 &&
875 0 != strcmp(sys_list[i].n_name, "_nosys") &&
876 (unsigned long)sy.sy_call != sys_list[151].n_value)
877 {
878 fprintf(stderr,
879 "WARNING: (kvm_nlist) %#lx != %#lx (sysent[%03d]) %03d [%s]\n",
880 (unsigned long) sys_list[i].n_value,
881 (unsigned long) sy.sy_call,
882 i, i, sys_list[i].n_name);
883 }
884 sh_smap[i].addr = (unsigned long) sy.sy_call;
885 strncpy(sh_smap[i].name, sys_list[i].n_name, 64);
886 if(kvm_read(kd, (unsigned int) sy.sy_call, &(sh_smap[i].code[0]),
887 2 * sizeof(unsigned int)) < 0)
888 {
889 fprintf(stderr,"check_sysent: kvm_read: %s\n", kvm_geterr(kd));
890 exit(EXIT_FAILURE);
891 }
892 }
893
894 if(kvm_close(kd) < 0)
895 {
896 fprintf(stderr,"check_sysent: kvm_nlist: %s\n", kvm_geterr(kd));
897 exit(EXIT_FAILURE);
898 }
899
900 printf("#ifndef SH_KERN_CALLS_H\n");
901 printf("#define SH_KERN_CALLS_H\n\n");
902
903 printf("#define SH_MAXCALLS %d\n\n", count);
904
905 printf("typedef struct _sh_syscall_t {\n");
906 printf(" unsigned int code[2]; /* 8 bytes */\n");
907 printf(" unsigned long addr;\n");
908 printf(" char * name;\n");
909 printf("} sh_syscall_t;\n\n");
910
911 printf("static sh_syscall_t sh_syscalls[] = {\n");
912 for (i = 0; i < count; ++i) {
913 printf(" /* %03d */ {{ 0x%-8.8x, 0x%-8.8x }, 0x%-8.8lx, N_(%c%s%c) },\n",
914 i, sh_smap[i].code[0], sh_smap[i].code[1],
915 sh_smap[i].addr, '"', sh_smap[i].name, '"');
916 }
917 printf(" /* eof */ { { 0x00000000, 0x00000000 }, 0x00000000, NULL }\n");
918 printf("};\n\n");
919 printf("#endif\n");
920 return 0;
921}
922/* if defined(HOST_IS_FREEBSD) */
923#endif
924
925/* #if defined(SH_USE_KERN) */
926#else
927
928#include <stdio.h>
929#include <stdlib.h>
930
931int main()
932{
933 printf("#ifndef SH_KERN_CALLS_H\n");
934 printf("#define SH_KERN_CALLS_H\n\n");
935
936 printf("/* Dummy header. */\n\n");
937
938 printf("typedef struct _sh_syscall_t {\n");
939 printf(" unsigned long addr;\n");
940 printf(" char * name;\n");
941 printf("} sh_syscall_t;\n\n");
942
943 printf("#endif\n");
944
945 return (EXIT_SUCCESS);
946}
947
948/* #ifdef SH_USE_KERN */
949#endif
Note: See TracBrowser for help on using the repository browser.