From 0e5f0d352aaa8f9c365447bcfeda9bb889ab9b76 Mon Sep 17 00:00:00 2001 From: Amelia Coutard Date: Sun, 8 May 2022 20:41:23 +0200 Subject: [PATCH] Added support for global constructors and destructors --- Makefile | 13 +++++++++---- linker.ld | 22 +++++++++++++++++++--- src/boot.S | 9 +++++++++ src/crti.S | 15 +++++++++++++++ src/crtn.S | 9 +++++++++ 5 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 src/crti.S create mode 100644 src/crtn.S diff --git a/Makefile b/Makefile index 7c6c8c0..cb116a3 100644 --- a/Makefile +++ b/Makefile @@ -12,12 +12,17 @@ CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -Werror -std=c++20 \ LDFLAGS ?= -O2 LDFLAGS := $(LDFLAGS) -Wall -Wextra -Werror -std=c++20 \ - -ffreestanding -T linker.ld -z max-page-size=0x1000 + -ffreestanding -T linker.ld -z max-page-size=0x1000 \ + -mno-red-zone -mcmodel=large # Normally has no effect, but is used to change the multilib libgcc, to use mcmodel=large and be able to use global constructors and destructors. LDLIBS := $(LDLIBS) -nostdlib -lgcc CPPOBJS := $(patsubst $(SRC_DIR)%,$(OUT_DIR)%.o,$(shell find $(SRC_DIR) -name '*.cpp')) -ASMOBJS := $(patsubst $(SRC_DIR)%,$(OUT_DIR)%.o,$(shell find $(SRC_DIR) -name '*.S')) +ASMOBJS := $(patsubst $(SRC_DIR)%,$(OUT_DIR)%.o,$(shell find $(SRC_DIR) -name '*.S' -and -not -name 'crti.S' -and -not -name 'crtn.S')) OBJECTS := $(CPPOBJS) $(ASMOBJS) +CRTI_OBJ := $(OUT_DIR)crti.S.o +CRTBEGIN_OBJ := $(shell $(CXX) $(LDFLAGS) -print-file-name=crtbegin.o) +CRTEND_OBJ := $(shell $(CXX) $(LDFLAGS) -print-file-name=crtend.o) +CRTN_OBJ := $(OUT_DIR)crtn.S.o build: $(OUT_DIR)amycros.iso qemu: build @@ -33,9 +38,9 @@ clean: -rm -rf $(OUT_DIR) $(DEPS_DIR) isodir -$(OUT_DIR)kernel.elf64: $(OBJECTS) linker.ld +$(OUT_DIR)kernel.elf64: $(OBJECTS) $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(CRTEND_OBJ) $(CRTN_OBJ) linker.ld mkdir -p $(OUT_DIR) - $(CXX) $(LDFLAGS) -o "$@" $(OBJECTS) $(LDLIBS) + $(CXX) $(LDFLAGS) -o "$@" $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(OBJECTS) $(CRTEND_OBJ) $(CRTN_OBJ) $(LDLIBS) $(OUT_DIR)%.o: $(SRC_DIR)% mkdir -p $(@D) diff --git a/linker.ld b/linker.ld index 7b57d1e..4c35e41 100644 --- a/linker.ld +++ b/linker.ld @@ -17,19 +17,35 @@ SECTIONS { .text ALIGN(4K) : AT(ADDR(.text) - KERNEL_VMA) { *(.text) + *(.text*) + *(.gnu.linkonce.t*) + . = ALIGN(8); + *(.init) + . = ALIGN(8); + *(.fini) + . = ALIGN(8); + *(.ctors) + . = ALIGN(8); + *(.dtors) } .rodata ALIGN(4K) : AT(ADDR(.rodata) - KERNEL_VMA) { + *(.rodata) *(.rodata*) - } - .data ALIGN(4K) : AT(ADDR(.data) - KERNEL_VMA) { - *(.data) + *(.gnu.linkonce.r*) } .eh_frame ALIGN(4K) : AT(ADDR(.eh_frame) - KERNEL_VMA) { *(.eh_frame) } + .data ALIGN(4K) : AT(ADDR(.data) - KERNEL_VMA) { + *(.data) + *(.data*) + *(.gnu.linkonce.d*) + } .bss ALIGN(4K) : AT(ADDR(.bss) - KERNEL_VMA) { *(.bss) *(COMMON) + *(.bss*) + *(.gnu.linkonce.b*) } . = ALIGN(4K); _kernel_phys_end = . - KERNEL_VMA; diff --git a/src/boot.S b/src/boot.S index ec6a75f..1bdfdba 100644 --- a/src/boot.S +++ b/src/boot.S @@ -237,6 +237,15 @@ _start: mov $PML4T - KERNEL_VMA, %rax mov %rax, %cr3 + call _init + mov %r14, %rsi mov %r15, %rdi call kmain # With the two arguments popped earlier. + + # Should never reach that point, but, oh well. + call _fini + + cli +1: hlt + jmp 1b diff --git a/src/crti.S b/src/crti.S new file mode 100644 index 0000000..7d0c60b --- /dev/null +++ b/src/crti.S @@ -0,0 +1,15 @@ +.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. */ diff --git a/src/crtn.S b/src/crtn.S new file mode 100644 index 0000000..2880ebb --- /dev/null +++ b/src/crtn.S @@ -0,0 +1,9 @@ +.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 -- 2.47.0