njn | d9ab15d | 2005-08-28 05:10:48 +0000 | [diff] [blame] | 1 | [Julian replying to Greg Parker's notes about darwin/ppc32] |
| 2 | |
| 3 | |
| 4 | > Some notes about porting Valgrind 3.x to Mac OS X / PowerPC: |
| 5 | > |
| 6 | > * Darwin always uses a 64-bit off_t, even on 32-bit architectures. |
| 7 | > (FreeBSD may also do this.) Valgrind currently allows off_t to |
| 8 | > be pointer sized only, but it doesn't look like there is any |
| 9 | > strong dependence on this anywhere. |
| 10 | |
| 11 | Ok. This sounds fairly harmless. |
| 12 | |
| 13 | > * dispatch.S should be platform-specific instead of arch-specific. |
| 14 | > In particular, Darwin's assembler is not GNU as, so the file's |
| 15 | > syntax would be wrong even if everything else were the same. |
| 16 | > It should be reasonable to change dispatch-$VG_ARCH.S to |
| 17 | > dispatch-$VG_OS-$VG_ARCH.S . |
| 18 | |
| 19 | True. |
| 20 | |
| 21 | > * Some Darwin syscalls take 7 arguments (in particular, mmap() |
| 22 | > with 64-bit off_t offset). Valgrind currently provides |
| 23 | > arg1..arg6. I don't see any obvious 8-argument syscalls. |
| 24 | > Do other architectures define a 7th syscall argument and |
| 25 | > just never use it, or do they have a 6 argument max? |
| 26 | |
| 27 | 6 args is as many as Linux uses, it seems, and that's why the |
| 28 | m_syswrap abstractions stop at 6. But clearly that could be |
| 29 | extended to 7 with minimal effort. |
| 30 | |
| 31 | > * Darwin syscalls return a full 64-bit result, even on 32-bit |
| 32 | > architectures. In particular, the lseek() syscall returns |
| 33 | > a 64-bit off_t in registers r3 and r4. For syscalls that |
| 34 | > return a 32-bit int, the kernel sets the other return |
| 35 | > register to zero (or the appropriate sign extension for |
| 36 | > signed return types). I don't know how much of an effect |
| 37 | > changing this would have. |
| 38 | |
| 39 | I think the m_syswrap abstractions should be able to hide that OK. |
| 40 | |
| 41 | > * Darwin/PPC syscalls indicate success and failure in an unusual |
| 42 | > way: successful calls and failed calls return to different |
| 43 | > points. A syscall call usually looks like this: |
| 44 | > |
| 45 | > // ...set up parameters here... |
| 46 | > sc // make the syscall |
| 47 | > b BAD // failed calls return here |
| 48 | > GOOD: |
| 49 | > nop // successful calls return here |
| 50 | > // ...handle success case here... |
| 51 | > blr |
| 52 | > BAD: |
| 53 | > // ...handle failure case here... |
| 54 | > blr |
| 55 | |
| 56 | So you're saying that after sc, execution continues either at |
| 57 | CIA+4 or CIA+8 depending on outcome. Right? |
| 58 | |
| 59 | > Handling this in VG_(do_syscall_for_client) isn't too bad. |
| 60 | > One option is to store the PC of the last simulated `sc` |
| 61 | > in the thread state, updating it before each call. Another |
| 62 | > is to store a "sc failed" bit in each thread state, updating |
| 63 | > it after each call. In either case, the simulated PC after |
| 64 | > completion of the simulated `sc` would be adjusted based on |
| 65 | > the result of the real `sc` or the syscall wrapper. The |
| 66 | > syscall restarter would use the extra thread state to decide |
| 67 | > whether to back up on instruction or two. |
| 68 | > |
| 69 | > Handling this in VEX might be more difficult, because VEX |
| 70 | > might need to know that `sc` looks like a conditional branch |
| 71 | > in basic block analysis. |
| 72 | |
| 73 | Probably pretty harmless. There's all sorts of tricks that can |
| 74 | be played. I think it's a non-problem. |
| 75 | |
| 76 | > (Of course, Mach traps use `sc` but don't use the PC-modifying |
| 77 | > calling convention. However, Mach traps are an entirely different |
| 78 | > ball of wax, and much will be said about them later.) |