1 #include <fcntl.h>
2 #include <inttypes.h>
3 #include <stdbool.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/mman.h>
8 #include <unistd.h>
9 
10 #if __LP64__
11 #define strtoptr strtoull
12 #else
13 #define strtoptr strtoul
14 #endif
15 
usage()16 static int usage()
17 {
18     fprintf(stderr,"r [-b|-s] <address> [<value>]\n");
19     return -1;
20 }
21 
main(int argc,char * argv[])22 int main(int argc, char *argv[])
23 {
24     if(argc < 2) return usage();
25 
26     int width = 4;
27     if(!strcmp(argv[1], "-b")) {
28         width = 1;
29         argc--;
30         argv++;
31     } else if(!strcmp(argv[1], "-s")) {
32         width = 2;
33         argc--;
34         argv++;
35     }
36 
37     if(argc < 2) return usage();
38     uintptr_t addr = strtoptr(argv[1], 0, 16);
39 
40     uintptr_t endaddr = 0;
41     char* end = strchr(argv[1], '-');
42     if (end)
43         endaddr = strtoptr(end + 1, 0, 16);
44 
45     if (!endaddr)
46         endaddr = addr + width - 1;
47 
48     if (endaddr <= addr) {
49         fprintf(stderr, "end address <= start address\n");
50         return -1;
51     }
52 
53     bool set = false;
54     uint32_t value = 0;
55     if(argc > 2) {
56         set = true;
57         value = strtoul(argv[2], 0, 16);
58     }
59 
60     int fd = open("/dev/mem", O_RDWR | O_SYNC);
61     if(fd < 0) {
62         fprintf(stderr,"cannot open /dev/mem\n");
63         return -1;
64     }
65 
66     off64_t mmap_start = addr & ~(PAGE_SIZE - 1);
67     size_t mmap_size = endaddr - mmap_start + 1;
68     mmap_size = (mmap_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
69 
70     void* page = mmap64(0, mmap_size, PROT_READ | PROT_WRITE,
71                         MAP_SHARED, fd, mmap_start);
72 
73     if(page == MAP_FAILED){
74         fprintf(stderr,"cannot mmap region\n");
75         return -1;
76     }
77 
78     while (addr <= endaddr) {
79         switch(width){
80         case 4: {
81             uint32_t* x = (uint32_t*) (((uintptr_t) page) + (addr & 4095));
82             if(set) *x = value;
83             fprintf(stderr,"%08"PRIxPTR": %08x\n", addr, *x);
84             break;
85         }
86         case 2: {
87             uint16_t* x = (uint16_t*) (((uintptr_t) page) + (addr & 4095));
88             if(set) *x = value;
89             fprintf(stderr,"%08"PRIxPTR": %04x\n", addr, *x);
90             break;
91         }
92         case 1: {
93             uint8_t* x = (uint8_t*) (((uintptr_t) page) + (addr & 4095));
94             if(set) *x = value;
95             fprintf(stderr,"%08"PRIxPTR": %02x\n", addr, *x);
96             break;
97         }
98         }
99         addr += width;
100     }
101     return 0;
102 }
103