source: trunk/src/kern_head.c@ 47

Last change on this file since 47 was 41, checked in by rainer, 18 years ago

Use mmap() if read() fails for /dev/kmem

File size: 24.0 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");
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
356struct inode_operations {
357 int (*create) (int *,int *,int);
358 int * (*lookup) (int *,int *);
359 int (*link) (int *,int *,int *);
360 int (*unlink) (int *,int *);
361 int (*symlink) (int *,int *,const char *);
362 int (*mkdir) (int *,int *,int);
363 int (*rmdir) (int *,int *);
364 int (*mknod) (int *,int *,int,int);
365 int (*rename) (int *, int *,
366 int *, int *);
367 int (*readlink) (int *, char *,int);
368 int (*follow_link) (int *, int *);
369 void (*truncate) (int *);
370 int (*permission) (int *, int);
371 int (*revalidate) (int *);
372 /*
373 int (*setattr) (int *, int *);
374 int (*getattr) (int *, int *);
375 int (*setxattr) (int *, const char *, void *, size_t, int);
376 ssize_t (*getxattr) (int *, const char *, void *, size_t);
377 ssize_t (*listxattr) (int *, char *, size_t);
378 int (*removexattr) (int *, const char *);
379 */
380};
381
382struct file_operations {
383 int (*create) (int *,int *,int);
384};
385
386struct proc_dir_entry {
387 unsigned short low_ino;
388 unsigned short namelen;
389 const char * name;
390 mode_t mode;
391 nlink_t nlink;
392 uid_t uid;
393 gid_t gid;
394 unsigned long size;
395 struct inode_operations * proc_iops;
396 struct file_operations * proc_fops;
397 /*
398 get_info_t *get_info;
399 struct module *owner;
400 struct proc_dir_entry *next, *parent, *subdir;
401 void *data;
402 read_proc_t *read_proc;
403 write_proc_t *write_proc;
404 atomic_t count;
405 int deleted;
406 */
407};
408
409
410
411int main(int argc, char * argv[])
412{
413 int i, count, maxcall, qq;
414 int which = 4;
415 smap_entry sh_smap[SH_MAXCALLS];
416 struct utsname utbuf;
417 char *p = NULL;
418
419 unsigned long proc_root;
420 unsigned long proc_root_iops;
421 unsigned long proc_root_lookup;
422
423 unsigned long addr_ni_syscall = 0;
424
425 if (argc > 1)
426 {
427 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
428 usage(EXIT_SUCCESS);
429 else if (strcmp(argv[1], "-v") == 0 ||
430 strcmp(argv[1], "--verbose") == 0)
431 verbose = 1;
432 }
433
434 if (0 != uname(&utbuf))
435 {
436 perror("kern_head: uname");
437 exit (EXIT_FAILURE);
438 }
439
440 if (strncmp(utbuf.release, SH_KERNEL_VERSION, 3) != 0)
441 {
442 fprintf(stderr, "kern_head: current kernel version %s does not match\n",
443 utbuf.release);
444 fprintf(stderr, "kern_head: %s from config.h\n", SH_KERNEL_VERSION);
445 fprintf(stderr, "kern_head: continuing with %s\n", SH_KERNEL_VERSION);
446
447 p = SH_KERNEL_VERSION;
448 } else {
449 p = utbuf.release;
450 }
451
452 if (strncmp(p, "2.2", 3) == 0)
453 which = 2;
454 else if (strncmp(p, "2.4", 3) == 0)
455 which = 4;
456 else if (strncmp(p, "2.6", 3) == 0)
457 which = 6;
458 else
459 {
460 fprintf(stderr, "kern_head: kernel %s not supported\n", p);
461 exit (EXIT_FAILURE);
462 }
463
464
465 if (utbuf.machine[0] != 'i' || utbuf.machine[2] != '8' ||
466 utbuf.machine[3] != '6')
467 {
468 fprintf(stderr, "kern_head: machine %s not supported\n", utbuf.machine);
469 exit (EXIT_FAILURE);
470 }
471
472 if (0 != getuid())
473 {
474 fprintf(stderr, "\n");
475
476 fprintf(stderr, "NOTE: kern_head: must run as 'root' (need to read from /dev/kmem)\n");
477 fprintf(stderr, " If you get this message, then proceed as follows:\n");
478 fprintf(stderr, " $ su\n");
479 fprintf(stderr, " $ ./kern_head > sh_ks.h\n");
480 fprintf(stderr, " $ exit\n");
481 fprintf(stderr, " $ make\n\n");
482 exit (EXIT_FAILURE);
483 }
484
485 printf("#ifndef SH_KERN_CALLS_H\n");
486 printf("#define SH_KERN_CALLS_H\n\n");
487
488 printf("\n/* Kernel %s, machine %s -- use table %s */\n\n",
489 p, utbuf.machine,
490 (which == 2) ? "callz_2p2" : "callz_2p4");
491
492
493 /* initiate the system call table
494 */
495 for (i = 0; i < SH_MAXCALLS; ++i)
496 {
497 if (which == 2)
498 {
499 if (callz_2p2[i] == NULL)
500 break;
501 strcpy(sh_smap[i].name, callz_2p2[i]);
502 }
503 else
504 {
505 if (callz_2p4[i] == NULL)
506 break;
507 strcpy(sh_smap[i].name, callz_2p4[i]);
508 }
509 sh_smap[i].addr = 0UL;
510 }
511
512 if (which == 6) /* fix syscall map for 2.6 */
513 {
514 strcpy(sh_smap[0].name, "sys_restart_syscall");
515 strcpy(sh_smap[180].name, "sys_pread64");
516 strcpy(sh_smap[181].name, "sys_pwrite64");
517 }
518 count = i;
519
520 /* get the actual number of the highest syscalls and use no more.
521 * get sys_call_table and system_call
522 */
523 maxcall = fill_smap(sh_smap, count);
524 if ( maxcall < 0)
525 {
526 printf("#endif\n");
527 fprintf(stderr, "kern_head: fill_smap failed\n");
528 exit (EXIT_FAILURE);
529 }
530 if (addr_system_call == 0L)
531 {
532 printf("#endif\n");
533 fprintf(stderr,
534 "kern_head: address of system_call not found in System.map\n");
535 fprintf(stderr,
536 "** This indicates that your System.map does not provide\n");
537 fprintf(stderr,
538 "** the required information, and thus use of the\n");
539 fprintf(stderr,
540 "** --with-kcheck option is not possible\n");
541 exit (EXIT_FAILURE);
542 }
543
544 for (i = 0; i < maxcall; ++i)
545 {
546 if (0 == strcmp(sh_smap[i].name, "sys_ni_syscall"))
547 {
548 addr_ni_syscall = sh_smap[i].addr;
549 break;
550 }
551 }
552 if (which < 6)
553 {
554 maxcall = (maxcall > 256) ? 256 : maxcall;
555 }
556
557 for (i = 0; i < maxcall; ++i)
558 {
559 if (sh_smap[i].addr == 0UL)
560 {
561 if (verbose > 0)
562 fprintf(stderr, "** unknown syscall **: [%s]\n", sh_smap[i].name);
563 strcpy(sh_smap[i].name, "sys_ni_syscall");
564 sh_smap[i].addr = addr_ni_syscall;
565 }
566 }
567
568
569 /* get the location of the syscall table address within system_call
570 */
571 if ( get_dispatch (&qq) < 0)
572 {
573 printf("#endif\n");
574 fprintf(stderr, "kern_head: get_dispatch failed\n");
575 exit (EXIT_FAILURE);
576 }
577
578 if (qq <= 252)
579 printf("#define SYS_CALL_LOC %d\n", qq);
580 else
581 {
582 printf("#endif\n");
583 fprintf(stderr, "kern_head: SYS_CALL_LOC (%d) too large\n", qq);
584 exit(EXIT_FAILURE);
585 }
586 printf("#define SH_SYS_CALL_ADDR %#lx\n\n", addr_system_call);
587
588 printf("static unsigned char system_call_code[256] = { 0 };\n");
589
590 printf("#define SH_MAXCALLS %d\n\n", maxcall);
591
592#ifdef SH_IDT_TABLE
593 printf("static unsigned char idt_table[2048] = { 0 };\n");
594#endif
595
596 printf("typedef struct _sh_syscall_t {\n");
597#ifdef SH_SYSCALL_CODE
598 printf(" unsigned int code[2]; /* 8 bytes */\n");
599#endif
600 printf(" unsigned long addr;\n");
601 printf(" char * name;\n");
602 printf("} sh_syscall_t;\n\n");
603
604 printf("static sh_syscall_t sh_syscalls[] = {\n");
605
606 for (i = 0; i < maxcall; ++i)
607 {
608#ifdef SH_SYSCALL_CODE
609 printf(" /* %03d */ { { 0, 0 }, 0, N_(%c%s%c) },\n",
610 i, '"', sh_smap[i].name, '"');
611#else
612 printf(" /* %03d */ { 0, N_(%c%s%c) },\n",
613 i, '"', sh_smap[i].name, '"');
614#endif
615 }
616#ifdef SH_SYSCALL_CODE
617 printf(" /* eof */ { { 0x00000000, 0x00000000 }, 0x00000000, NULL }\n");
618#else
619 printf(" /* eof */ { 0x00000000, NULL }\n");
620#endif
621 printf("};\n\n");
622
623
624 /* get proc addresses
625 */
626 proc_root = get_symbol_from_systemmap (SYSTEMMAP,
627 "proc_root", 'D');
628 if (proc_root == 0)
629 {
630 proc_root = get_symbol_from_systemmap (SYSTEMMAP,
631 "proc_root", 'd');
632 }
633 if (proc_root == 0)
634 {
635 proc_root = get_symbol_from_systemmap (SYSTEMMAP,
636 "proc_root", 'R');
637 }
638 if (proc_root != 0) {
639 printf("#define PROC_ROOT_LOC %#lx\n\n", proc_root);
640 }
641
642 proc_root_lookup = get_symbol_from_systemmap (SYSTEMMAP,
643 "proc_root_lookup", 't');
644 if (proc_root_lookup == 0)
645 {
646 proc_root_lookup = get_symbol_from_systemmap (SYSTEMMAP,
647 "proc_root_lookup", 'T');
648 }
649 if (proc_root_lookup != 0) {
650 printf("#define PROC_ROOT_LOOKUP_LOC %#lx\n\n", proc_root_lookup);
651 }
652
653 proc_root_iops = get_symbol_from_systemmap (SYSTEMMAP,
654 "proc_root_inode_operations",
655 'd');
656 if (proc_root_iops == 0)
657 {
658 proc_root_iops = get_symbol_from_systemmap (SYSTEMMAP,
659 "proc_root_inode_operations",
660 'D');
661 }
662 if (proc_root_iops == 0)
663 {
664 proc_root_iops = get_symbol_from_systemmap (SYSTEMMAP,
665 "proc_root_inode_operations",
666 'R');
667 }
668 if (proc_root_iops != 0) {
669 printf("#define PROC_ROOT_IOPS_LOC %#lx\n\n", proc_root_iops);
670 }
671
672 printf("#endif\n");
673
674 exit (EXIT_SUCCESS);
675}
676
677/* if defined(HOST_IS_LINUX) */
678#endif
679
680/************************************************************
681 *
682 *
683 * FreeBSD Implementation
684 *
685 ************************************************************/
686
687#if defined(HOST_IS_FREEBSD) || defined(__OpenBSD__)
688
689#include <stdlib.h>
690#include <unistd.h>
691#include <string.h>
692#include <err.h>
693#include <kvm.h>
694#include <fcntl.h>
695#include <nlist.h>
696#include <limits.h>
697#include <sys/types.h>
698#include <sys/utsname.h>
699
700#ifdef __FreeBSD__
701#include <sys/sysent.h>
702#endif
703
704#include <sys/syscall.h>
705
706#ifndef SYS_MAXSYSCALL
707#define SYS_MAXSYSCALL 512
708#endif
709
710/* number of system calls */
711#define SH_MAXCALLS 512
712#include "kern_head.h"
713static int verbose = 0;
714
715#ifdef __OpenBSD__
716struct proc;
717struct sysent {
718 short sy_narg;
719 short sy_argsize;
720 int (*sy_call)(struct proc *, void *, register_t *);
721};
722#endif
723
724typedef struct _smap_entry {
725 unsigned int code[2]; /* 8 bytes */
726 unsigned long addr;
727 char name[64];
728} smap_entry;
729
730union {
731 unsigned long addr_sys_call_table;
732 unsigned char str_sys_call_table[sizeof(unsigned long)];
733} sh_sys_call;
734
735struct nlist sys_list[SYS_MAXSYSCALL+1];
736
737struct nlist list[2];
738
739
740int main(int argc, char * argv[])
741{
742 int i, count, which;
743 smap_entry sh_smap[SYS_MAXSYSCALL];
744 struct utsname utbuf;
745 char errbuf[_POSIX2_LINE_MAX];
746
747 struct sysent sy;
748 unsigned long offset = 0L;
749 kvm_t *kd;
750
751 list[0].n_name = "_sysent";
752 list[1].n_name = NULL;
753
754 if (argc > 1)
755 {
756 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
757 usage(EXIT_SUCCESS);
758 else if (strcmp(argv[1], "-v") == 0 ||
759 strcmp(argv[1], "--verbose") == 0)
760 verbose = 1;
761 }
762
763 if (0 != uname(&utbuf))
764 {
765 perror("kern_head: uname");
766 exit (EXIT_FAILURE);
767 }
768
769#ifdef __OpenBSD__
770 if (utbuf.release[0] == '3')
771 which = 38;
772#else
773 if (utbuf.release[0] == '4')
774 which = 4;
775 else if (utbuf.release[0] == '5')
776 which = 5;
777 else if (utbuf.release[0] == '6')
778 which = 5;
779#endif
780 else
781 {
782 fprintf(stderr, "kern_head: kernel %s not supported\n", utbuf.release);
783 exit (EXIT_FAILURE);
784 }
785
786 if (utbuf.machine[0] != 'i' || utbuf.machine[2] != '8' ||
787 utbuf.machine[3] != '6')
788 {
789 fprintf(stderr, "kern_head: machine %s not supported\n", utbuf.machine);
790 exit (EXIT_FAILURE);
791 }
792
793 if (0 != getuid())
794 {
795 fprintf(stderr, "\n");
796 fprintf(stderr, "NOTE: kern_head: must run as 'root' ");
797 fprintf(stderr, "(need to read from /dev/kmem)\n");
798 fprintf(stderr, " If you get this message, then proceed ");
799 fprintf(stderr, "as follows:\n");
800 fprintf(stderr, " $ su\n");
801 fprintf(stderr, " $ ./kern_head > sh_ks.h\n");
802 fprintf(stderr, " $ exit\n");
803 fprintf(stderr, " $ make\n\n");
804 exit (EXIT_FAILURE);
805 }
806
807 kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
808 if (!kd)
809 {
810 fprintf(stderr, "check_sysent: kvm_openfiles: %s\n", errbuf);
811 exit(EXIT_FAILURE);
812 }
813
814 i = kvm_nlist(kd, list);
815 if (i == -1)
816 {
817 fprintf(stderr, "check_sysent: kvm_nlist: %s\n", kvm_geterr(kd));
818 exit(EXIT_FAILURE);
819 }
820 else if (i == 1)
821 {
822 fprintf(stderr, "check_sysent: kvm_nlist: _sysent not found\n");
823 exit(EXIT_FAILURE);
824 }
825 else if (list[0].n_value == 0)
826 {
827 fprintf(stderr, "check_sysent: kvm_nlist: zero address for _sysent\n");
828 exit(EXIT_FAILURE);
829 }
830
831 if (which == 4)
832 printf("\n/* Kernel %s, machine %s -- use table %s */\n\n",
833 utbuf.release, utbuf.machine, "callz_fbsd");
834 else if (which == 5 || which == 6)
835 printf("\n/* Kernel %s, machine %s -- use table %s */\n\n",
836 utbuf.release, utbuf.machine, "callz_fbsd5");
837 else if (which == 38)
838 printf("\n/* Kernel %s, machine %s -- use table %s */\n\n",
839 utbuf.release, utbuf.machine, "callz_obsd");
840
841
842 i = 0;
843 if (which == 4) {
844 while ((callz_fbsd[i] != NULL) && (i < SYS_MAXSYSCALL))
845 {
846 sys_list[i].n_name = callz_fbsd[i];
847 /* fprintf(stderr, "sys_list[%d] = %s\n", i, sys_list[i].n_name); */
848 ++i;
849 }
850 if ((utbuf.release[1] == '.') && (utbuf.release[2] == '1') &&
851 (utbuf.release[3] == '0'))
852 {
853 sys_list[336].n_name = callz_fbsd[151]; /* sendfile -> nosys */
854 }
855 } else if (which == 5 || which == 6) {
856 while ((callz_fbsd5[i] != NULL) && (i < SYS_MAXSYSCALL))
857 {
858 sys_list[i].n_name = callz_fbsd5[i];
859 /* fprintf(stderr, "sys_list[%d] = %s\n", i, sys_list[i].n_name); */
860 ++i;
861 }
862 }
863 else if (which == 38) {
864 while ((callz_obsd[i] != NULL) && (i < SYS_MAXSYSCALL))
865 {
866 sys_list[i].n_name = callz_obsd[i];
867 /* fprintf(stderr, "sys_list[%d] = %s\n", i, sys_list[i].n_name); */
868 ++i;
869 }
870 }
871
872 count = i;
873 sys_list[i].n_name = NULL;
874
875 i = kvm_nlist(kd, sys_list);
876 if (i == -1)
877 {
878 fprintf(stderr, "check_sysent: kvm_nlist: %s\n", kvm_geterr(kd));
879 /* exit(EXIT_FAILURE); */
880 }
881 else if (i != 0 && verbose != 0)
882 {
883 fprintf(stderr, "check_sysent: kvm_nlist: %d out of %d invalid.\n",
884 i, count);
885 fprintf(stderr, " Probably the table in kern_head.h\n");
886 fprintf(stderr, " is not for your kernel version.\n");
887 fprintf(stderr, " (No reason to worry, kcheck will "\
888 "work anyway)\n\n");
889 }
890
891 for (i = 0; i < count /* SYS_MAXSYSCALL */; i++)
892 {
893 if (NULL == sys_list[i].n_name)
894 break;
895 if (!sys_list[i].n_value && 0 != strcmp(sys_list[i].n_name, "_nosys")
896 && verbose != 0)
897 {
898 fprintf(stderr,"check_sysent: not found: slot %03d [%s]\n",
899 i, sys_list[i].n_name);
900 /* exit(EXIT_FAILURE); */
901 }
902 offset = list[0].n_value + (i*sizeof(struct sysent));
903 if (kvm_read(kd, offset, &sy, sizeof(struct sysent)) < 0)
904 {
905 fprintf(stderr,"check_sysent: kvm_read: %s\n", kvm_geterr(kd));
906 exit(EXIT_FAILURE);
907 }
908
909 if (verbose > 0)
910 fprintf(stderr, "(kvm_nlist) %#lx %#lx (sysent[%03d]) %03d [%s]\n",
911 (unsigned long) sys_list[i].n_value,
912 (unsigned long) sy.sy_call,
913 i, i, sys_list[i].n_name);
914
915 if((unsigned long)sy.sy_call != sys_list[i].n_value &&
916 sys_list[i].n_value != 0 &&
917 0 != strcmp(sys_list[i].n_name, "_nosys") &&
918 (unsigned long)sy.sy_call != sys_list[151].n_value)
919 {
920 fprintf(stderr,
921 "WARNING: (kvm_nlist) %#lx != %#lx (sysent[%03d]) %03d [%s]\n",
922 (unsigned long) sys_list[i].n_value,
923 (unsigned long) sy.sy_call,
924 i, i, sys_list[i].n_name);
925 }
926 sh_smap[i].addr = (unsigned long) sy.sy_call;
927 strncpy(sh_smap[i].name, sys_list[i].n_name, 64);
928 if(kvm_read(kd, (unsigned int) sy.sy_call, &(sh_smap[i].code[0]),
929 2 * sizeof(unsigned int)) < 0)
930 {
931 fprintf(stderr,"check_sysent: kvm_read: %s\n", kvm_geterr(kd));
932 exit(EXIT_FAILURE);
933 }
934 }
935
936 if(kvm_close(kd) < 0)
937 {
938 fprintf(stderr,"check_sysent: kvm_nlist: %s\n", kvm_geterr(kd));
939 exit(EXIT_FAILURE);
940 }
941
942 printf("#ifndef SH_KERN_CALLS_H\n");
943 printf("#define SH_KERN_CALLS_H\n\n");
944
945 printf("#define SH_MAXCALLS %d\n\n", count);
946
947 printf("typedef struct _sh_syscall_t {\n");
948 printf(" unsigned int code[2]; /* 8 bytes */\n");
949 printf(" unsigned long addr;\n");
950 printf(" char * name;\n");
951 printf("} sh_syscall_t;\n\n");
952
953 printf("static sh_syscall_t sh_syscalls[] = {\n");
954 for (i = 0; i < count; ++i) {
955 printf(" /* %03d */ {{ 0x%-8.8x, 0x%-8.8x }, 0x%-8.8lx, N_(%c%s%c) },\n",
956 i, sh_smap[i].code[0], sh_smap[i].code[1],
957 sh_smap[i].addr, '"', sh_smap[i].name, '"');
958 }
959 printf(" /* eof */ { { 0x00000000, 0x00000000 }, 0x00000000, NULL }\n");
960 printf("};\n\n");
961 printf("#endif\n");
962 return 0;
963}
964/* if defined(HOST_IS_FREEBSD) */
965#endif
966
967/* #if defined(SH_USE_KERN) */
968#else
969
970#include <stdio.h>
971#include <stdlib.h>
972
973int main()
974{
975 printf("#ifndef SH_KERN_CALLS_H\n");
976 printf("#define SH_KERN_CALLS_H\n\n");
977
978 printf("/* Dummy header. */\n\n");
979
980 printf("typedef struct _sh_syscall_t {\n");
981 printf(" unsigned long addr;\n");
982 printf(" char * name;\n");
983 printf("} sh_syscall_t;\n\n");
984
985 printf("#endif\n");
986
987 return (EXIT_SUCCESS);
988}
989
990/* #ifdef SH_USE_KERN */
991#endif
Note: See TracBrowser for help on using the repository browser.