Convert binary page-table arrays captured from hboot images to C-language structures
[pagetables.git] / pagetables.c
1 /*
2    Generate readable C-source structures from binary page-table arrays found in hboot images
3    Copyright (C) 2010 TJ
4    Author: TJ <linux@tjworld.net>
5
6    This program is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, version 3 of the License.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <sys/mman.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <ctype.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <string.h>
28
29 void
30 usage(const char *name) {
31  printf("Usage: %s:  [-d -f <pagetable>\n", name);
32  printf("Copyright 2010 TJ <linux@tjworld.net>\n"
33         "Licensed under the terms of the GNU GPL v3\n\n"
34         "\t-d\tprint addresses in decimal not hexadecimal\n"
35         "\t-f\tpath to the file containing the needle\n\n"
36
37         "\tInformation messages are written to stderr and only matches are written to stdout.\n"
38         "\tThis allows the output to be piped through other filters.\n"
39  );
40 }
41
42 int
43 main(int argc, char *argv[], char *env[]) {
44  int ret = 0;
45  int c, use_decimal, pagetable_fd;
46  char *pagetable_name;
47  void *pagetable_mmap;
48  struct stat pagetable_stat;
49
50  pagetable_name = pagetable_mmap = NULL;
51  use_decimal = 0;
52
53  if (argc > 1) { // must have some parameters
54   opterr = 0;
55
56   while ((c = getopt(argc, argv, "f:d")) != -1 ) { // iterate the options
57    switch(c) {
58     case 'f':
59      pagetable_name = optarg;
60      break;
61     case 'd':
62      use_decimal = 1;
63      break;
64     default:
65      abort();
66    }
67   }
68
69   if ((pagetable_fd = open(pagetable_name, O_RDONLY)) == -1) {
70    perror("Unable to open pagetable");
71    ret |= 1;
72   }
73
74   
75   if (!ret) {
76    fstat(pagetable_fd, &pagetable_stat);
77    fprintf(stderr, "Base:\t%s\n", use_decimal == 1 ? "decimal" : "hexadecimal");
78    fprintf(stderr, "Pagetable:\t\t%12ld\t%s\n", pagetable_stat.st_size, pagetable_name);
79
80    if(MAP_FAILED == (pagetable_mmap = mmap(pagetable_mmap, pagetable_stat.st_size, PROT_READ, MAP_SHARED, pagetable_fd, 0))) {
81     perror("Unable to memory-map pagetable");
82     exit(4);
83    }
84    {
85     void *f = pagetable_mmap; // convenient short names
86     unsigned long offset;
87     unsigned long end = pagetable_stat.st_size;
88     unsigned int virtual;
89     unsigned int physical;
90     unsigned int count;
91     fprintf(stderr, "Processing...\n");
92     for (offset = 0; offset <= end; offset += 12) {
93      virtual = *(unsigned int *)(f + offset);
94      physical = *(unsigned int *)(f + offset + 4);
95      count = *(unsigned int *)(f + offset + 8);
96      if (use_decimal) fprintf(stdout, "{%010u, %010u, %010u},\n", virtual, physical, count);
97      else fprintf(stdout, "{0x%08X, 0x%08X, 0x%08X},\n", virtual, physical, count);
98     }
99     fprintf(stderr, "Done.\n");
100    }
101   }
102  }
103  else
104   usage(argv[0]);
105
106  if (pagetable_mmap > 0) munmap(pagetable_mmap, pagetable_stat.st_size);
107  if (pagetable_fd > 0) close(pagetable_fd);
108
109  return ret;
110 }