从 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_size
是 1<<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 语义提供了一种实现它的方法,但这绝不是一个好主意。
首先,为标题道歉,我真的不知道如何解释它。
我正在用 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_size
是 1<<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 语义提供了一种实现它的方法,但这绝不是一个好主意。