xref: /dragonfly/test/debug/kwrite.c (revision b7cb6098b29b5d9c4d9d8aace381eca12dbd801f)
1 /*
2  * Tool to read/write kernel memory.
3  *
4  * Compile with
5           cc -o kwrite kwrite.c -lkvm
6  *
7  * $DragonFly: src/test/debug/kwrite.c,v 1.1 2006/01/09 15:05:45 corecode Exp $
8  */
9 
10 #include <fcntl.h>
11 #include <kvm.h>
12 #include <limits.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <errno.h>
16 #include <err.h>
17 
18 static void
usage(void)19 usage(void)
20 {
21           fprintf(stderr, "usage: kwrite addr[/width] [bval] [bval]\n");
22           exit(1);
23 }
24 
25 int
main(int argc,char ** argv)26 main(int argc, char **argv)
27 {
28           char errbuf[_POSIX2_LINE_MAX];
29           kvm_t *kvm;
30           unsigned long addr, width = 1, i;
31           char *endptr, *endptr2;
32 
33           if (argc < 2)
34                     usage();
35 
36           errno = 0;
37           addr = strtoul(argv[1], &endptr, 0);
38           if (endptr == argv[1])
39                     errx(1, "no addr");
40           if (errno != 0)
41                     err(1, "addr '%s'", argv[1]);
42           switch (*endptr) {
43           case 0:
44                     break;
45           case '/':
46                     endptr++;
47                     width = strtoul(endptr, &endptr2, 0);
48                     if (endptr2 == endptr)
49                               errx(1, "no width");
50                     if (errno != 0)
51                               err(1, "width '%s'", endptr);
52                     break;
53           default:
54                     errx(1, "invalid addr '%s'", argv[1]);
55           }
56 
57           kvm = kvm_openfiles(NULL, NULL, NULL, O_RDWR, errbuf);
58           if (kvm == NULL)
59                     errx(1, "%s", errbuf);
60 
61           if (argc < 3) {
62                     for (i = 0; i < width; i++) {
63                               char b;
64 
65                               if (kvm_read(kvm, addr + i, &b, 1) != 1)
66                                         errx(1, "%s", kvm_geterr(kvm));
67                               printf("%#0*lx %02x\n",
68                                         (int)sizeof(addr) * 2, addr + i, b);
69                     }
70           } else {
71                     if (argc < width + 2)
72                               errx(1, "too few values for width %ld", width);
73                     width = argc - 2;
74                     for (i = 0; i < width; i++) {
75                               long v;
76                               char b, bo;
77 
78                               errno = 0;
79                               v = strtol(argv[2 + i], &endptr, 0);
80                               if (endptr == argv[2 + i] || *endptr != 0)
81                                         errx(1, "invalid value '%s'", argv[2 + i]);
82                               if (errno != 0 || v < 0 || v > 256) {
83                                         if (errno == 0) errno = ERANGE;
84                                         errx(1, "value '%s'", argv[2 + i]);
85                               }
86                               b = v;
87 
88                               if (kvm_read(kvm, addr + i, &bo, 1) != 1)
89                                         errx(1, "%s", kvm_geterr(kvm));
90                               printf("%#0*lx %02x -> %02x\n",
91                                      (int)sizeof(addr) * 2, addr + i, bo, b);
92                               if (kvm_write(kvm, addr + i, &b, 1) != 1)
93                                         errx(1, "%s", kvm_geterr(kvm));
94                     }
95           }
96 
97           return 0;
98 }
99