寻找mmap标志值

时间:2016-07-27 02:03:36

标签: c assembly x86 x86-64 mmap

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

2 个答案:

答案 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
  • 或者:了解系统保存头文件的位置,以及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),这两个目录都是所有系统标头所在的目录。

要查找系统首先保留标头的位置,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

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