How to execute a 64-bit syscall
on Mac in C++.
I need the below to work:
#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);
}
The problem is that addr
below should be 64-bit as it is a pointer, but it truncates the result to 32-bit value.
I compile with:
g++ ./mmap.cc -o ./mmap
P.S. I know there exists mmap
function, the above is just an example, I need to get syscall
function to work.
P.P.S. The problem is that on 64-bit systems syscall
should return 64-bit value, but in Mac unistd.h
it is defined as int
:
int syscall(int, ...);
Is that a bug? The mmap
system call return correctly void*
:
void * mmap(void *, size_t, int, int, int, off_t) __DARWIN_ALIAS(mmap);
How is mmap
actually implemented?
P.P.P.S.
On Linux it is defined correctly as long:
long syscall(long number, ...);
After some searching I did not find a way to execute 64-bit system calls on Mac.
So, I implemented those myself, you can find the functions here.
Also, if you use those functions don't forget to add 0x2000000
Unix system call class shift to your system call numbers:
int SYS_write = 4;
int STDOUT = 1;
char* str = "Hello world\n";
syscall3(0x2000000 + SYS_write, STDOUT, str, 12);
The syscall
function is deprecated on OS X as Ken Thomases pointed out.
For your specific example, you should use mmap
instead of syscall
. The mmap
function is not implemented in terms of the syscall
function but in terms of __mmap
:
libsystem_kernel.dylib`mmap:
0x7fff643fa69e <+87>: callq 0x7fff643fe998 ; __mmap
which, in turn, does the actual syscall and is probably implemented in assembly:
libsystem_kernel.dylib`__mmap:
0x7fff643fe998 <+0>: movl $0x20000c5, %eax ; imm = 0x20000C5
0x7fff643fe99d <+5>: movq %rcx, %r10
0x7fff643fe9a0 <+8>: syscall
0x7fff643fe9a2 <+10>: jae 0x7fff643fe9ac ; <+20>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With