寻找 mmap 标志值

k3v*_*k3v 3 c x86 assembly mmap x86-64

我想知道在哪里可以找到 os x 上的 mmap 标志值。mmap 的联机帮助页说要使用 MAP_PRIVATE、MAP_... 等,但是如果您正在处理程序集,则必须知道进行系统调用的实际值。我试图寻找定义这些常量的头文件,但我找不到它。有人可以链接它吗?

Pet*_*des 5

首先找到正确的文件:两个选项:

  • 谷歌宏,并查看文档以查看它所说的包含哪些标题。例如,mmap手册页只提到了sys/mman.h.
  • 或者:了解您的系统保存头文件的位置,并在那里递归 grep。(或者使用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


使用 C 预处理器转储宏值。

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)