我想知道在哪里可以找到os x上的mmap标志值。 mmap的联机帮助页说要使用MAP_PRIVATE,MAP _...等等,但是如果要处理汇编,则必须知道实际值以进行系统调用。我试着寻找定义这些常量的头文件,但我找不到它。有人可能会链接它吗?
答案 0 :(得分:2)
在gcc中使用-E
选项可以在预处理器之后查看源文件的输出。在以下源文件上使用gcc -E test.c
#include <sys/mman.h>
int main() {
return MAP_PRIVATE;
}
输出
...
# 2 "asdf.c" 2
int main() {
return 0x02;
}
表示MAP_PRIVATE
在我的系统上等于0x02
。但是,在所有系统上可能都不是这样。
答案 1 :(得分:1)
首先找到正确的文件:两个选项:
mmap
手册页仅提及sys/mman.h
。ack
, because it knows not to search binary files and is generally good for this sort of thing)。例如在我的GNU / Linux系统上,ack --hh MAP_PRIVATE /usr/include/ /usr/lib/gcc/x86_64-linux-gnu/5/
将仅搜索这两个目录下的.h
个文件(--hh
),这两个目录都是所有系统标头所在的目录。要查找系统首先保留标头的位置,cpp输出(不包括-dM
)包括当前行号设置行,它们会告诉您包含哪些标题。例如
# 216 "/usr/lib/gcc/x86_64-linux-gnu/5/include/stddef.h" 3 4
gcc -E -dM
只打印 #define
行,其中包含处理结束时所有宏的最终值,而不是预处理源。 -
告诉它从stdin读取,因此您可以使用echo
将代码片段传入其中。
echo '#include <sys/mman.h>' | gcc -E - -dM | less
在less
中,您当然可以使用/
进行搜索。 您还可以使用&
进行过滤,隐藏与正则表达式不匹配的行。因此,您可以键入&amp; MAP _ 以获取MAP_宏定义。
在x86-64 GNU / Linux上,我得到:
#define MAP_32BIT 0x40
#define MAP_TYPE 0x0f
#define MAP_EXECUTABLE 0x01000
#define MAP_FAILED ((void *) -1)
#define MAP_PRIVATE 0x02
...
如果您正在编写一些需要这些宏定义的实际asm代码,请记住gcc -c foo.S
在汇编之前通过C预处理器运行.S
个文件。但是,sys/mman.h
包含除宏定义之外的行(如typedef unsigned char __u_char;
),这些行不是有效的asm语法。
最具前瞻性/可移植性的方法可能是您的构建脚本/ Makefile使用gcc -E -dM
创建您需要的系统头的本地纯宏版本。然后,您的.S
文件可以#include "system_macros/mman.h"
,依此类推。
但是,请注意((void *) -1)
的{{1}}定义:该语法将无法汇编,因此这并不总是适用于编写可在具有相同ABI但不同常量的不同系统上工作的可移植asm和系统调用号码。
对于系统调用号,系统MAP_FAILED
通常只有宏,而不是原型或typedef。
您的asm来源应该如下所示:
asm/unistd.h
或者对于NASM,使用类似# 4th arg (flags) goes in r10 for the syscall ABI, vs. rcx for function calls
mov $(MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB), %r10d
的内容将cpp宏转换为NASM sed
定义:
.equ