首先找到正确的文件:两个选项:
mmap
手册页只提到了sys/mman.h
.ack
,因为它知道不搜索二进制文件并且通常对这类事情有好处)。例如,在我的 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
Run Code Online (Sandbox Code Playgroud)
在 中less
,您当然可以使用 进行搜索/
。 您还可以使用&
, 隐藏与正则表达式不匹配的行进行过滤。因此,您可以键入&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
...
Run Code Online (Sandbox Code Playgroud)
如果您正在编写一些需要这些宏定义的实际汇编代码,请记住在汇编之前通过 C 预处理器gcc -c foo.S
运行.S
文件。但是,sys/mman.h
包含typedef unsigned char __u_char;
不是有效 asm 语法的宏定义(如)以外的行。
执行此操作的最面向未来/可移植的方法可能是让您的构建脚本/Makefilegcc -E -dM
用于创建您需要的系统头文件的本地仅宏版本。然后你的.S
文件可以#include "system_macros/mman.h"
等等。
但是,请注意以下((void *) -1)
定义MAP_FAILED
:该语法不会组合,因此这并不总是适用于编写在具有相同 ABI 但不同常量和系统调用号的不同系统上工作的可移植 asm。
对于系统调用号,系统asm/unistd.h
通常只有宏,没有原型或类型定义。
你的 asm 源应该是这样的:
# 4th arg (flags) goes in r10 for the syscall ABI, vs. rcx for function calls
mov $(MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB), %r10d
Run Code Online (Sandbox Code Playgroud)
或者对于 NASM,使用类似sed
将 cpp 宏转换为 NASM.equ
定义的方法:
mov r10d, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB
Run Code Online (Sandbox Code Playgroud)