Simplified the x86 syscall interface a bit. We no longer pass a pointer
to the parameters nor the number of parameters; the kernel is able to get both without problems. The syscall functions in libroot (_kern_*()) are now self-contained (they don't "jmp" to separate code anymore), which at least theoretically allows gdb to print a stack trace with the syscall function on the top when a thread is currently performing a syscall. Practically it doesn't work yet, though, since those functions are frameless (i.e. create no stack frame) which needs special support I haven't implemented yet. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14661 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -479,18 +479,18 @@ i386_handle_trap(struct iframe frame)
|
||||
#endif
|
||||
/* syscall interface works as such:
|
||||
* %eax has syscall #
|
||||
* %ecx has number of args (0-16)
|
||||
* %edx has pointer to buffer containing args from first to last
|
||||
* each is verified to make sure someone doesn't try to clobber it
|
||||
* %esp + 4 points to the syscall parameters
|
||||
*/
|
||||
if (frame.ecx <= MAX_ARGS) {
|
||||
if (IS_KERNEL_ADDRESS(frame.edx)
|
||||
|| user_memcpy(args, (void *)frame.edx, frame.ecx * sizeof(unsigned int)) < B_OK) {
|
||||
if (frame.eax >= 0 && frame.eax < kSyscallCount) {
|
||||
void *params = (void*)(frame.user_esp + 4);
|
||||
int paramSize = kSyscallInfos[frame.eax].parameter_size;
|
||||
if (IS_KERNEL_ADDRESS((addr_t)params)
|
||||
|| user_memcpy(args, params, paramSize) < B_OK) {
|
||||
retcode = B_BAD_ADDRESS;
|
||||
} else
|
||||
ret = syscall_dispatcher(frame.eax, (void *)args, &retcode);
|
||||
} else {
|
||||
// want to pass too many args into the system
|
||||
// invalid syscall number
|
||||
retcode = EINVAL;
|
||||
}
|
||||
frame.eax = retcode & 0xffffffff;
|
||||
|
||||
Reference in New Issue
Block a user