UNIX Syscalls

Linux

Linux: i386 (INT 0x80)

 1 2 3 4 5 6 7 8 91011121314151617181920212223
.data
    .set .L_STDOUT,        1
    .set .L_SYSCALL_EXIT,  1
    .set .L_SYSCALL_WRITE, 4
    .L_message:
        .ascii "Hello, world!\n"
        .set .L_message_len, . - .L_message

.text
    .global _start
    _start:
        # write(STDOUT, message, message_len)
        mov $.L_SYSCALL_WRITE, %eax
        mov $.L_STDOUT,        %ebx
        mov $.L_message,       %ecx
        mov $.L_message_len,   %edx
        int $0x80

        # exit(0)
        mov $.L_SYSCALL_EXIT, %eax
        mov $0,               %ebx
        int $0x80

static linking

12345678
$ as --32 -o hello.o hello.s
$ ld -m elf_i386 -o hello hello.o
$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped
$ ./hello
Hello, world!
$

dynamic linking

 1 2 3 4 5 6 7 8 910111213
$ as --32 -o hello.o hello.s
$ ld -m elf_i386 -o hello hello.o \
   --dynamic-linker /lib/ld-linux.so.2 \
   -l:ld-linux.so.2
$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, not stripped
$ ldd hello
    /lib/ld-linux.so.2 (0x56614000)
    linux-gate.so.1 (0xf77ba000)
$ ./hello
Hello, world!
$

Linux: i386 (vDSO)

 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132
.extern __kernel_vsyscall

.data
    .set .L_STDOUT,        1
    .set .L_SYSCALL_WRITE, 4
    .set .L_SYSCALL_EXIT,  1
    .L_message:
        .ascii "Hello, world!\n"
        .set .L_message_len, . - .L_message

.text
    .global _start
    _start:
        call .L_get_pc_thunk.esi
        add  $_GLOBAL_OFFSET_TABLE_, %esi

        # write(STDOUT, message, message_len)
        mov  $.L_SYSCALL_WRITE, %eax
        mov  $.L_STDOUT,        %ebx
        mov  $.L_message,       %ecx
        mov  $.L_message_len,   %edx
        call *__kernel_vsyscall@GOT(%esi)

        # exit(0)
        mov  $.L_SYSCALL_EXIT, %eax
        mov  $0,            %ebx
        call *__kernel_vsyscall@GOT(%esi)

    .L_get_pc_thunk.esi:
        mov (%esp), %esi
        ret

dynamic linking

 1 2 3 4 5 6 7 8 9101112131415161718
$ echo '' | as --32 -o dummy_so.o
$ ld -m elf_i386 -shared -soname=linux-gate.so.1 -o dummy_so dummy_so.o

$ as --32 -o hello.o hello.s
$ ld -m elf_i386 -o hello hello.o \
   --defsym __kernel_vsyscall=0 \
   --dynamic-linker /lib/ld-linux.so.2 \
   -l:ld-linux.so.2 \
   dummy_so
$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, not stripped
$ ldd hello
    /lib/ld-linux.so.2 (0x56625000)
    linux-gate.so.1 (0xf77d5000)
$ ./hello
Hello, world!
$

Linux: x86-64

 1 2 3 4 5 6 7 8 91011121314151617181920212223
.data
    .set .L_STDOUT,        1
    .set .L_SYSCALL_EXIT,  60
    .set .L_SYSCALL_WRITE, 1
    .L_message:
        .ascii "Hello, world!\n"
        .set .L_message_len, . - .L_message

.text
    .global _start
    _start:
        # write(STDOUT, message, message_len)
        mov     $.L_SYSCALL_WRITE, %rax
        mov     $.L_STDOUT,        %rdi
        mov     $.L_message,       %rsi
        mov     $.L_message_len,   %rdx
        syscall

        # exit(0)
        mov     $.L_SYSCALL_EXIT, %rax
        mov     $0,               %rdi
        syscall

static linking

12345678
$ as --64 -o hello.o hello.s
$ ld -m elf_x86_64 -o hello hello.o
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
$ ./hello
Hello, world!
$

dynamic linking

 1 2 3 4 5 6 7 8 910111213
$ as --64 -o hello.o hello.s
$ ld -m elf_x86_64 -o hello hello.o \
   --dynamic-linker /lib64/ld-linux-x86-64.so.2 \
   -l:ld-linux-x86-64.so.2
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, not stripped
$ ldd hello
    /lib64/ld-linux-x86-64.so.2 (0x00007f472a831000)
    linux-vdso.so.1 (0x00007ffe83d7a000)
$ ./hello
Hello, world!
$

Darwin (MacOS X)

Darwin: i386

 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031
.macosx_version_min 10, 8

.data
    .set L_STDOUT,        1
    .set L_SYSCALL_EXIT,  1
    .set L_SYSCALL_WRITE, 4
    L_message:
        .ascii "Hello, world!\n"
        .set L_message_len, . - L_message

.text
    .global _main
    _main:
        mov %eax, %esi

        # write(STDOUT, message, message_len)
        push $L_message_len
        lea  L_message-_main(%esi), %eax
        push %eax
        push $L_STDOUT
        push $0 # stack padding
        mov  $L_SYSCALL_WRITE, %eax
        int  $0x80
        add  $16, %esp

        # exit(0)
        push $0 # exit code
        push $0 # stack padding
        mov  $L_SYSCALL_EXIT, %eax
        int  $0x80

