summaryrefslogtreecommitdiffstats
path: root/util/mainpfn.c
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2023-01-30 11:25:17 +0100
committerLouis Burda <quent.burda@gmail.com>2023-01-30 11:25:17 +0100
commit27ac7a95b69d70622f281c1b8d0300d38e5c541d (patch)
tree1bd563bdeb74beef328d11142f520b5c1d1bd26b /util/mainpfn.c
parent2ee037acfeb15bbea48422199e09ce9911dfe117 (diff)
downloadcachepc-27ac7a95b69d70622f281c1b8d0300d38e5c541d.tar.gz
cachepc-27ac7a95b69d70622f281c1b8d0300d38e5c541d.zip
Added mainpfn guest utility to determine rough pfn for userspace code
Diffstat (limited to 'util/mainpfn.c')
-rw-r--r--util/mainpfn.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/util/mainpfn.c b/util/mainpfn.c
new file mode 100644
index 0000000..17c1b18
--- /dev/null
+++ b/util/mainpfn.c
@@ -0,0 +1,51 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+struct pageinfo {
+ uint64_t pfn : 54;
+ unsigned int soft_dirty : 1;
+ unsigned int file_page : 1;
+ unsigned int swapped : 1;
+ unsigned int present : 1;
+};
+
+void
+pagemap_get_entry(struct pageinfo *entry, int fd, uintptr_t vaddr)
+{
+ uint64_t data;
+ size_t offset;
+
+ offset = (vaddr / sysconf(_SC_PAGE_SIZE)) * 8;
+ if (pread(fd, (void *) &data, 8, offset) != 8)
+ err(1, "pread");
+
+ entry->pfn = data & ((1ULL << 54) - 1);
+ entry->soft_dirty = (data >> 54) & 1;
+ entry->file_page = (data >> 61) & 1;
+ entry->swapped = (data >> 62) & 1;
+ entry->present = (data >> 63) & 1;
+}
+
+int
+main(int argc, const char **argv)
+{
+ char filepath[256];
+ struct pageinfo info;
+ pid_t pid;
+ int fd;
+
+ pid = getpid();
+ snprintf(filepath, sizeof(filepath), "/proc/%u/pagemap", pid);
+
+ fd = open(filepath, O_RDONLY);
+ if (!fd) err(1, "open");
+
+ pagemap_get_entry(&info, fd, (uintptr_t) main);
+ printf("PFN: %08lx\n", info.pfn);
+
+ close(fd);
+}