diff options
author | Tony Luck <tony.luck@intel.com> | 2014-03-18 09:41:25 -0700 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2014-03-18 09:41:25 -0700 |
commit | 73ad3885126b2e15d757594d6c693d9b9ac37b36 (patch) | |
tree | 7994e75497dff8faee2d2738fca84b2ee581c00d | |
parent | de00752da7c655798bc87d0a4f52af236829c55d (diff) | |
download | ras-tools-73ad3885126b2e15d757594d6c693d9b9ac37b36.tar.gz |
Add vtop.c - for finding physical address in arbitrary process.
-rwxr-xr-x | vtop.c | 81 |
1 files changed, 81 insertions, 0 deletions
@@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 Intel Corporation + * Authors: Tony Luck + * + * This software may be redistributed and/or modified under the terms of + * the GNU General Public License ("GPL") version 2 only as published by the + * Free Software Foundation. + */ + +/* + * Given a process if and virtual address, dig around in + * /proc/id/pagemap to find the physical address (if present) + * behind the virtual one. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <time.h> +#include <signal.h> +#include <sys/mman.h> + +static int pagesize=0x1000; + +/* + * get information about address from /proc/{pid}/pagemap + */ + +unsigned long long vtop(unsigned long long addr, int proc_id) +{ + unsigned long pinfo; + + int fd; + char pagemapname[64]; + long offset; + + offset = addr / pagesize * (sizeof pinfo); + + /* sprintf(pagemapname, "/proc/%d/pagemap", getpid()); */ + sprintf(pagemapname, "/proc/%d/pagemap",proc_id); + + fd = open(pagemapname, O_RDONLY); + if (fd == -1) { + perror(pagemapname); + exit(1); + } + if (pread(fd, &pinfo, sizeof pinfo, offset) != sizeof pinfo) { + perror(pagemapname); + exit(1); + } + close(fd); + if ((pinfo & (1ull << 63)) == 0) { + printf("page not present\n"); + exit(1); + } + return ((pinfo & 0x007fffffffffffffull) << 12) + (addr & (pagesize - 1)); +} + +int main(int argc, char **argv) +{ + int process_id; + unsigned long long buf, phys; + + if(argc < 2) { + printf("require virtual address and pid: 'vtop vaddress pid'\n"); + return 1; + } + + pagesize = getpagesize(); + buf = strtoul(argv[1], NULL, 16); + + process_id = atol(argv[2]); + + phys = vtop(buf, process_id); + + printf("vtop(%llx,%d) = %llx\n", buf, process_id, phys); + + return 0; +} |