mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
Kernel+LibSystem: Add a 4th syscall argument
Let's allow passing 4 function arguments to a syscall. The 4th argument goes into ESI or RSI.
This commit is contained in:
parent
9b78ae5149
commit
deff554096
Notes:
sideshowbarker
2024-07-18 08:22:19 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/deff5540966
5 changed files with 33 additions and 8 deletions
|
@ -531,6 +531,17 @@ inline uintptr_t invoke(Function function, T1 arg1, T2 arg2, T3 arg3)
|
|||
: "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4>
|
||||
inline uintptr_t invoke(Function function, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
|
||||
{
|
||||
uintptr_t result;
|
||||
asm volatile("int $0x82"
|
||||
: "=a"(result)
|
||||
: "a"(function), "d"((uintptr_t)arg1), "c"((uintptr_t)arg2), "b"((uintptr_t)arg3), "S"((uintptr_t)arg4)
|
||||
: "memory");
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -104,18 +104,20 @@ struct [[gnu::packed]] RegisterState {
|
|||
#endif
|
||||
}
|
||||
|
||||
void capture_syscall_params(FlatPtr& function, FlatPtr& arg1, FlatPtr& arg2, FlatPtr& arg3) const
|
||||
void capture_syscall_params(FlatPtr& function, FlatPtr& arg1, FlatPtr& arg2, FlatPtr& arg3, FlatPtr& arg4) const
|
||||
{
|
||||
#if ARCH(I386)
|
||||
function = eax;
|
||||
arg1 = edx;
|
||||
arg2 = ecx;
|
||||
arg3 = ebx;
|
||||
arg4 = esi;
|
||||
#else
|
||||
function = rax;
|
||||
arg1 = rdx;
|
||||
arg2 = rcx;
|
||||
arg3 = rbx;
|
||||
arg4 = rsi;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ NEVER_INLINE NAKED void syscall_asm_entry()
|
|||
|
||||
namespace Syscall {
|
||||
|
||||
static KResultOr<FlatPtr> handle(RegisterState&, FlatPtr function, FlatPtr arg1, FlatPtr arg2, FlatPtr arg3);
|
||||
static KResultOr<FlatPtr> handle(RegisterState&, FlatPtr function, FlatPtr arg1, FlatPtr arg2, FlatPtr arg3, FlatPtr arg4);
|
||||
|
||||
UNMAP_AFTER_INIT void initialize()
|
||||
{
|
||||
|
@ -88,7 +88,7 @@ UNMAP_AFTER_INIT void initialize()
|
|||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
typedef KResultOr<FlatPtr> (Process::*Handler)(FlatPtr, FlatPtr, FlatPtr);
|
||||
typedef KResultOr<FlatPtr> (Process::*Handler)(FlatPtr, FlatPtr, FlatPtr, FlatPtr);
|
||||
typedef KResultOr<FlatPtr> (Process::*HandlerWithRegisterState)(RegisterState&);
|
||||
struct HandlerMetadata {
|
||||
Handler handler;
|
||||
|
@ -101,7 +101,7 @@ static const HandlerMetadata s_syscall_table[] = {
|
|||
};
|
||||
#undef __ENUMERATE_SYSCALL
|
||||
|
||||
KResultOr<FlatPtr> handle(RegisterState& regs, FlatPtr function, FlatPtr arg1, FlatPtr arg2, FlatPtr arg3)
|
||||
KResultOr<FlatPtr> handle(RegisterState& regs, FlatPtr function, FlatPtr arg1, FlatPtr arg2, FlatPtr arg3, FlatPtr arg4)
|
||||
{
|
||||
VERIFY_INTERRUPTS_ENABLED();
|
||||
auto current_thread = Thread::current();
|
||||
|
@ -109,7 +109,7 @@ KResultOr<FlatPtr> handle(RegisterState& regs, FlatPtr function, FlatPtr arg1, F
|
|||
current_thread->did_syscall();
|
||||
|
||||
if (function >= Function::__Count) {
|
||||
dbgln("Unknown syscall {} requested ({:p}, {:p}, {:p})", function, arg1, arg2, arg3);
|
||||
dbgln("Unknown syscall {} requested ({:p}, {:p}, {:p}, {:p})", function, arg1, arg2, arg3, arg4);
|
||||
return ENOSYS;
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ KResultOr<FlatPtr> handle(RegisterState& regs, FlatPtr function, FlatPtr arg1, F
|
|||
auto handler = (HandlerWithRegisterState)syscall_metadata.handler;
|
||||
result = (process.*(handler))(regs);
|
||||
} else {
|
||||
result = (process.*(syscall_metadata.handler))(arg1, arg2, arg3);
|
||||
result = (process.*(syscall_metadata.handler))(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -207,9 +207,10 @@ NEVER_INLINE void syscall_handler(TrapFrame* trap)
|
|||
FlatPtr arg1;
|
||||
FlatPtr arg2;
|
||||
FlatPtr arg3;
|
||||
regs.capture_syscall_params(function, arg1, arg2, arg3);
|
||||
FlatPtr arg4;
|
||||
regs.capture_syscall_params(function, arg1, arg2, arg3, arg4);
|
||||
|
||||
auto result = Syscall::handle(regs, function, arg1, arg2, arg3);
|
||||
auto result = Syscall::handle(regs, function, arg1, arg2, arg3, arg4);
|
||||
|
||||
if (result.is_error()) {
|
||||
regs.set_return_reg(result.error());
|
||||
|
|
|
@ -28,4 +28,9 @@ uintptr_t syscall3(uintptr_t function, uintptr_t arg0, uintptr_t arg1, uintptr_t
|
|||
{
|
||||
return Syscall::invoke((Syscall::Function)function, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
uintptr_t syscall4(uintptr_t function, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
|
||||
{
|
||||
return Syscall::invoke((Syscall::Function)function, arg0, arg1, arg2, arg3);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ uintptr_t syscall0(uintptr_t function);
|
|||
uintptr_t syscall1(uintptr_t function, uintptr_t arg0);
|
||||
uintptr_t syscall2(uintptr_t function, uintptr_t arg0, uintptr_t arg1);
|
||||
uintptr_t syscall3(uintptr_t function, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2);
|
||||
uintptr_t syscall4(uintptr_t function, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -39,4 +40,9 @@ inline uintptr_t syscall(auto function, auto arg0, auto arg1, auto arg2)
|
|||
return syscall3((uintptr_t)function, (uintptr_t)arg0, (uintptr_t)arg1, (uintptr_t)arg2);
|
||||
}
|
||||
|
||||
inline uintptr_t syscall(auto function, auto arg0, auto arg1, auto arg2, auto arg3)
|
||||
{
|
||||
return syscall4((uintptr_t)function, (uintptr_t)arg0, (uintptr_t)arg1, (uintptr_t)arg2, (uintptr_t)arg3);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue