Open smougel opened 10 years ago
Thanks. I don't have a mac at the moment, so it could be a while. Is there a cross assembler or some sort of development environment for mac that will work on Linux?
nasm -f macho -o output
should create a mach-o style binary. GNU assembler/linker should be able to do this if the option wasn't disabled by your distro (some do this to save space on the binary). As long as the mac is the same micro-architecture as where you're developing it, you should be able to create binaries with just a change of format, not a cross compiler.
I was hacking on this a little, I'll upstream some of my patches. The first step was to get everything to build, which I have.
name | Linux | Apple | same fn signature |
---|---|---|---|
write | 1 | 4 | :white_check_mark: |
open | 2 | 5 | :white_check_mark: |
close | 3 | 6 | :white_check_mark: |
lseek | 8 | 199 | |
mmap | 9 | 197 | |
sigaction | 13 | 46 | :white_check_mark: |
select | 23 | 93 | |
nanosleep | 35 | 334? | |
sendfile | 40 | 337 | |
socket | 41 | 97 | |
accept | 43 | 30 | |
sendto | 44 | 133 | |
recvfrom | 45 | 29 | |
bind | 49 | 104 | |
listen | 50 | 106 | |
setsockopts | 54 | 105 | |
clone | 56 | 360? | |
exit | 60 | 1 | |
getdents | 78 | 196? | |
exit_group | 231 | :x: |
note getdents defined but not used??
I think we should use the preprocessor to check for OS specific symbols and have conditional assembling. example
looks like the system call number need to be shifted. I have verified this, will try to find more info as to why: https://filippo.io/making-system-calls-from-assembly-in-mac-os-x/ edit: see also: http://dustin.schultz.io/blog/2010/11/15/mac-os-x-64-bit-assembly-system-calls/
I'm able to get the usage warning printing! w00t
does linux pass command line args on the stack? https://github.com/nemasu/asmttpd/blob/master/main.asm#L53-L58
When I inspect the registers on entry, %rdi is argc and %rsi is argv. The current code looks like it pulls them off the stack. Calling print_line with start_text blows away %rdi and %rsi.
argv and argc are passed on the stack.
But for Linux system calls it uses registers first, then stack:
https://github.com/nemasu/asmttpd/blob/master/main.asm#L28
Which is what I use internally too.
argv and argc are passed on the stack.
right, but it doesn't look to be the case for Mach-O binaries. Asking an friend who's an LLVM dev to confirm.
I'll need this for OSX's equivalent to nanosleep: https://opensource.apple.com/source/Libc/Libc-583/gen/nanosleep.c
err, they're passed on the stack for 32b programs on Linux/OSX and in %rdi and %rsi for 64b programs.
The makefile makes it looks like you're compiling a 64b binary, so why are argc/argv being popped off the stack?
According to the AMD64 ABi doc, http://www.x86-64.org/documentation/abi.pdf, page 29, argv and argc are passed on the stack.
If we take a look at the dissasembly on OSX:
Disassembly of section .text:
0000000100000f60 <_main>:
#include <stdio.h>
int main (int argc, char** argv) {
100000f60: 55 push %rbp
100000f61: 48 89 e5 mov %rsp,%rbp
puts(argv[0]);
100000f64: 48 8b 3e mov (%rsi),%rdi [hello! taking argv[0] from %rsi and putting in %rdi for puts]
100000f67: e8 04 00 00 00 callq 100000f70 <_main+0x10>
100000f6c: 31 c0 xor %eax,%eax
}
even on Linux:
00000000004004f0 <main>:
#include <stdio.h>
int main (int argc, char** argv) {
puts(argv[0]);
4004f0: 50 push %rax
4004f1: 48 8b 3e mov (%rsi),%rdi [SAME!!]
4004f4: e8 c7 fe ff ff callq 4003c0 <puts@plt>
4004f9: 31 c0 xor %eax,%eax
}
Unless _start is pulling things off the stack and into registers before calling into _main.
Unless _start is pulling things off the stack and into registers before calling into _main.
That MUST be the case. Without the -osx_min_version
flag to ld, arguments are indeed passed on stack to _start. Ok, I'll carry on.
For my reference, man syscall
and /usr/include/sys/syscall.h
are helpful!
Looks like _start is defined in /usr/lib/crt1.o
, which should be linked against, according to man 1 ld
.
I've got a lot more of this working. The real work will be pthread_create (processes and threads are created with clone(2) on Linux, not so on OSX), and nanosleep (nanosleep(2) on Linux, __semwait_signal on OSX). I think I'll need to link against libc for OSX to get the address of clock_sem.
pthread_create:
pthread_join:
gcc on mac works, so you can use as as assembler.
as - Portable GNU assembler.
What is your point? Both comments seem unrelated. See my comment about nanosleep and clone. Also, I sold off my last piece of Mac hardware, so I will no longer be pursuing this issue. :(
http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/kern/syscalls.master