mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:22:43 +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
					
				
					 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling