Recently I was playing with freebsd system calls I had no problem for i386 part since its well documented at here. But i can't find same document for x86_64.
I saw people are using same way like on linux but they use just assembly not c. I suppose in my case system call actually changing some register which is used by high optimization level so it gives different behaviour.
/* for SYS_* constants */ #include <sys/syscall.h> /* for types like size_t */ #include <unistd.h> ssize_t sys_write(int fd, const void *data, size_t size){ register long res __asm__("rax"); register long arg0 __asm__("rdi") = fd; register long arg1 __asm__("rsi") = (long)data; register long arg2 __asm__("rdx") = size; __asm__ __volatile__( "syscall" : "=r" (res) : "0" (SYS_write), "r" (arg0), "r" (arg1), "r" (arg2) : "rcx", "r11", "memory" ); return res; } int main(){ for(int i = 0; i < 1000; i++){ char a = 0; int some_invalid_fd = -1; sys_write(some_invalid_fd, &a, 1); } return 0; } In above code I just expect it to call sys_write 1000 times then return main. I use truss to check system call and their parameters. Everything works fine with -O0 but when I go -O3 for loop getting stuck forever. I believe system call changing i variable or 1000 to something weird.
Dump of assembler code for function main:
0x0000000000201900 <+0>: push %rbp 0x0000000000201901 <+1>: mov %rsp,%rbp 0x0000000000201904 <+4>: mov $0x3e8,%r8d 0x000000000020190a <+10>: lea -0x1(%rbp),%rsi 0x000000000020190e <+14>: mov $0x1,%edx 0x0000000000201913 <+19>: mov $0xffffffffffffffff,%rdi 0x000000000020191a <+26>: nopw 0x0(%rax,%rax,1) 0x0000000000201920 <+32>: movb $0x0,-0x1(%rbp) 0x0000000000201924 <+36>: mov $0x4,%eax 0x0000000000201929 <+41>: syscall 0x000000000020192b <+43>: add $0xffffffff,%r8d 0x000000000020192f <+47>: jne 0x201920 <main+32> 0x0000000000201931 <+49>: xor %eax,%eax 0x0000000000201933 <+51>: pop %rbp 0x0000000000201934 <+52>: ret What is wrong with sys_write()? Why for loop getting stuck?
没有评论:
发表评论