寻找 mmap 标志值
Looking for mmap flag values
我想知道在哪里可以找到 os x 上的 mmap 标志值。 mmap 的联机帮助页说要使用 MAP_PRIVATE、MAP_... 等等,但是如果您正在处理程序集,则必须知道进行系统调用的实际值。我试图寻找定义这些常量的头文件,但找不到。有人 link 可以 possibly 吗?
在 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
。然而,并非所有系统都如此。
首先找到正确的文件:两个选项:
- google 宏,并查看文档以了解它说要包含的 header 内容。例如
mmap
手册页仅提及 sys/mman.h
.
- 或者:了解您的系统在哪里保存 header 文件,recursive-grep 在那里。 (或使用
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
),这是所有系统 header 所在的目录。
要首先找到系统保留 headers 的位置,cpp 输出(不带 -dM
)包括 current-line-number 设置行,告诉您哪些 headers包括在内。例如
# 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
在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
...
也许在构建系统中使用它而不是 hard-coding 您的搜索结果
如果您正在编写一些需要这些宏定义的实际 asm 代码,请记住 gcc -c foo.S
在汇编之前通过 C 预处理器运行 .S
文件。但是,sys/mman.h
包含宏定义以外的行(如 typedef unsigned char __u_char;
),这些行不是有效的 asm 语法。
最future-proof/可移植的方法可能是您的构建脚本/Makefile 使用gcc -E -dM
创建本地macro-only你需要的系统版本headers。然后你的 .S
文件可以 #include "system_macros/mman.h"
等等。
但是,请注意 MAP_FAILED
的 ((void *) -1)
定义:该语法不会 assemble,因此这并不总是适用于编写可在不同系统上运行的可移植 asm相同的 ABI 但不同的常量和系统调用编号。
对于系统调用号,系统asm/unistd.h
通常只有宏,没有原型或typedef。
你的 asm 源应该是这样的:
# 4th arg (flags) goes in r10 for the syscall ABI, vs. rcx for function calls
mov $(MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB), %r10d
或者对于 NASM,使用类似 sed
的东西将 cpp 宏转换为 NASM .equ
定义:
mov r10d, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB
我想知道在哪里可以找到 os x 上的 mmap 标志值。 mmap 的联机帮助页说要使用 MAP_PRIVATE、MAP_... 等等,但是如果您正在处理程序集,则必须知道进行系统调用的实际值。我试图寻找定义这些常量的头文件,但找不到。有人 link 可以 possibly 吗?
在 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
。然而,并非所有系统都如此。
首先找到正确的文件:两个选项:
- google 宏,并查看文档以了解它说要包含的 header 内容。例如
mmap
手册页仅提及sys/mman.h
. - 或者:了解您的系统在哪里保存 header 文件,recursive-grep 在那里。 (或使用
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
),这是所有系统 header 所在的目录。
要首先找到系统保留 headers 的位置,cpp 输出(不带 -dM
)包括 current-line-number 设置行,告诉您哪些 headers包括在内。例如
# 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
在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
...
也许在构建系统中使用它而不是 hard-coding 您的搜索结果
如果您正在编写一些需要这些宏定义的实际 asm 代码,请记住 gcc -c foo.S
在汇编之前通过 C 预处理器运行 .S
文件。但是,sys/mman.h
包含宏定义以外的行(如 typedef unsigned char __u_char;
),这些行不是有效的 asm 语法。
最future-proof/可移植的方法可能是您的构建脚本/Makefile 使用gcc -E -dM
创建本地macro-only你需要的系统版本headers。然后你的 .S
文件可以 #include "system_macros/mman.h"
等等。
但是,请注意 MAP_FAILED
的 ((void *) -1)
定义:该语法不会 assemble,因此这并不总是适用于编写可在不同系统上运行的可移植 asm相同的 ABI 但不同的常量和系统调用编号。
对于系统调用号,系统asm/unistd.h
通常只有宏,没有原型或typedef。
你的 asm 源应该是这样的:
# 4th arg (flags) goes in r10 for the syscall ABI, vs. rcx for function calls
mov $(MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB), %r10d
或者对于 NASM,使用类似 sed
的东西将 cpp 宏转换为 NASM .equ
定义:
mov r10d, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB