nemasu / asmttpd

Web server for Linux written in amd64 assembly.
GNU General Public License v2.0
3.02k stars 200 forks source link

if you want to port on Mac OS : Syscall #6

Open smougel opened 10 years ago

smougel commented 10 years ago

http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/kern/syscalls.master

nemasu commented 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?

DavidJFelix commented 10 years ago

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.

nickdesaulniers commented 9 years ago

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.

nickdesaulniers commented 9 years ago

syscall IDs used:

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??

nickdesaulniers commented 9 years ago

I think we should use the preprocessor to check for OS specific symbols and have conditional assembling. example

nickdesaulniers commented 8 years ago

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/

nickdesaulniers commented 8 years ago

I'm able to get the usage warning printing! w00t

nickdesaulniers commented 8 years ago

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.

nemasu commented 8 years ago

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.

nickdesaulniers commented 8 years ago

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

nickdesaulniers commented 8 years ago

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?

nemasu commented 8 years ago

According to the AMD64 ABi doc, http://www.x86-64.org/documentation/abi.pdf, page 29, argv and argc are passed on the stack.

nickdesaulniers commented 8 years ago

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.

nickdesaulniers commented 8 years ago

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.

nickdesaulniers commented 8 years ago

For my reference, man syscall and /usr/include/sys/syscall.h are helpful!

nickdesaulniers commented 8 years ago

Looks like _start is defined in /usr/lib/crt1.o, which should be linked against, according to man 1 ld.

nickdesaulniers commented 8 years ago

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.

nickdesaulniers commented 8 years ago

pthread_create:

pthread_join:

nickdesaulniers commented 8 years ago

proc_info bsdthread_create

DmitryHetman commented 7 years ago

gcc on mac works, so you can use as as assembler.

DmitryHetman commented 7 years ago

as - Portable GNU assembler.

nickdesaulniers commented 7 years ago

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. :(