Kernel/LibC/DynamicLoader: Update process start ABI
We now use SysV abi for process startup
This commit is contained in:
@@ -2,18 +2,22 @@
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
pushl $0
|
||||
# get argc, argv, envp
|
||||
movl (%esp), %edi
|
||||
leal 4(%esp), %esi
|
||||
leal 4(%esi, %edi, 4), %edx
|
||||
|
||||
# align stack
|
||||
andl $-16, %esp
|
||||
xorl %ebp, %ebp
|
||||
|
||||
# save argc, argv, envp
|
||||
subl $4, %esp
|
||||
pushl %edx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
|
||||
# STACK LAYOUT
|
||||
# null
|
||||
# argc
|
||||
# argv
|
||||
# envp
|
||||
|
||||
xorl %ebp, %ebp
|
||||
subl $4, %esp
|
||||
|
||||
pushl $__fini_array_end
|
||||
pushl $__fini_array_start
|
||||
|
||||
@@ -2,21 +2,22 @@
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
pushq $0
|
||||
# get argc, argv, envp
|
||||
movq (%rsp), %rdi
|
||||
leaq 8(%rsp), %rsi
|
||||
leaq 8(%rsi, %rdi, 8), %rdx
|
||||
|
||||
# align stack
|
||||
andq $-16, %rsp
|
||||
xorq %rbp, %rbp
|
||||
|
||||
# save argc, argv, envp
|
||||
subq $8, %rsp
|
||||
pushq %rdi
|
||||
pushq %rsi
|
||||
pushq %rdx
|
||||
|
||||
# STACK LAYOUT
|
||||
# null
|
||||
# argc
|
||||
# argv
|
||||
# envp
|
||||
|
||||
xorq %rbp, %rbp
|
||||
|
||||
# init libc
|
||||
movq 0(%rsp), %rdi
|
||||
movq %rdx, %rdi # environ
|
||||
|
||||
pushq $__fini_array_end
|
||||
pushq $__fini_array_start
|
||||
@@ -31,9 +32,10 @@ _start:
|
||||
addq $(6 * 8), %rsp
|
||||
|
||||
# call main
|
||||
movq 16(%rsp), %rdi
|
||||
movq 8(%rsp), %rsi
|
||||
movq 0(%rsp), %rdx
|
||||
popq %rdx
|
||||
popq %rsi
|
||||
popq %rdi
|
||||
addq $8, %rsp
|
||||
call main
|
||||
|
||||
# call exit
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <BAN/Atomic.h>
|
||||
#include <BAN/PlacementNew.h>
|
||||
|
||||
#include <kernel/Arch.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
@@ -16,15 +18,30 @@ struct pthread_trampoline_info_t
|
||||
};
|
||||
|
||||
// stack is 16 byte aligned on entry, this `call` is used to align it
|
||||
extern "C" void pthread_trampoline(void*);
|
||||
asm("pthread_trampoline: call pthread_trampoline_cpp");
|
||||
extern "C" void _pthread_trampoline(void*);
|
||||
asm(
|
||||
#if ARCH(x86_64)
|
||||
"_pthread_trampoline:"
|
||||
"popq %rdi;"
|
||||
"andq $-16, %rsp;"
|
||||
"xorq %rbp, %rbp;"
|
||||
"call _pthread_trampoline_cpp"
|
||||
#elif ARCH(i686)
|
||||
"_pthread_trampoline:"
|
||||
"ud2;"
|
||||
"popl %edi;"
|
||||
"andl $-16, %esp;"
|
||||
"xorl %ebp, %ebp;"
|
||||
"subl $12, %esp;"
|
||||
"pushl %edi;"
|
||||
"call _pthread_trampoline_cpp"
|
||||
#endif
|
||||
);
|
||||
|
||||
extern "C" void pthread_trampoline_cpp(void* arg)
|
||||
extern "C" void _pthread_trampoline_cpp(void* arg)
|
||||
{
|
||||
pthread_trampoline_info_t info;
|
||||
memcpy(&info, arg, sizeof(pthread_trampoline_info_t));
|
||||
auto info = *reinterpret_cast<pthread_trampoline_info_t*>(arg);
|
||||
free(arg);
|
||||
|
||||
pthread_exit(info.start_routine(info.arg));
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
@@ -63,24 +80,30 @@ void pthread_cleanup_push(void (*routine)(void*), void* arg)
|
||||
s_cleanup_stack = cleanup;
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t* __restrict thread, const pthread_attr_t* __restrict attr, void* (*start_routine)(void*), void* __restrict arg)
|
||||
int pthread_create(pthread_t* __restrict thread_id, const pthread_attr_t* __restrict attr, void* (*start_routine)(void*), void* __restrict arg)
|
||||
{
|
||||
auto* info = static_cast<pthread_trampoline_info_t*>(malloc(sizeof(pthread_trampoline_info_t)));
|
||||
if (info == nullptr)
|
||||
return -1;
|
||||
info->start_routine = start_routine;
|
||||
info->arg = arg;
|
||||
return errno;
|
||||
|
||||
*info = {
|
||||
.start_routine = start_routine,
|
||||
.arg = arg,
|
||||
};
|
||||
|
||||
const auto ret = syscall(SYS_PTHREAD_CREATE, attr, pthread_trampoline, info);
|
||||
if (ret == -1)
|
||||
{
|
||||
free(info);
|
||||
return -1;
|
||||
}
|
||||
goto pthread_create_error;
|
||||
|
||||
if (thread)
|
||||
*thread = ret;
|
||||
|
||||
if (thread_id)
|
||||
*thread_id = ret;
|
||||
return 0;
|
||||
|
||||
pthread_create_error:
|
||||
const int return_code = errno;
|
||||
free(info);
|
||||
return return_code;
|
||||
}
|
||||
|
||||
void pthread_exit(void* value_ptr)
|
||||
|
||||
Reference in New Issue
Block a user