forked from Bananymous/banan-os
				
			LibC: we don't parse syscall arguments in unistd
We just call Kernel::syscall() with 5 arguments from the variadic function. This was a necessary addition since the syscall() function used over 2 KiB of stack space.
This commit is contained in:
		
							parent
							
								
									1a6100f083
								
							
						
					
					
						commit
						834bf33e57
					
				
							
								
								
									
										286
									
								
								libc/unistd.cpp
								
								
								
								
							
							
						
						
									
										286
									
								
								libc/unistd.cpp
								
								
								
								
							|  | @ -27,288 +27,16 @@ long syscall(long syscall, ...) | ||||||
| 	va_list args; | 	va_list args; | ||||||
| 	va_start(args, syscall); | 	va_start(args, syscall); | ||||||
| 
 | 
 | ||||||
| 	long ret = -1; | 	uintptr_t arg1 = va_arg(args, uintptr_t); | ||||||
| 
 | 	uintptr_t arg2 = va_arg(args, uintptr_t); | ||||||
| 	switch (syscall) | 	uintptr_t arg3 = va_arg(args, uintptr_t); | ||||||
| 	{ | 	uintptr_t arg4 = va_arg(args, uintptr_t); | ||||||
| 		case SYS_EXIT: | 	uintptr_t arg5 = va_arg(args, uintptr_t); | ||||||
| 		{ |  | ||||||
| 			int exit_code = va_arg(args, int); |  | ||||||
| 			ret = Kernel::syscall(SYS_EXIT, exit_code); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_READ: |  | ||||||
| 		{ |  | ||||||
| 			int fd = va_arg(args, int); |  | ||||||
| 			void* buffer = va_arg(args, void*); |  | ||||||
| 			size_t bytes = va_arg(args, size_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_READ, fd, (uintptr_t)buffer, bytes); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_WRITE: |  | ||||||
| 		{ |  | ||||||
| 			int fd = va_arg(args, int); |  | ||||||
| 			const void* buffer = va_arg(args, const void*); |  | ||||||
| 			size_t bytes = va_arg(args, size_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_WRITE, fd, (uintptr_t)buffer, bytes); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_TERMID: |  | ||||||
| 		{ |  | ||||||
| 			char* buffer = va_arg(args, char*); |  | ||||||
| 			ret = Kernel::syscall(SYS_TERMID, (uintptr_t)buffer); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_CLOSE: |  | ||||||
| 		{ |  | ||||||
| 			int fd = va_arg(args, int); |  | ||||||
| 			ret = Kernel::syscall(SYS_CLOSE, fd); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_OPEN: |  | ||||||
| 		{ |  | ||||||
| 			const char* path = va_arg(args, const char*); |  | ||||||
| 			int oflags = va_arg(args, int); |  | ||||||
| 			mode_t mode = va_arg(args, mode_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_OPEN, (uintptr_t)path, oflags, mode); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_OPENAT: |  | ||||||
| 		{ |  | ||||||
| 			int fd = va_arg(args, int); |  | ||||||
| 			const char* path = va_arg(args, const char*); |  | ||||||
| 			int oflags = va_arg(args, int); |  | ||||||
| 			mode_t mode = va_arg(args, mode_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_OPENAT, fd, (uintptr_t)path, oflags, mode); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_ALLOC: |  | ||||||
| 		{ |  | ||||||
| 			size_t bytes = va_arg(args, size_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_ALLOC, bytes); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_REALLOC: |  | ||||||
| 		{ |  | ||||||
| 			void* ptr = va_arg(args, void*); |  | ||||||
| 			size_t size = va_arg(args, size_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_REALLOC, (uintptr_t)ptr, size); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_FREE: |  | ||||||
| 		{ |  | ||||||
| 			void* ptr = va_arg(args, void*); |  | ||||||
| 			ret = Kernel::syscall(SYS_FREE, (uintptr_t)ptr); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SEEK: |  | ||||||
| 		{ |  | ||||||
| 			int fd = va_arg(args, int); |  | ||||||
| 			off_t offset = va_arg(args, off_t); |  | ||||||
| 			int whence = va_arg(args, int); |  | ||||||
| 			ret = Kernel::syscall(SYS_SEEK, fd, offset, whence); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_TELL: |  | ||||||
| 		{ |  | ||||||
| 			int fd = va_arg(args, int); |  | ||||||
| 			ret = Kernel::syscall(SYS_TELL, fd); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_GET_TERMIOS: |  | ||||||
| 		{ |  | ||||||
| 			struct termios* termios = va_arg(args, struct termios*); |  | ||||||
| 			ret = Kernel::syscall(SYS_GET_TERMIOS, (uintptr_t)termios); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SET_TERMIOS: |  | ||||||
| 		{ |  | ||||||
| 			const struct termios* termios = va_arg(args, const struct termios*); |  | ||||||
| 			ret = Kernel::syscall(SYS_SET_TERMIOS, (uintptr_t)termios); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_FORK: |  | ||||||
| 		{ |  | ||||||
| 			ret = Kernel::syscall(SYS_FORK); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_EXEC: |  | ||||||
| 		{ |  | ||||||
| 			const char* pathname = va_arg(args, const char*); |  | ||||||
| 			const char* const* argv = va_arg(args, const char* const*); |  | ||||||
| 			const char* const* envp = va_arg(args, const char* const*); |  | ||||||
| 			ret = Kernel::syscall(SYS_EXEC, (uintptr_t)pathname, (uintptr_t)argv, (uintptr_t)envp); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SLEEP: |  | ||||||
| 		{ |  | ||||||
| 			unsigned int seconds = va_arg(args, unsigned int); |  | ||||||
| 			ret = Kernel::syscall(SYS_SLEEP, seconds); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_WAIT: |  | ||||||
| 		{ |  | ||||||
| 			pid_t pid = va_arg(args, pid_t); |  | ||||||
| 			int* stat_loc = va_arg(args, int*); |  | ||||||
| 			int options = va_arg(args, int); |  | ||||||
| 			ret = Kernel::syscall(SYS_WAIT, pid, (uintptr_t)stat_loc, options); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_FSTAT: |  | ||||||
| 		{ |  | ||||||
| 			int fd = va_arg(args, int); |  | ||||||
| 			struct stat* buf = va_arg(args, struct stat*); |  | ||||||
| 			ret = Kernel::syscall(SYS_FSTAT, (uintptr_t)fd, (uintptr_t)buf); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SETENVP: |  | ||||||
| 		{ |  | ||||||
| 			char** envp = va_arg(args, char**); |  | ||||||
| 			ret = Kernel::syscall(SYS_SETENVP, (uintptr_t)envp); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_READ_DIR_ENTRIES: |  | ||||||
| 		{ |  | ||||||
| 			int fd = va_arg(args, int); |  | ||||||
| 			void* buffer = va_arg(args, void*); |  | ||||||
| 			size_t buffer_size = va_arg(args, size_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_READ_DIR_ENTRIES, fd, (uintptr_t)buffer, buffer_size); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SET_UID: |  | ||||||
| 		{ |  | ||||||
| 			uid_t uid = va_arg(args, uid_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_SET_UID, uid); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SET_GID: |  | ||||||
| 		{ |  | ||||||
| 			gid_t gid = va_arg(args, gid_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_SET_GID, gid); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SET_EUID: |  | ||||||
| 		{ |  | ||||||
| 			uid_t uid = va_arg(args, uid_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_SET_EUID, uid); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SET_EGID: |  | ||||||
| 		{ |  | ||||||
| 			gid_t gid = va_arg(args, gid_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_SET_EGID, gid); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SET_REUID: |  | ||||||
| 		{ |  | ||||||
| 			uid_t ruid = va_arg(args, uid_t); |  | ||||||
| 			uid_t euid = va_arg(args, uid_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_SET_REUID, ruid, euid); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SET_REGID: |  | ||||||
| 		{ |  | ||||||
| 			gid_t rgid = va_arg(args, gid_t); |  | ||||||
| 			gid_t egid = va_arg(args, gid_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_SET_REGID, rgid, egid); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_GET_UID: |  | ||||||
| 		{ |  | ||||||
| 			ret = Kernel::syscall(SYS_GET_UID); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_GET_GID: |  | ||||||
| 		{ |  | ||||||
| 			ret = Kernel::syscall(SYS_GET_GID); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_GET_EUID: |  | ||||||
| 		{ |  | ||||||
| 			ret = Kernel::syscall(SYS_GET_EUID); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_GET_EGID: |  | ||||||
| 		{ |  | ||||||
| 			ret = Kernel::syscall(SYS_GET_EGID); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_GET_PWD: |  | ||||||
| 		{ |  | ||||||
| 			char* buffer = va_arg(args, char*); |  | ||||||
| 			size_t size = va_arg(args, size_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_GET_PWD, (uintptr_t)buffer, size); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SET_PWD: |  | ||||||
| 		{ |  | ||||||
| 			const char* path = va_arg(args, const char*); |  | ||||||
| 			ret = Kernel::syscall(SYS_SET_PWD, (uintptr_t)path); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_CLOCK_GETTIME: |  | ||||||
| 		{ |  | ||||||
| 			clockid_t clock_id = va_arg(args, clockid_t); |  | ||||||
| 			timespec* tp = va_arg(args, timespec*); |  | ||||||
| 			ret = Kernel::syscall(SYS_CLOCK_GETTIME, clock_id, (uintptr_t)tp); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_PIPE: |  | ||||||
| 		{ |  | ||||||
| 			int* fildes = va_arg(args, int*); |  | ||||||
| 			ret = Kernel::syscall(SYS_PIPE, (uintptr_t)fildes); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_DUP2: |  | ||||||
| 		{ |  | ||||||
| 			int fildes = va_arg(args, int); |  | ||||||
| 			int fildes2 = va_arg(args, int); |  | ||||||
| 			ret = Kernel::syscall(SYS_DUP2, fildes, fildes2); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_RAISE: |  | ||||||
| 		{ |  | ||||||
| 			int signal = va_arg(args, int); |  | ||||||
| 			ret = Kernel::syscall(SYS_RAISE, signal); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_KILL: |  | ||||||
| 		{ |  | ||||||
| 			pid_t pid = va_arg(args, pid_t); |  | ||||||
| 			int signal = va_arg(args, int); |  | ||||||
| 			ret = Kernel::syscall(SYS_KILL, pid, signal); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SIGNAL: |  | ||||||
| 		{ |  | ||||||
| 			int signal = va_arg(args, int); |  | ||||||
| 			void (*handler)(int) = va_arg(args, void(*)(int)); |  | ||||||
| 			ret = Kernel::syscall(SYS_SIGNAL, signal, (uintptr_t)handler); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_TCSETPGRP: |  | ||||||
| 		{ |  | ||||||
| 			int fd = va_arg(args, int); |  | ||||||
| 			pid_t pgrp = va_arg(args, pid_t); |  | ||||||
| 			ret = Kernel::syscall(SYS_TCSETPGRP, fd, pgrp); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_GET_PID: |  | ||||||
| 		{ |  | ||||||
| 			ret = Kernel::syscall(SYS_GET_PID); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		case SYS_SIGNAL_DONE: |  | ||||||
| 			// Should not be called by an user
 |  | ||||||
| 			// fall through
 |  | ||||||
| 		default: |  | ||||||
| 			puts("LibC: Unhandeled syscall"); |  | ||||||
| 			ret = -ENOSYS; |  | ||||||
| 			break; |  | ||||||
| 	} |  | ||||||
| 	 | 	 | ||||||
| 	va_end(args); | 	va_end(args); | ||||||
| 
 | 
 | ||||||
|  | 	long ret = Kernel::syscall(syscall, arg1, arg2, arg3, arg4, arg5); | ||||||
|  | 	 | ||||||
| 	if (ret < 0) | 	if (ret < 0) | ||||||
| 	{ | 	{ | ||||||
| 		errno = -ret; | 		errno = -ret; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue