0

I understand that the used address space of 64-bit PCs is [0,2^48), but can I use mmap to map a file to an address above 248?

I wrote the following code but found out the mapped address was still inside [0,2^48).

int
main(void) {
    const char* name = "/tmp/file";

    int fd = open(name, O_RDONLY);
    if (fd < 0) {
        perror("open");
        exit(-1);
    }

    int pageSize = sysconf(_SC_PAGE_SIZE);
    void* targetAddr = (void*)(0UL - pageSize);

    char* str = mmap(targetAddr, pageSize, PROT_READ, MAP_SHARED, fd, 0);
    if (str == MAP_FAILED) {
        perror("mmap");
        exit(-1);
    }

    printf("addr: %p\n", str);

    return 0;
}

Sample output: addr: 0x7fc761f6f000

Is it even possible to map some file to address above 248 with mmap?

If not, how can I make use of the "unused" bit48-bit63?

I am just curious how to make use of the higher bits of the address.

OS: Ubuntu16.04

MemSize: 4GB

Stephen Kitt
  • 434,908
z.h.
  • 994
  • What architecture? From context, it looks like x86_64 (aka amd64), which doesn't normally have user-addressable memory in that part of the address space. – Toby Speight May 14 '19 at 12:53
  • @TobySpeight Yes, it's x86_64. Indeed, those bits are reserved by the os and should follow certain convention. – z.h. May 14 '19 at 13:12
  • Also, on that platform, the range between 0000ffffffffffff and ffff00000000 is reserved by the CPU (it's a trap representation). – Toby Speight May 14 '19 at 13:20

1 Answers1

1

You can only map anything above 248 if you’ve enabled five-level page tables, which gives you 56 bits of virtual address space, or if you’re in the kernel (which uses the top half of the address space).

Note that the bits above the “used” bits aren’t unused, they’re reserved, and must be equal to the top-most used bit. x86-64 defines a canonical form, where user space has addresses starting with all-zero bits, and kernel space has addresses starting with all-one bits. See also the kernel’s memory map.

Stephen Kitt
  • 434,908