2017-06-18 9 views
0

J'essaye d'écrire une application simple sur Mac OS X en utilisant seulement des syscalls, aucune bibliothèque standard.Quel est le problème avec l'appel système mmap sur Mac OS X?

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 

Comme vous pouvez le voir, l'application reflète fondamentalement simple echo. Lorsque je cours le programme sans arguments, il se termine avec succès, donc je suppose que fonctionne exit. Mais quand je l'exécute avec n'importe quel argument, il se bloque avec Segmentation fault: 11. Si je comprends bien maintenant, quand mmap est appelé, le noyau renvoie une valeur étrange: 9. Je suppose que 9 n'est pas une adresse correcte, mais je ne comprends pas mon erreur, car selon les documentations, toutes les valeurs passées à syscall sont correctes . Les numéros Syscall sont tirés de here.

+0

Je pense que le 9 vous obtenez est la valeur 'de errno', qui serait' EBADF'. –

Répondre