2013-06-10 32 views
8

Próbuję odcyfrować, jak użyć/proc/pid/pagemap, aby uzyskać adres fizyczny danego zestawu stron. Załóżmy, że z/proc/pid/maps otrzymuję adres wirtualny afa2d000-afa42000, który odpowiada kupie. Moje pytanie brzmi: w jaki sposób mogę użyć tych informacji do przechodzenia przez plik mapy stron i znaleźć fizyczne ramki strony odpowiadające adresowi afa2d000-afa42000.Jak odszyfrować/proc/pid/pagemap wpisy w systemie Linux?

Pozycja/proc/pid/pagemap ma format binarny. Czy są jakieś narzędzia pomocne w analizie tego pliku?

Odpowiedz

2

Spróbuj http://www.eqware.net/Articles/CapturingProcessMemoryUsageUnderLinux/ Można analizować pagemap dla Ciebie, na przykład, jeśli adres wirtualny jesteś zainteresowany jest w sterty, który jest 0x055468: = 0004c000-0005a000 rw-p 00000000 00:00 0 [ sterty] : 86000000000FD6D6 : 0600000000000000
: 0600000000000000
: 86000000000FE921
: 86000000000FE922
: 0600000000000000
: 86000000000FD5AD
: 86000000000FD6D4
: 86000000000FD5F8
: 86000000000FD5FA => 9-ta

Załóżmy rozmiaru strony 4KB i (0x055468 - 0x4c000) mod 4K = 9, Więc strona numer ramy swojej stronie 9. strona ramy ==>: 86000000000FD5FA Więc fizyczna PFN jest 0xFD5FA000 (wziąć ostatnie 55 bity i czasy rozmiar strony) plus offset: (0x055468 - 0x4c000 - 9 * 4K) = 0x468 ==> fizyczny addr jest 0xFD5FA000 + 0x468 = 0xFD5FA468

+0

Czy udało ci się skompilować page-analyse.cpp, pomijając brakujący #include Otrzymuję ten błąd kompilatora: 'page-analyze.cpp: W funkcji 'void make_short_name (char *, const char *)': page-analyze.cpp: 135: 35: błąd: przypisanie lokalizacji tylko do odczytu '* strchr (b, 93)' make: ** * [page-analyze] Error 1' – JohnnyFromBF

+0

Przykro mi, link na bok, odpowiedź sama w sobie ma sens, ale jest bardzo źle napisana przez IMO. Potrzebne formatowanie, źródło danych nie jest jasne/zademonstrowane ... także, że "mod" musi być "div" – nhed

1

dokumentacji jądra Linux

Linux kernel doc opisujące format: https://github.com/torvalds/linux/blob/v4.9/Documentation/vm/pagemap.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 

C funkcja analizatora składni

GitHub upstream.

#define _XOPEN_SOURCE 700 
#include <fcntl.h> /* open */ 
#include <stdint.h> /* uint64_t */ 
#include <stdlib.h> /* size_t */ 
#include <unistd.h> /* 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; 
} PagemapEntry; 

/* Parse the pagemap entry for the given virtual address. 
* 
* @param[out] entry  the parsed entry 
* @param[in] pagemap_fd file descriptor to an open /proc/pid/pagemap file 
* @param[in] vaddr  virtual address to get entry for 
* @return 0 for success, 1 for failure 
*/ 
int pagemap_get_entry(PagemapEntry *entry, int pagemap_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; 
} 

Przykład Runnable programy wykorzystujące go: