#include #include #include #include #include #include #include #include #define PADDR_MASK ((1UL << 54) - 1) #define INRAM_MASK ((1UL << 63)) #define PAGE_SIZE getpagesize() int main(int argc, char**argv){ if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return -1; } pid_t pid = atol(argv[1]); if (pid == 0) { fprintf(stderr, "Provided PID \"%s\" invalid\n", argv[1]); return -1; } char maps_file[PATH_MAX]; char pagemap_file[PATH_MAX]; snprintf(maps_file, sizeof(maps_file), "/proc/%d/maps", pid); snprintf(pagemap_file, sizeof(maps_file), "/proc/%d/pagemap", pid); FILE* maps_fp = fopen(maps_file, "r"); if (maps_fp == NULL) { fprintf(stderr, "Unable to open \"%s\"\n", maps_file); return -1; } FILE* pagemap_fp = fopen(pagemap_file, "r"); if (pagemap_fp == NULL) { fprintf(stderr, "Unable to open \"%s\"\n", pagemap_file); return -1; } while(1) { char buf[1024]; if (fgets(buf, sizeof(buf), maps_fp) == NULL){ // End of file break; } printf("\n%s", buf); unsigned long base; unsigned long limit; if (sscanf(buf, "%lx-%lx", &base, &limit) != 2) { fprintf(stderr, "Failed to parse line in maps file\n"); } else { printf("%18s | %18s | %s\n", "Virtual", "Physical", "Page table entry"); printf("------------------------------------------------------------\n"); for (; base < limit; base += PAGE_SIZE) { // Read the page table entry unsigned long page_number = base / PAGE_SIZE; uint64_t pte = 0; int err = fseek(pagemap_fp, page_number * sizeof(pte), SEEK_SET); if (err == -1) { fprintf(stderr, "Failed to seek to page number %lu in %s: %s\n", page_number, pagemap_file, strerror(errno)); continue; } size_t entries_read = fread(&pte, sizeof(pte), 1, pagemap_fp); if (entries_read != 1) { fprintf(stderr, "Failed to read page number %lu in %s: %s\n", page_number, pagemap_file, strerror(errno)); continue; } // Decode and report mappings printf("0x%016lx | ", base); bool in_ram = !!(pte & INRAM_MASK); if (in_ram) { uint64_t paddr = (pte & PADDR_MASK) * PAGE_SIZE; if (paddr == 0) { printf("%18s | ", "NULL"); } else { printf("0x%016lx | ", paddr); } } else { printf("%18s | ", "Not in RAM"); } printf("0x%016lx\n", pte); } } } return 0; }