Kernel/LibC: Add support for init_array and fini_array

This commit is contained in:
Bananymous 2024-08-26 14:04:58 +03:00
parent 7c4b9218f2
commit 2c520391eb
18 changed files with 154 additions and 51 deletions

View File

@ -216,6 +216,14 @@ higher_half:
# call global constuctors # call global constuctors
call _init call _init
movl $__init_array_start, %ebx
jmp 2f
1: movl (%ebx), %eax
call *%eax
addl $4, %ebx
2: cmpl $__init_array_end, %ebx
jne 1b
# call to the kernel itself (clear ebp for stacktrace) # call to the kernel itself (clear ebp for stacktrace)
xorl %ebp, %ebp xorl %ebp, %ebp

View File

@ -1,23 +0,0 @@
.section .text
.global _start
_start:
# Set up end of the stack frame linked list.
movl $0, %ebp
pushl %ebp # rip=0
pushl %ebp # rbp=0
movl %esp, %ebp
# Prepare signals, memory allocation, stdio and such.
#call initialize_standard_library
# Run the global constructors.
call _init
# Run main
call main
# Terminate the process with the exit code.
movl %eax, %edi
call exit
.size _start, . - _start

View File

@ -1,9 +1,9 @@
/* x86 crti.s */ /* i686 crti.s */
.section .init .section .init
.global _init .global _init
.type _init, @function .type _init, @function
_init: _init:
push %ebp pushl %ebp
movl %esp, %ebp movl %esp, %ebp
/* gcc will nicely put the contents of crtbegin.o's .init section here. */ /* gcc will nicely put the contents of crtbegin.o's .init section here. */
@ -11,6 +11,14 @@ _init:
.global _fini .global _fini
.type _fini, @function .type _fini, @function
_fini: _fini:
push %ebp pushl %ebp
movl %esp, %ebp movl %esp, %ebp
/* gcc will nicely put the contents of crtbegin.o's .fini section here. */ /* gcc will nicely put the contents of crtbegin.o's .fini section here. */
.section .init_array
.global __init_array_start
__init_array_start:
.section .fini_array
.global __fini_array_start
__fini_array_start:

View File

@ -1,4 +1,4 @@
/* x86 crtn.s */ /* i686 crtn.s */
.section .init .section .init
/* gcc will nicely put the contents of crtend.o's .init section here. */ /* gcc will nicely put the contents of crtend.o's .init section here. */
popl %ebp popl %ebp
@ -8,3 +8,11 @@
/* gcc will nicely put the contents of crtend.o's .fini section here. */ /* gcc will nicely put the contents of crtend.o's .fini section here. */
popl %ebp popl %ebp
ret ret
.section .init_array
.global __init_array_end
__init_array_end:
.section .fini_array
.global __fini_array_end
__fini_array_end:

View File

@ -216,6 +216,14 @@ higher_half:
# call global constuctors # call global constuctors
call _init call _init
movq $__init_array_start, %rbx
jmp 2f
1: movq (%rbx), %rax
call *%rax
addq $8, %rbx
2: cmpq $__init_array_end, %rbx
jne 1b
# call to the kernel itself (clear rbp for stacktrace) # call to the kernel itself (clear rbp for stacktrace)
xorq %rbp, %rbp xorq %rbp, %rbp

View File

@ -14,3 +14,11 @@ _fini:
pushq %rbp pushq %rbp
movq %rsp, %rbp movq %rsp, %rbp
/* gcc will nicely put the contents of crtbegin.o's .fini section here. */ /* gcc will nicely put the contents of crtbegin.o's .fini section here. */
.section .init_array
.global __init_array_start
__init_array_start:
.section .fini_array
.global __fini_array_start
__fini_array_start:

View File

@ -8,3 +8,11 @@
/* gcc will nicely put the contents of crtend.o's .fini section here. */ /* gcc will nicely put the contents of crtend.o's .fini section here. */
popq %rbp popq %rbp
ret ret
.section .init_array
.global __init_array_end
__init_array_end:
.section .fini_array
.global __fini_array_end
__fini_array_end:

View File

