From 2c520391eb8973ef5279bd197f2961db748c4e83 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 26 Aug 2024 14:04:58 +0300 Subject: [PATCH] Kernel/LibC: Add support for init_array and fini_array --- kernel/arch/i686/boot.S | 8 +++ kernel/arch/i686/crt0.S | 23 -------- kernel/arch/i686/crti.S | 14 ++++- kernel/arch/i686/crtn.S | 10 +++- kernel/arch/x86_64/boot.S | 8 +++ kernel/arch/x86_64/crti.S | 8 +++ kernel/arch/x86_64/crtn.S | 8 +++ script/build.sh | 2 +- toolchain/build.sh | 4 +- userspace/libraries/LibC/arch/i686/crt0.S | 8 +++ userspace/libraries/LibC/arch/i686/crti.S | 8 +++ userspace/libraries/LibC/arch/i686/crtn.S | 8 +++ userspace/libraries/LibC/arch/x86_64/crt0.S | 8 +++ userspace/libraries/LibC/arch/x86_64/crti.S | 8 +++ userspace/libraries/LibC/arch/x86_64/crtn.S | 8 +++ userspace/libraries/LibC/malloc.cpp | 2 +- userspace/libraries/LibC/stdio.cpp | 64 +++++++++++++++------ userspace/libraries/LibC/unistd.cpp | 6 +- 18 files changed, 154 insertions(+), 51 deletions(-) delete mode 100644 kernel/arch/i686/crt0.S diff --git a/kernel/arch/i686/boot.S b/kernel/arch/i686/boot.S index 520cdca4..8b1a4733 100644 --- a/kernel/arch/i686/boot.S +++ b/kernel/arch/i686/boot.S @@ -216,6 +216,14 @@ higher_half: # call global constuctors 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) xorl %ebp, %ebp diff --git a/kernel/arch/i686/crt0.S b/kernel/arch/i686/crt0.S deleted file mode 100644 index 24453324..00000000 --- a/kernel/arch/i686/crt0.S +++ /dev/null @@ -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 diff --git a/kernel/arch/i686/crti.S b/kernel/arch/i686/crti.S index 30dd4ea2..96130d42 100644 --- a/kernel/arch/i686/crti.S +++ b/kernel/arch/i686/crti.S @@ -1,9 +1,9 @@ -/* x86 crti.s */ +/* i686 crti.s */ .section .init .global _init .type _init, @function _init: - push %ebp + pushl %ebp movl %esp, %ebp /* gcc will nicely put the contents of crtbegin.o's .init section here. */ @@ -11,6 +11,14 @@ _init: .global _fini .type _fini, @function _fini: - push %ebp + pushl %ebp movl %esp, %ebp /* 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: diff --git a/kernel/arch/i686/crtn.S b/kernel/arch/i686/crtn.S index 1da795d6..106f4c1c 100644 --- a/kernel/arch/i686/crtn.S +++ b/kernel/arch/i686/crtn.S @@ -1,4 +1,4 @@ -/* x86 crtn.s */ +/* i686 crtn.s */ .section .init /* gcc will nicely put the contents of crtend.o's .init section here. */ popl %ebp @@ -8,3 +8,11 @@ /* gcc will nicely put the contents of crtend.o's .fini section here. */ popl %ebp ret + +.section .init_array +.global __init_array_end +__init_array_end: + +.section .fini_array +.global __fini_array_end +__fini_array_end: diff --git a/kernel/arch/x86_64/boot.S b/kernel/arch/x86_64/boot.S index c3b92131..25d9950d 100644 --- a/kernel/arch/x86_64/boot.S +++ b/kernel/arch/x86_64/boot.S @@ -216,6 +216,14 @@ higher_half: # call global constuctors 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) xorq %rbp, %rbp diff --git a/kernel/arch/x86_64/crti.S b/kernel/arch/x86_64/crti.S index 7c9624cc..91808154 100644 --- a/kernel/arch/x86_64/crti.S +++ b/kernel/arch/x86_64/crti.S @@ -14,3 +14,11 @@ _fini: pushq %rbp movq %rsp, %rbp /* 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: diff --git a/kernel/arch/x86_64/crtn.S b/kernel/arch/x86_64/crtn.S index 5d6f1e9a..8f3bdab2 100644 --- a/kernel/arch/x86_64/crtn.S +++ b/kernel/arch/x86_64/crtn.S @@ -8,3 +8,11 @@ /* gcc will nicely put the contents of crtend.o's .fini section here. */ popq %rbp ret + +.section .init_array +.global __init_array_end +__init_array_end: + +.section .fini_array +.global __fini_array_end +__fini_array_end: diff --git a/script/build.sh b/script/build.sh index 0cc7e324..fd41b72d 100755 --- a/script/build.sh +++ b/script/build.sh @@ -104,7 +104,7 @@ case $1 in run_qemu -nographic $QEMU_ACCEL ;; qemu-debug) - run_qemu -serial stdio -d int -no-reboot + run_qemu -serial stdio -d int -action reboot=shutdown,shutdown=pause ;; bochs) run_bochs diff --git a/toolchain/build.sh b/toolchain/build.sh index 3e7d672f..2c47fbc8 100755 --- a/toolchain/build.sh +++ b/toolchain/build.sh @@ -92,7 +92,7 @@ build_binutils () { --target="$BANAN_TOOLCHAIN_TRIPLE" \ --prefix="$BANAN_TOOLCHAIN_PREFIX" \ --with-sysroot="$BANAN_SYSROOT" \ - --disable-initfini-array \ + --enable-initfini-array \ --disable-nls \ --disable-werror @@ -119,7 +119,7 @@ build_gcc () { --target="$BANAN_TOOLCHAIN_TRIPLE" \ --prefix="$BANAN_TOOLCHAIN_PREFIX" \ --with-sysroot="$BANAN_SYSROOT" \ - --disable-initfini-array \ + --enable-initfini-array \ --disable-nls \ --enable-languages=c,c++ diff --git a/userspace/libraries/LibC/arch/i686/crt0.S b/userspace/libraries/LibC/arch/i686/crt0.S index d44ffdce..0e6dfbf5 100644 --- a/userspace/libraries/LibC/arch/i686/crt0.S +++ b/userspace/libraries/LibC/arch/i686/crt0.S @@ -21,6 +21,14 @@ _start: # call global constructors 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 movl 0(%esp), %eax xchgl %eax, 8(%esp) diff --git a/userspace/libraries/LibC/arch/i686/crti.S b/userspace/libraries/LibC/arch/i686/crti.S index 64945d13..96130d42 100644 --- a/userspace/libraries/LibC/arch/i686/crti.S +++ b/userspace/libraries/LibC/arch/i686/crti.S @@ -14,3 +14,11 @@ _fini: pushl %ebp movl %esp, %ebp /* 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: diff --git a/userspace/libraries/LibC/arch/i686/crtn.S b/userspace/libraries/LibC/arch/i686/crtn.S index 9adcd820..106f4c1c 100644 --- a/userspace/libraries/LibC/arch/i686/crtn.S +++ b/userspace/libraries/LibC/arch/i686/crtn.S @@ -8,3 +8,11 @@ /* gcc will nicely put the contents of crtend.o's .fini section here. */ popl %ebp ret + +.section .init_array +.global __init_array_end +__init_array_end: + +.section .fini_array +.global __fini_array_end +__fini_array_end: diff --git a/userspace/libraries/LibC/arch/x86_64/crt0.S b/userspace/libraries/LibC/arch/x86_64/crt0.S index e4176a9f..324c5bb2 100644 --- a/userspace/libraries/LibC/arch/x86_64/crt0.S +++ b/userspace/libraries/LibC/arch/x86_64/crt0.S @@ -22,6 +22,14 @@ _start: # call global constructors 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 movq 16(%rsp), %rdi movq 8(%rsp), %rsi diff --git a/userspace/libraries/LibC/arch/x86_64/crti.S b/userspace/libraries/LibC/arch/x86_64/crti.S index 7c9624cc..91808154 100644 --- a/userspace/libraries/LibC/arch/x86_64/crti.S +++ b/userspace/libraries/LibC/arch/x86_64/crti.S @@ -14,3 +14,11 @@ _fini: pushq %rbp movq %rsp, %rbp /* 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: diff --git a/userspace/libraries/LibC/arch/x86_64/crtn.S b/userspace/libraries/LibC/arch/x86_64/crtn.S index 5d6f1e9a..8f3bdab2 100644 --- a/userspace/libraries/LibC/arch/x86_64/crtn.S +++ b/userspace/libraries/LibC/arch/x86_64/crtn.S @@ -8,3 +8,11 @@ /* gcc will nicely put the contents of crtend.o's .fini section here. */ popq %rbp ret + +.section .init_array +.global __init_array_end +__init_array_end: + +.section .fini_array +.global __fini_array_end +__fini_array_end: diff --git a/userspace/libraries/LibC/malloc.cpp b/userspace/libraries/LibC/malloc.cpp index 81bdd2d5..147eaece 100644 --- a/userspace/libraries/LibC/malloc.cpp +++ b/userspace/libraries/LibC/malloc.cpp @@ -48,7 +48,7 @@ struct malloc_pool_t 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; for (size_t i = 0; i < s_malloc_pool_count; i++) diff --git a/userspace/libraries/LibC/stdio.cpp b/userspace/libraries/LibC/stdio.cpp index 9f6d9ae8..bea1a6a3 100644 --- a/userspace/libraries/LibC/stdio.cpp +++ b/userspace/libraries/LibC/stdio.cpp @@ -15,20 +15,20 @@ struct FILE { - int fd { -1 }; - mode_t mode { 0 }; - int buffer_type { _IOLBF }; - bool eof { false }; - bool error { false }; + int fd; + mode_t mode; + int buffer_type; + bool eof; + bool error; - int pid { -1 }; + int pid; - int unget_char { EOF }; + int unget_char; - unsigned char inline_buffer_storage[BUFSIZ] {}; - unsigned char* buffer = inline_buffer_storage; - uint32_t buffer_size = BUFSIZ; - uint32_t buffer_index { 0 }; + unsigned char inline_buffer_storage[BUFSIZ]; + unsigned char* buffer; + uint32_t buffer_size; + uint32_t buffer_index; }; struct ScopeLock @@ -47,18 +47,46 @@ struct ScopeLock FILE* m_file; }; -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 }, -}; +static FILE s_files[FOPEN_MAX]; FILE* stdin = &s_files[0]; FILE* stdout = &s_files[1]; FILE* stderr = &s_files[2]; 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) { ScopeLock _(file); @@ -79,7 +107,7 @@ int fclose(FILE* file) ScopeLock _(file); (void)fflush(file); int ret = (close(file->fd) == -1) ? EOF : 0; - file = {}; + init_closed_file(file); return ret; } diff --git a/userspace/libraries/LibC/unistd.cpp b/userspace/libraries/LibC/unistd.cpp index 262b66b8..48639ce0 100644 --- a/userspace/libraries/LibC/unistd.cpp +++ b/userspace/libraries/LibC/unistd.cpp @@ -15,10 +15,12 @@ char** environ; -extern void init_malloc(); +extern void _init_malloc(); +extern void _init_stdio(); extern "C" void _init_libc(char** _environ) { - init_malloc(); + _init_malloc(); + _init_stdio(); if (!_environ) return;