Linux 中的虚拟地址转换

Linux 中的虚拟地址转换

我尝试将虚拟地址转换为物理地址。我可以翻译下面的地址。

00400000-00401000 r-xp 00000000 103:04 14292394  /home/user/readMaps
00600000-00601000 r--p 00000000 103:04 14292394  /home/user/readMaps
00601000-00602000 rw-p 00001000 103:04 14292394  /home/user/readMaps
00602000-00623000 rw-p 00000000 00:00 0          [heap]

但以下地址未能翻译。

7ffff7a0d000-7ffff7bcd000 r-xp 00000000 103:04 1970900 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7bcd000-7ffff7dcd000 ---p 001c0000 103:04 1970900 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7dcd000-7ffff7dd1000 r--p 001c0000 103:04 1970900 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7dd1000-7ffff7dd3000 rw-p 001c4000 103:04 1970900 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7dd3000-7ffff7dd7000 rw-p 00000000 00:00 0 
7ffff7dd7000-7ffff7dfd000 r-xp 00000000 103:04 1970872 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7fdb000-7ffff7fde000 rw-p 00000000 00:00 0
7ffff7ff7000-7ffff7ffa000 r--p 00000000 00:00 0        [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0        [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00025000 103:04 1970872 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffd000-7ffff7ffe000 rw-p 00026000 103:04 1970872 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0         [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]

地址区域有区别吗?或者我用另一种方式来翻译它吗?

这是我的翻译代码。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>

#define O_RDONLY 0x0000

int main(int argc, char* argv[]) {  

    if(argv[1]==NULL) {
        printf("No Virtual Address...\n");
        return 1;
    }

    if(argv[2]==NULL) {
        printf("No PID...\n");
        return 2;
    }

    char* fileName = malloc(sizeof(char)*25);    
    size_t virtualAddress = strtoull(argv[1], NULL, 0);
    char* processNum = argv[2];
    sprintf(fileName, "/proc/%s/pagemap", processNum);

    static int pagemap = -1;
    if (pagemap == -1) {
        pagemap = open(fileName, O_RDONLY);
        if (pagemap < 0) {
            printf("page map error\n");
            errno = EPERM;
            return 1;
        }
    }
    //printf("pagemap : %d\n", pagemap);

    uint64_t value;
    int got = 0;
    got = pread(pagemap, &value, 8, (virtualAddress / 0x1000) * 8);

    if(got != 8) {
        printf("pread error\n");
        errno = EPERM;
        return 0;
    }

    uint64_t pageFrameNumber = value & ((1ULL << 54) - 1); 

    if(pageFrameNumber == 0) {
        printf("page frame number error\n");
        errno = EPERM;
        return 0;
    }

    printf("Result : %p\n", pageFrameNumber * 0x1000 + virtualAddress % 0x1000);

    return 0;
}

相关内容