source: trunk/src/kern_head.c@ 94

Last change on this file since 94 was 92, checked in by rainer, 18 years ago

Move fd closing more towards program start. Fix OpenBSD 4.0 compatibility for kernel check.

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 /dev/kmem)\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.