Mac 64位系统调用

3

如何在Mac上使用C++执行64位syscall

我需要使以下内容正常工作:

#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>

int main() {
  long* addr = (long*) syscall(SYS_mmap, 0, 100, 1 | 2, 2 | 4096, -1, 0);
}

问题在于下面的addr应该是64位的指针,但它将结果截断为32位值。
我使用以下编译方式:
g++ ./mmap.cc -o ./mmap 

附言:我知道存在mmap函数,上面只是一个例子,我需要让syscall函数正常工作。

另外,问题在于在64位系统上,syscall应该返回64位值,但在Mac的unistd.h中它被定义为int

int  syscall(int, ...);

这是一个bug吗?mmap系统调用正确地返回了void*

void *  mmap(void *, size_t, int, int, int, off_t) __DARWIN_ALIAS(mmap);

请问 "mmap" 的实际实现过程是怎样的?

P.P.P.S.

在 Linux 上,只要正确定义,就可以使用它:

long syscall(long number, ...);

您没有收到编译器警告,指出 syscall() 已过时吗?在 unistd.h 中的函数声明已经被标记为过时属性,并包含语句“syscall(2) 不受支持,请切换到受支持的接口。”您正试图做的事情在 macOS 上是明确不受支持的。此外,苹果公司已经解释说,库接口(例如 mmap() 等函数)是 ABI 兼容接口,直接系统调用不能保证跨操作系统更新后仍然可用或兼容。 - Ken Thomases
@KenThomases 我知道这些,你知道如何执行64位的syscall而不使用汇编吗? - Vad
2个回答

7

经过搜索,我没有找到在Mac上执行64位系统调用的方法。

因此,我自己实现了这些功能,您可以在这里找到函数

另外,如果您使用这些功能,请不要忘记将0x2000000 Unix系统调用类偏移添加到您的系统调用号码中:

int SYS_write = 4;
int STDOUT = 1;
char* str = "Hello world\n";

syscall3(0x2000000 + SYS_write, STDOUT, str, 12);

4

如Ken Thomases指出,syscall函数在OS X上已经被弃用。

对于你的具体例子,你应该使用mmap而不是syscallmmap函数不是基于syscall函数实现的,而是基于__mmap函数实现的:

libsystem_kernel.dylib`mmap:
    0x7fff643fa69e <+87>:  callq  0x7fff643fe998            ; __mmap

这个函数实际上会执行系统调用,很可能是用汇编语言实现的:

libsystem_kernel.dylib`__mmap:
    0x7fff643fe998 <+0>:  movl   $0x20000c5, %eax          ; imm = 0x20000C5
    0x7fff643fe99d <+5>:  movq   %rcx, %r10
    0x7fff643fe9a0 <+8>:  syscall
    0x7fff643fe9a2 <+10>: jae    0x7fff643fe9ac            ; <+20>

就像我之前说的,mmap只是一个例子。所以,我可以这样说,Mac基本上没有正确实现syscall函数,我需要自己来实现吗? - Vad
据我所知,如果您需要一个64位的返回值,那么您将不得不编写自己的函数。 - vitaut

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接