¿Cómo decodificar / proc / pid / entradas de mapa de páginas en Linux?

Estoy tratando de descifrar cómo usar / proc / pid / pagemp para obtener la dirección física de un conjunto determinado de páginas. Supongamos que de los mapas / proc / pid /, obtengo la dirección virtual afa2d000-afa42000 que corresponde al montón. Mi pregunta es cómo utilizo esta información para atravesar el archivo de mapa de página y encontrar que los marcos de página físicos corresponden a la dirección afa2d000-afa42000.

La entrada / proc / pid / pagemp está en formato binario. ¿Hay alguna herramienta para ayudar a analizar este archivo?

    Pruebe esto http://www.eqware.net/Articles/CapturingProcessMemoryUsageUnderLinux/ Puede analizar el mapa de página para usted, por ejemplo, si la dirección virtual que le interesa está en el montón que es 0x055468: = 0004c000-0005a000 rw-p 00000000 00:00 0 [montón]: 86000000000FD6D6: 0600000000000000
    : 0600000000000000
    : 86000000000FE921
    : 86000000000FE922
    : 0600000000000000
    : 86000000000FD5AD
    : 86000000000FD6D4
    : 86000000000FD5F8
    : 86000000000FD5FA => 9º

    Supongamos que el tamaño de página es 4KB y (0x055468 – 0x4c000) mod 4K = 9, por lo que el número de fotogtwig de la página es la 9ª página fotogtwigs ==>: 86000000000FD5FA Por lo tanto, el físico pfn es 0xFD5FA000 (tome los últimos 55 bits y tiempos tamaño de página) más el desplazamiento: (0x055468 – 0x4c000 – 9 * 4K) = 0x468 ==> el código físico es 0xFD5FA000 + 0x468 = 0xFD5FA468

    Espero que este enlace te ayude. Es una herramienta muy simple, y determinar la dirección a la que necesita acceder es muy simple: http://fivelinesofcode.blogspot.com/2014/03/how-to-translate-virtual-to-physical.html

    Documentación del kernel de Linux

    Linux kernel doc que describe el formato: https://github.com/torvalds/linux/blob/v4.9/Documentation/vm/pagemp.txt

     * Bits 0-54 page frame number (PFN) if present * Bits 0-4 swap type if swapped * Bits 5-54 swap offset if swapped * Bit 55 pte is soft-dirty (see Documentation/vm/soft-dirty.txt) * Bit 56 page exclusively mapped (since 4.2) * Bits 57-60 zero * Bit 61 page is file-page or shared-anon (since 3.5) * Bit 62 page swapped * Bit 63 page present 

    Función del analizador C

    GitHub aguas arriba .

     #define _XOPEN_SOURCE 700 #include  /* open */ #include  /* uint64_t */ #include  /* size_t */ #include  /* pread, sysconf */ typedef struct { uint64_t pfn : 54; unsigned int soft_dirty : 1; unsigned int file_page : 1; unsigned int swapped : 1; unsigned int present : 1; } PagempEntry; /* Parse the pagemp entry for the given virtual address. * * @param[out] entry the parsed entry * @param[in] pagemp_fd file descriptor to an open /proc/pid/pagemp file * @param[in] vaddr virtual address to get entry for * @return 0 for success, 1 for failure */ int pagemp_get_entry(PagempEntry *entry, int pagemp_fd, uintptr_t vaddr) { size_t nread; ssize_t ret; uint64_t data; nread = 0; while (nread < sizeof(data)) { ret = pread(pagemap_fd, &data, sizeof(data), (vaddr / sysconf(_SC_PAGE_SIZE)) * sizeof(data) + nread); nread += ret; if (ret <= 0) { return 1; } } entry->pfn = data & (((uint64_t)1 < < 54) - 1); entry->soft_dirty = (data >> 54) & 1; entry->file_page = (data >> 61) & 1; entry->swapped = (data >> 62) & 1; entry->present = (data >> 63) & 1; return 0; } 

    Ejemplos de progtwigs ejecutables que lo utilizan:

    • convertir una dirección virtual a física: ¿Hay alguna API para determinar la dirección física de la dirección virtual en Linux?
    • volcar información sobre todas las páginas de un proceso: / proc / [pid] / pagemps y / proc / [pid] / maps | linux

    En caso de que la gente quiera hacer esto desde Rust, he agregado una implementación de Rust para que pueda navegar fácilmente /proc/$pid/maps y /proc/$pid/pagemp : https://crates.io/crates/vm- información