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