dynamic linking

 1 2 3 4 5 6 7 8 91011
$ as -arch i386 -o hello.o hello.s
$ ld -arch i386 -macosx_version_min 10.8 -lSystem -o hello hello.o
$ file hello
hello: Mach-O executable i386
$ otool -L hello
hello:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)
$ ./hello
Hello, world!
$

Darwin: x86-64

 1 2 3 4 5 6 7 8 910111213141516171819202122232425
.macosx_version_min 10, 8

.data
    .set L_STDOUT,        1
    .set L_SYSCALL_EXIT,  0x2000001
    .set L_SYSCALL_WRITE, 0x2000004
    L_message:
        .ascii "Hello, world!\n"
        .set L_message_len, . - L_message

.text
    .global _main
    _main:
        # write(STDOUT, message, message_len)
        mov     $L_SYSCALL_WRITE, %rax
        mov     $L_STDOUT,        %rdi
        lea     L_message(%rip),  %rsi
        mov     $L_message_len,   %rdx
        syscall

        # exit(0)
        mov     $L_SYSCALL_EXIT, %rax
        mov     $0,              %rdi
        syscall

dynamic linking

 1 2 3 4 5 6 7 8 9101112
$ as -arch x86_64 hello.s -o hello.o
$ ld -arch x86_64 -o hello hello.o \
    -macosx_version_min 10.8 -lSystem
$ file hello
hello: Mach-O 64-bit executable x86_64
$ otool -L hello
hello:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)
$ ./hello
Hello, world!
$

FreeBSD

FreeBSD: i386

 1 2 3 4 5 6 7 8 91011121314151617181920212223242526
.data
    .set .L_STDOUT,        1
    .set .L_SYSCALL_EXIT,  1
    .set .L_SYSCALL_WRITE, 4
    .L_message:
        .ascii "Hello, world!\n"
        .set .L_message_len, . - .L_message

.text
    .global _start
    _start:
        # write(STDOUT, message, message_len)
        push $.L_message_len
        push $.L_message
        push $.L_STDOUT
        push $0 # stack padding
        mov  $.L_SYSCALL_WRITE, %eax
        int  $0x80
        add  $16, %esp

        # exit(0)
        push $0 # exit code
        push $0 # stack padding
        mov  $.L_SYSCALL_EXIT, %eax
        int  $0x80

static linking

12345678
$ as --32 -o hello.o hello.s
$ ld -m elf_i386_fbsd -o hello hello.o
$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), statically linked, not stripped
$ ./hello
Hello, world!
$

dynamic linking

 1 2 3 4 5 6 7 8 91011121314
$ as --32 -o hello.o hello.s
$ ld -m elf_i386_fbsd -o hello hello.o \
    --dynamic-linker=/libexec/ld-elf.so.1 \
    -L/libexec -l:ld-elf.so.1 \
    --hash-style=gnu
$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, not stripped
$ ldd hello
hello:
    /libexec/ld-elf.so.1 (0x2806e000)
$ ./hello
Hello, world!
$

FreeBSD: x86-64

 1 2 3 4 5 6 7 8 91011121314151617181920212223
.data
    .set L_STDOUT,        1
    .set L_SYSCALL_EXIT,  1
    .set L_SYSCALL_WRITE, 4
    L_message:
        .ascii "Hello, world!\n"
        .set L_message_len, . - L_message

.text
    .global _main
    _main:
        # write(STDOUT, message, message_len)
        mov     $L_SYSCALL_WRITE, %rax
        mov     $L_STDOUT,        %rdi
        mov     $L_message,       %rsi
        mov     $L_message_len,   %rdx
        syscall

        # exit(0)
        mov     $L_SYSCALL_EXIT, %rax
        mov     $0,              %rdi
        syscall

static linking

12345678
$ as --64 -o hello.o hello.s
$ ld -m elf_x86_64_fbsd -o hello hello.o
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), statically linked, not stripped
$ ./hello
Hello, world!
$

dynamic linking

 1 2 3 4 5 6 7 8 91011121314
$ as --64 -o hello.o hello.s
$ ld -m elf_x86_64_fbsd -o hello hello.o \
    --dynamic-linker=/libexec/ld-elf.so.1 \
    -L/libexec -l:ld-elf.so.1 \
    --hash-style=gnu
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, not stripped
$ ldd hello
hello:
    /libexec/ld-elf.so.1 (0x800822000)
$ ./hello
Hello, world!
$

SunOS 4.x (Solaris 1.x)

SunOS: SPARC v7

 1 2 3 4 5 6 7 8 91011121314151617181920212223
.seg "data"
    L_STDOUT        = 1
    L_SYSCALL_EXIT  = 1
    L_SYSCALL_WRITE = 4
    L_message:
        .ascii "Hello world!\n"
        L_message_len = . - L_message

.seg "text"
    .global _start
    _start:
        ! write(STDOUT, message, message_len)
        mov L_SYSCALL_WRITE, %g1
        mov L_STDOUT,        %o0
        set L_message,       %o1
        set L_message_len,   %o2
        ta  0

        ! exit(0)
        mov L_SYSCALL_EXIT, %g1
        mov 0,              %o0
        ta  0

static linking

 1 2 3 4 5 6 7 8 910
% as -o hello.o hello.s
% ld -e _start -o hello hello.o
% file hello
hello:          sparc demand paged executable not stripped
% ldd hello
hello: statically linked
% ./hello
Hello world!
%