@ -104,7 +104,7 @@ case $1 in
run_qemu -nographic $QEMU_ACCEL run_qemu -nographic $QEMU_ACCEL
;; ;;
qemu-debug) qemu-debug)
run_qemu -serial stdio -d int -no-reboot run_qemu -serial stdio -d int -action reboot=shutdown,shutdown=pause
;; ;;
bochs) bochs)
run_bochs run_bochs

View File

@ -92,7 +92,7 @@ build_binutils () {
--target="$BANAN_TOOLCHAIN_TRIPLE" \ --target="$BANAN_TOOLCHAIN_TRIPLE" \
--prefix="$BANAN_TOOLCHAIN_PREFIX" \ --prefix="$BANAN_TOOLCHAIN_PREFIX" \
--with-sysroot="$BANAN_SYSROOT" \ --with-sysroot="$BANAN_SYSROOT" \
--disable-initfini-array \ --enable-initfini-array \
--disable-nls \ --disable-nls \
--disable-werror --disable-werror
@ -119,7 +119,7 @@ build_gcc () {
--target="$BANAN_TOOLCHAIN_TRIPLE" \ --target="$BANAN_TOOLCHAIN_TRIPLE" \
--prefix="$BANAN_TOOLCHAIN_PREFIX" \ --prefix="$BANAN_TOOLCHAIN_PREFIX" \
--with-sysroot="$BANAN_SYSROOT" \ --with-sysroot="$BANAN_SYSROOT" \
--disable-initfini-array \ --enable-initfini-array \
--disable-nls \ --disable-nls \
--enable-languages=c,c++ --enable-languages=c,c++

View File

@ -21,6 +21,14 @@ _start:
# call global constructors # call global constructors
call _init call _init
movl $__init_array_start, %ebx
jmp 2f
1: movl (%ebx), %eax
call *%eax
addl $4, %ebx
2: cmpl $__init_array_end, %ebx
jne 1b
# call main # call main
movl 0(%esp), %eax movl 0(%esp), %eax
xchgl %eax, 8(%esp) xchgl %eax, 8(%esp)

View File

@ -14,3 +14,11 @@ _fini:
pushl %ebp pushl %ebp
movl %esp, %ebp movl %esp, %ebp
/* gcc will nicely put the contents of crtbegin.o's .fini section here. */ /* gcc will nicely put the contents of crtbegin.o's .fini section here. */
.section .init_array
.global __init_array_start
__init_array_start:
.section .fini_array
.global __fini_array_start
__fini_array_start:

View File

@ -8,3 +8,11 @@
/* gcc will nicely put the contents of crtend.o's .fini section here. */ /* gcc will nicely put the contents of crtend.o's .fini section here. */
popl %ebp popl %ebp
ret ret
.section .init_array
.global __init_array_end
__init_array_end:
.section .fini_array
.global __fini_array_end
__fini_array_end:

View File

@ -22,6 +22,14 @@ _start:
# call global constructors # call global constructors
call _init call _init
movq $__init_array_start, %rbx
jmp 2f
1: movq (%rbx), %rax
call *%rax
addq $8, %rbx
2: cmpq $__init_array_end, %rbx
jne 1b
# call main # call main
movq 16(%rsp), %rdi movq 16(%rsp), %rdi
movq 8(%rsp), %rsi movq 8(%rsp), %rsi

View File

@ -14,3 +14,11 @@ _fini:
pushq %rbp pushq %rbp
movq %rsp, %rbp movq %rsp, %rbp
/* gcc will nicely put the contents of crtbegin.o's .fini section here. */ /* gcc will nicely put the contents of crtbegin.o's .fini section here. */
.section .init_array
.global __init_array_start
__init_array_start:
.section .fini_array
.global __fini_array_start
__fini_array_start:

View File

@ -8,3 +8,11 @@
/* gcc will nicely put the contents of crtend.o's .fini section here. */ /* gcc will nicely put the contents of crtend.o's .fini section here. */
popq %rbp popq %rbp
ret ret
.section .init_array
.global __init_array_end
__init_array_end:
.section .fini_array
.global __fini_array_end
__fini_array_end:

View File

@ -48,7 +48,7 @@ struct malloc_pool_t
static malloc_pool_t s_malloc_pools[s_malloc_pool_count]; static malloc_pool_t s_malloc_pools[s_malloc_pool_count];
void init_malloc() void _init_malloc()
{ {
size_t pool_size = s_malloc_pool_size_initial; size_t pool_size = s_malloc_pool_size_initial;
for (size_t i = 0; i < s_malloc_pool_count; i++) for (size_t i = 0; i < s_malloc_pool_count; i++)

View File

@ -15,20 +15,20 @@
struct FILE struct FILE
{ {
int fd { -1 }; int fd;
mode_t mode { 0 }; mode_t mode;
int buffer_type { _IOLBF }; int buffer_type;
bool eof { false }; bool eof;
bool error { false }; bool error;
int pid { -1 }; int pid;
int unget_char { EOF }; int unget_char;
unsigned char inline_buffer_storage[BUFSIZ] {}; unsigned char inline_buffer_storage[BUFSIZ];
unsigned char* buffer = inline_buffer_storage; unsigned char* buffer;
uint32_t buffer_size = BUFSIZ; uint32_t buffer_size;
uint32_t buffer_index { 0 }; uint32_t buffer_index;
}; };
struct ScopeLock struct ScopeLock
@ -47,18 +47,46 @@ struct ScopeLock
FILE* m_file; FILE* m_file;
}; };
static FILE s_files[FOPEN_MAX] { static FILE s_files[FOPEN_MAX];
{ .fd = STDIN_FILENO, .mode = O_RDONLY },
{ .fd = STDOUT_FILENO, .mode = O_WRONLY },
{ .fd = STDERR_FILENO, .mode = O_WRONLY, .buffer_type = _IONBF },
{ .fd = STDDBG_FILENO, .mode = O_WRONLY },
};
FILE* stdin = &s_files[0]; FILE* stdin = &s_files[0];
FILE* stdout = &s_files[1]; FILE* stdout = &s_files[1];
FILE* stderr = &s_files[2]; FILE* stderr = &s_files[2];
FILE* stddbg = &s_files[3]; FILE* stddbg = &s_files[3];
static void init_closed_file(FILE* file)
{
file->fd = -1;
file->mode = 0;
file->buffer_type = _IOLBF;
file->eof = false;
file->error = false;
file->pid = -1;
file->unget_char = EOF;
file->buffer = file->inline_buffer_storage;
file->buffer_size = BUFSIZ;
file->buffer_index = 0;
}
void _init_stdio()
{
for (size_t i = 0; i < FOPEN_MAX; i++)
init_closed_file(&s_files[i]);
s_files[STDIN_FILENO].fd = STDIN_FILENO;
s_files[STDIN_FILENO].mode = O_RDONLY;
s_files[STDOUT_FILENO].fd = STDOUT_FILENO;
s_files[STDOUT_FILENO].mode = O_WRONLY;
s_files[STDERR_FILENO].fd = STDERR_FILENO;
s_files[STDERR_FILENO].mode = O_WRONLY;
s_files[STDERR_FILENO].buffer_type = _IONBF;
s_files[STDDBG_FILENO].fd = STDDBG_FILENO;
s_files[STDDBG_FILENO].mode = O_WRONLY;
}
void clearerr(FILE* file) void clearerr(FILE* file)
{ {
ScopeLock _(file); ScopeLock _(file);
@ -79,7 +107,7 @@ int fclose(FILE* file)
ScopeLock _(file); ScopeLock _(file);
(void)fflush(file); (void)fflush(file);
int ret = (close(file->fd) == -1) ? EOF : 0; int ret = (close(file->fd) == -1) ? EOF : 0;
file = {}; init_closed_file(file);
return ret; return ret;
} }

View File

@ -15,10 +15,12 @@
char** environ; char** environ;
extern void init_malloc(); extern void _init_malloc();
extern void _init_stdio();
extern "C" void _init_libc(char** _environ) extern "C" void _init_libc(char** _environ)
{ {
init_malloc(); _init_malloc();
_init_stdio();
if (!_environ) if (!_environ)
return; return;