source: trunk/src/kern_head.c@ 9

Last change on this file since 9 was 9, checked in by rainer, 19 years ago

Compile kernel check module in OpenBSD

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