Add complete support for calling global constructors

This commit is contained in:
Baptiste Wicht 2013-11-10 21:09:36 +01:00
parent b7185edf8a
commit 31a75bfcbe
9 changed files with 112 additions and 2 deletions

View File

@ -1,4 +1,5 @@
CC=x86_64-elf-g++
AS=x86_64-elf-as
WARNING_FLAGS=-Wall -Wextra -pedantic -Wold-style-cast -Wshadow
CPP_FLAGS=-masm=intel -Iinclude/ -nostdlib -O1 -std=c++11 -fno-exceptions -fno-rtti -ffreestanding -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow $(WARNING_FLAGS)
@ -10,13 +11,18 @@ KERNEL_O_FILES=kernel.o keyboard.o console.o kernel_utils.o timer.o shell.o util
CRTBEGIN_OBJ:=$(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o)
CRTEND_OBJ:=$(shell $(CC) $(CFLAGS) -print-file-name=crtend.o)
LINK_O_FILES=$(KERNEL_O_FILES)
LINK_O_FILES=crti.o $(CRTBEGIN_OBJ) $(KERNEL_O_FILES) $(CRTEND_OBJ) crtn.o
kernel.bin: $(LINK_O_FILES)
$(CC) $(KERNEL_LINK_FLAGS) -o kernel.bin.o $(LINK_O_FILES)
objcopy -R .note -R .comment -S -O binary kernel.bin.o kernel.bin
crti.o: src/crti.s
$(AS) -c src/crti.s -o crti.o
crtn.o: src/crtn.s
$(AS) -c src/crtn.s -o crtn.o
kernel.o: src/kernel.cpp
$(CC) $(KERNEL_FLAGS) -c src/kernel.cpp -o kernel.o

View File

@ -14,6 +14,7 @@ namespace keyboard {
const char KEY_ENTER = 0x1C;
const char KEY_BACKSPACE = 0x0E;
const char KEY_UP = 0x48;
void install_driver();
char get_char();

View File

@ -16,4 +16,21 @@ void operator delete(void* p);
void* operator new[](uint64_t size);
void operator delete[](void* p);
#define ATEXIT_MAX_FUNCS 128
extern "C" {
typedef int uarch_t;
struct atexit_func_entry_t {
void (*destructor_func)(void *);
void *obj_ptr;
void *dso_handle;
};
int __cxa_atexit(void (*f)(void *), void *objptr, void *dso);
void __cxa_finalize(void *f);
}
#endif

View File

@ -40,6 +40,8 @@ public:
rhs.data = nullptr;
rhs._size = 0;
rhs._capacity = 0;
return *this;
}
~vector(){
@ -54,6 +56,10 @@ public:
return _size;
}
size_type capacity(){
return _capacity;
}
//Modifiers
void push_back(value_type& element){

18
kernel/src/crti.s Normal file
View File

@ -0,0 +1,18 @@
/* x86_64 crti.s */
.section .init
.global _init
.type _init, @function
_init:
push %rbp
movq %rsp, %rbp
/* gcc will nicely put the contents of crtbegin.o's .init section here. */
.section .fini
.global _fini
.type _fini, @function
_fini:
push %rbp
movq %rsp, %rbp
/* gcc will nicely put the contents of crtbegin.o's .fini section here. */

11
kernel/src/crtn.s Normal file
View File

@ -0,0 +1,11 @@
/* x86_64 crtn.s */
.section .init
/* gcc will nicely put the contents of crtend.o's .init section here. */
popq %rbp
ret
.section .fini
/* gcc will nicely put the contents of crtend.o's .fini section here. */
popq %rbp
ret

View File

@ -13,12 +13,17 @@
extern "C" {
void _init();
void __attribute__ ((section ("main_section"))) kernel_main(){
load_memory_map();
init_memory_manager();
install_timer();
keyboard::install_driver();
disks::detect_disks();
_init();
init_shell();
return;

View File

@ -14,9 +14,12 @@
#include "utils.hpp"
#include "memory.hpp"
#include "disks.hpp"
#include "vector.hpp"
namespace {
vector<char*> history;
//Declarations of the different functions
void reboot_command(const char* params);
@ -84,6 +87,8 @@ void start_shell(){
}
k_print("thor> ");
} else if(key == keyboard::KEY_UP){
//TODO
} else if(key == keyboard::KEY_BACKSPACE){
if(current_input_length > 0){
k_print('\b');
@ -386,6 +391,7 @@ void init_shell(){
clear_command(0);
k_print("thor> ");
k_print_line(history.capacity());
start_shell();
}

View File

@ -23,3 +23,43 @@ void* operator new[](uint64_t size){
void operator delete[](void* p){
return k_free(p);
}
extern "C" {
atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS];
uarch_t __atexit_func_count = 0;
int __cxa_atexit(void (*f)(void *), void *objptr, void *dso){
if (__atexit_func_count >= ATEXIT_MAX_FUNCS) {
return -1;
}
__atexit_funcs[__atexit_func_count].destructor_func = f;
__atexit_funcs[__atexit_func_count].obj_ptr = objptr;
__atexit_funcs[__atexit_func_count].dso_handle = dso;
__atexit_func_count++;
return 0; /*I would prefer if functions returned 1 on success, but the ABI says...*/
}
void __cxa_finalize(void *f){
uarch_t i = __atexit_func_count;
if (!f){
while (i--){
if (__atexit_funcs[i].destructor_func){
(*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
}
}
return;
}
for ( ; i >= 0; --i){
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
if (__atexit_funcs[i].destructor_func == f){
(*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
__atexit_funcs[i].destructor_func = 0;
}
#pragma GCC diagnostic pop
}
}
}