从 mmap 分配的地址转换函数——我不知道要使用哪个地址

cast a function from mmap allocated address -- I can't figure out which address to use

首先,为标题道歉,我真的不知道如何解释它。

我正在用 mmap 分配私有内存块,如下所示:

char *err = mmap(
    (void*) ( alloc_size * (1 << 20)),          // Map from the start of the 2^20th page
    4 * alloc_size,                     // for one page length
    PROT_READ |  PROT_WRITE | PROT_EXEC,
    34,                         // to a private block of hardware memory
    0,
    0
    );

( alloc_size1<<12 = 4096)

显然我可以像这样转换为函数指针 [typedef int (*foo)()]:

foo f = (foo)0x10000000
f();

系统找到地址,调用函数。但是当我尝试大于 4096 的东西时出现问题,即 1<<13 = 8192,它不再能找到有效的地址。请帮我弄清楚要使用的地址以及所有这些的实际工作原理。

Please help me figure out what address to use and how all of these really work.

不要试图找出要使用的地址。到目前为止,最简单和最便携的方法是mmap()选择,方法是传递一个空指针作为第一个参数:

void *p = mmap(
    NULL,                        // mmap chooses the address
    4 * alloc_size,              // length
    PROT_READ |  PROT_WRITE | PROT_EXEC,
    MAP_PRIVATE | MAP_ANONYMOUS, // visible only to this process; not backed by a file
    0,                           // n/a for MAP_ANONYMOUS
    0                            // n/a for MAP_ANONYMOUS
    );

至于

apparently I can cast to a function pointer [typedef int (*foo)()] like this:

foo f = (foo)0x10000000

,将指针性质隐藏在 typedef 后面是非常糟糕的形式,并且声明不提供原型的函数或函数指针类型是有问题的。否则,是的,你可以这样做,但是将整数转换为指针的结果是 implementation-defined,除了在一些不包括那个的狭窄情况下。如果您正在为一个独立的实现编写代码,那么这样做可能仍然有意义,否则就没有意义。

我想你是想把函数的地址匹配到映射内存的地址,但只要你依赖POSIX mmap,你也可以根据 POSIX 的规定,您可以将 void * 转换为函数指针:

int (*f)(void) = p;

总的来说,重点似乎是动态创建一个函数,然后调用它。请不要将我对您问题的回答视为对此类 activity 的任何宽恕。这是一个糟糕的想法,并且不受 ISO C 的支持。POSIX 语义提供了一种实现它的方法,但这绝不是一个好主意。