2017-06-18 140 views
0

我正試圖在Mac OS X上只使用syscalls編寫一個簡單的應用程序,沒有標準庫。Mac OS X上的mmap系統調用有什麼問題?

的main.c

#define PROT_READ 0x1 
#define PROT_WRITE 0x2 
#define MAP_ANONYMOUS 0x20 
#define MAP_PRIVATE 0x02 

#define PAGE_SIZE 4096 

#define NULL 0 

#define STDOUT 1 

#define SYSCALL_BASE 0x2000000 
#define SYSCALL_GET(num) SYSCALL_BASE + num 

long long syscall(long long arg1, long long arg2, long long arg3, long long arg4, long long arg5, long long arg6, long long cn); 

void exit(long long status) { 
    syscall(status, 0, 0, 0, 0, 0, SYSCALL_GET(1)); 
} 

long long write(long long fd, char *buf, long long len) { 
    return syscall(fd, buf, len, 0, 0, 0, SYSCALL_GET(4)); 
} 

void *mmap(void *addr, long long length, long long prot, long long flags, long long fd, long long offset) { 
    return syscall(addr, length, prot, flags, fd, offset, SYSCALL_GET(197)); 
} 

long long munmap(void *addr, long long length) { 
    return syscall(addr, length, 0, 0, 0, 0, SYSCALL_GET(73)); 
} 

int strlen(char *s) { 
    int len = 0; 
    while (*(s++) != '\0') { 
    len++; 
    } 
    return len; 
} 

int putchar(char c) { 
    return write(STDOUT, &c, 1); 
} 

int main(int argc, char *argv[]) { 
    if (argc <= 1) { 
    return 0; 
    } 

    int *lengths = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 

    for (int i = 1; i < argc; i++) { 
    lengths[i] = strlen(argv[i]); 
    } 

    for (int i = 1; i < argc; i++) { 
    write(STDOUT, argv[i], lengths[i]); 
    putchar(' '); 
    } 

    putchar('\n'); 

    munmap(lengths, PAGE_SIZE); 
    return 0; 
} 

的start.s

.global start 
.global _syscall 

.text 
start: 
popq %rdi 
movq %rsp, %rsi 
andq $0xfffffffffffffff0, %rsp 
call _main 
movq %rax, %rdi 
call _exit 

_syscall: 
movq %rcx, %r10 
movq 8(%rsp), %rax 
pushq %rbx # alignment 
syscall 
popq %rbx 
retq 

正如你所看到的,應用程序基本上反映了簡單echo。當我運行沒有參數的程序時,它成功完成,所以我假設exit調用工程。但是當我用任何參數運行它時,它會與Segmentation fault: 11崩潰。據我現在瞭解,當調用mmap時,內核返回奇怪的值:9.我認爲9不是正確的地址,但我不明白我的錯誤,因爲根據文檔,所有傳遞給syscall的值都是正確的。系統調用號碼取自here

+0

我認爲你得到的9是'errno'值,這將是'EBADF'。 –

回答