I'm having problems constructing the initial stack for the guest executable for Valgrind on macOS 12 Intel. This seemed to work OK for macOS 11 but I'm getting a bad 'apple' pointer on macOS 12.
The stack (constructed by Valgrind) looks like this
higher address +-----------------+ <- clstack_end
| |
: string table :
| |
+-----------------+
| NULL |
+-----------------+
| executable_path | (first arg to execve())
+-----------------+
| NULL |
- -
| envp |
+-----------------+
| NULL |
- -
| argv |
+-----------------+
| argc |
+-----------------+
| mach_header * | (dynamic only)
lower address +-----------------+ <- sp
| undefined |
: :
The problem that I'm having is with the executable path (or the apple pointer). This points to NULL. The actual pointer to the "executable=xxx" string is 16 bytes lower in memory.
The code for main starts with
Dump of assembler code for function main:
0x0000000100003a90 <+0>: push %rbp
0x0000000100003a91 <+1>: mov %rsp,%rbp
0x0000000100003a94 <+4>: sub $0x60,%rsp
0x0000000100003a98 <+8>: movl $0x0,-0x4(%rbp)
0x0000000100003a9f <+15>: mov %edi,-0x8(%rbp)
0x0000000100003aa2 <+18>: mov %rsi,-0x10(%rbp)
0x0000000100003aa6 <+22>: mov %rdx,-0x18(%rbp)
0x0000000100003aaa <+26>: mov %rcx,-0x20(%rbp)
That's the prefix, making space for locals, setting a local variable to 0 then getting the 4 arguments from main in edi, rsi, rdx and rcx as per the SYSV amd64 ABI.
I think that it is dyld that puts the apple pointer into rcx.
Can anyone tall me how dyld works out the address of the apple pointer?