17.12.2.1.3. pagemap_dump.out
Dump the physical address of all pages mapped to a given process using /proc/<pid>/maps and /proc/<pid>/pagemap.
First launch linux/virt_to_phys_user.out as described at Userland physical address experiments. Suppose that the output was:
# ./posix/virt_to_phys_test.out & vaddr 0x601048 pid 63 # ./linux/virt_to_phys_user.out 63 0x601048 0x1a61048
Now obtain the page map for the process:
./linux/pagemap_dump.out 63
Sample output excerpt:
vaddr pfn soft-dirty file/shared swapped present library 400000 1ede 0 1 0 1 ./posix/virt_to_phys_test.out 600000 1a6f 0 0 0 1 ./posix/virt_to_phys_test.out 601000 1a61 0 0 0 1 ./posix/virt_to_phys_test.out 602000 2208 0 0 0 1 [heap] 603000 220b 0 0 0 1 [heap] 7ffff78ec000 1fd4 0 1 0 1 /lib/libuClibc-1.0.30.so
Source:
Adapted from: https://github.com/dwks/pagemap/blob/8a25747bc79d6080c8b94eac80807a4dceeda57a/pagemap2.c
Meaning of the flags:
-
vaddr: first virtual address of a page the belongs to the process. Notably:./run-toolchain readelf -- -l "$(./getvar userland_build_dir)/posix/virt_to_phys_test.out"
contains:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align ... LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x000000000000075c 0x000000000000075c R E 0x200000 LOAD 0x0000000000000e98 0x0000000000600e98 0x0000000000600e98 0x00000000000001b4 0x0000000000000218 RW 0x200000 Section to Segment mapping: Segment Sections... ... 02 .interp .hash .dynsym .dynstr .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 03 .ctors .dtors .jcr .dynamic .got.plt .data .bssfrom which we deduce that:
-
400000is the text segment -
600000is the data segment
-
-
pfn: add three zeroes to it, and you have the physical address.Three zeroes is 12 bits which is 4kB, which is the size of a page.
For example, the virtual address
0x601000haspfnof0x1a61, which means that its physical address is0x1a61000This is consistent with what
linux/virt_to_phys_user.outtold us: the virtual address0x601048has physical address0x1a61048.048corresponds to the three last zeroes, and is the offset within the page.Also, this value falls inside
0x601000, which as previously analyzed is the data section, which is the normal location for global variables such as ours. -
soft-dirty: TODO -
file/shared: TODO.1seems to indicate that the page can be shared across processes, possibly for read-only pages? E.g. the text segment has1, but the data has0. -
swapped: TODO swapped to disk? -
present: TODO vs swapped? -
library: which executable owns that page
This program works in two steps:
-
parse the human readable lines lines from
/proc/<pid>/maps. This files contains lines of form:7ffff7b6d000-7ffff7bdd000 r-xp 00000000 fe:00 658 /lib/libuClibc-1.0.22.so
which tells us that:
-
7f8af99f8000-7f8af99ff000is a virtual address range that belong to the process, possibly containing multiple pages. -
/lib/libuClibc-1.0.22.sois the name of the library that owns that memory
-
-
loop over each page of each address range, and ask
/proc/<pid>/pagemapfor more information about that page, including the physical address