9 static struct maps *alloc_map(void)
13 map = malloc(sizeof *map);
17 memset(map, 0, sizeof(*map));
18 INIT_LIST_HEAD(&map->list);
23 static struct maps *parse_maps(FILE *file)
25 struct maps *the_map = NULL;
29 while(fgets(line, sizeof(line), file)) {
30 struct maps *map = alloc_map();
31 unsigned long start, end;
40 ret = sscanf(line, "%lx-%lx %*s %*s %*s %*s %s",
43 printf("%x, start %lx, end %lx, str: %s\n",
44 ret, start, end, ret >= 3 ? name : "");
47 printf("Error reading input: %s\n", line);
53 map->size = end - start;
56 strncpy(map->name, name, sizeof(map->name));
58 list_add_tail(&map->list, &the_map->list);
64 static void clear_pageframe(struct pageframe *pf)
66 memset(pf, 0, sizeof(*pf));
69 static struct pageframe *alloc_pageframe(void)
71 struct pageframe *pageframe;
73 pageframe = malloc(sizeof *pageframe);
74 if (pageframe == NULL)
77 clear_pageframe(pageframe);
82 #define BITRANGE(first, last) (((2ll << (last - first)) - 1) << first)
84 static void pageframe_to_struct(unsigned long long p, struct pageframe *pf)
86 pf->page_present = !!(BITRANGE(63, 63) & p);
87 pf->page_swapped = !!(BITRANGE(62, 62) & p);
88 pf->page_shift = (BITRANGE(55, 60) & p) << 55;
89 pf->pfn = (BITRANGE(0, 54) & p);
91 printf("pfn: %lx shift: %x present: %d swapped %d\n",
92 pf->pfn, pf->page_shift, pf->page_present, pf->page_swapped);
95 static int compare_pageframe(struct bintree *at, struct bintree *bt)
97 struct pageframe *a, *b;
98 a = tree_to_pageframe(at);
99 b = tree_to_pageframe(bt);
101 return a->pfn - b->pfn;
104 struct bintree_ops pageframe_ops = {
105 .compare = compare_pageframe,
108 /* Read data from the /proc/pid/pagemap file */
109 static int parse_pageframe(FILE *file, struct pageframe **pageframe_tree,
112 struct maps *map, *tmp;
113 struct pageframe *match, *pageframe = alloc_pageframe();
115 unsigned long long pf;
118 /* Go through the list of allocated memory areas */
119 list_for_each_entry(map, &maps->list, list) {
120 start = map->start >> (PAGE_SHIFT - 3);
121 len = map->size >> (PAGE_SHIFT - 3);
123 printf("start: %lx len %lx: name: %s\n",
124 start, len, map->name);
126 ret = fseek(file, start, SEEK_SET);
129 fprintf(stderr, "Error seeking to %lx: %s\n", start,
135 for (i = 0; i < len; i++) {
136 ret = fread(&pf, 1, sizeof(pf), file);
137 if (ret != sizeof(pf)) {
140 "Error reading %ld bytes, got %d: %s\n",
141 sizeof(pf), ret, strerror(errno));
146 pageframe_to_struct(pf, pageframe);
147 match = tree_to_pageframe(
148 bintree_add(&(*pageframe_tree)->tree,
149 &pageframe->tree, &pageframe_ops));
151 if (*pageframe_tree == NULL)
152 *pageframe_tree = match;
155 * Add a link from the physical page to this
159 match->maps = alloc_map();
161 INIT_LIST_HEAD(&match->maps->list);
165 list_add(&match->maps->list, &tmp->list);
173 struct pageframe *read_pageframe(int pid, struct pageframe *pageframe)
180 snprintf(path, sizeof(path), "/proc/%d/maps", pid);
181 file = fopen(path, "rb");
186 maps = parse_maps(file);
188 snprintf(path, sizeof(path), "/proc/%d/pagemap", pid);
189 file = fopen(path, "rb");
194 parse_pageframe(file, &pageframe, maps);
199 fprintf(stderr, "Failed to open file %s: %s\n", path, strerror(error));