From 0cb03d7929d79f8c2051e0164676433e310597f6 Mon Sep 17 00:00:00 2001
From: Amelia Coutard <eliottulio.coutard@gmail.com>
Date: Sun, 26 Feb 2023 23:58:04 +0100
Subject: [PATCH] Revamped build system, and rewrote test module to be simpler
 and more correct (though still not actually just producing an elf. Coming
 soon)

---
 Makefile                 |  2 +-
 kernel/module.mk         | 20 +++++++-----------
 kernel/src/elf64.cpp     |  1 +
 kernel/src/elf64.hpp     |  1 +
 kernel/src/kernel.cpp    |  1 +
 test_module/linker.ld    | 44 ++++++++++++++++++++++++++++++++++++++++
 test_module/module.mk    | 39 ++++++++++++++++++++++++++++++-----
 test_module/src/test.S   |  6 ++++++
 test_module/src/test.cpp |  9 ++++++++
 test_module/test.S       | 15 --------------
 10 files changed, 104 insertions(+), 34 deletions(-)
 create mode 100644 kernel/src/elf64.cpp
 create mode 100644 kernel/src/elf64.hpp
 create mode 100644 test_module/linker.ld
 create mode 100644 test_module/src/test.S
 create mode 100644 test_module/src/test.cpp
 delete mode 100644 test_module/test.S

diff --git a/Makefile b/Makefile
index 5b2df7f..4501196 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ LDFLAGS := $(LDFLAGS) -Wall -Wextra -Werror -std=c++20 -ffreestanding
 TO_ISO :=
 TO_CLEAN :=
 
-include */module.mk
+include **/module.mk
 
 build: amycros.iso
 qemu: build
diff --git a/kernel/module.mk b/kernel/module.mk
index d503c39..e9bb8a8 100644
--- a/kernel/module.mk
+++ b/kernel/module.mk
@@ -13,20 +13,18 @@ EXEC_NAME := kernel.elf64
 TO_ISO   += isodir/boot/$(EXEC_NAME)
 TO_CLEAN += $(OUT_DIR) $(DEP_DIR)
 
-OLD_CXXFLAGS := $(CXXFLAGS)
-OLD_LDFLAGS := $(LDFLAGS)
-CXXFLAGS := $(OLD_CXXFLAGS) -mcmodel=kernel -mno-red-zone \
+LOCAL_CXXFLAGS := $(CXXFLAGS) -mcmodel=kernel -mno-red-zone \
 	-isystem /usr/include -isystem /usr/include/c++/12.2.1 \
 	-isystem /usr/include/c++/12.2.1/x86_64-pc-linux-gnu
 	# The previous two lines are a dirty hack.
-LDFLAGS := $(OLD_LDFLAGS) -T kernel/linker.ld -z max-page-size=0x1000 \
-	   -mno-red-zone -mcmodel=kernel
+LOCAL_LDFLAGS := $(LDFLAGS) -T kernel/linker.ld -z max-page-size=0x1000 \
+	-mno-red-zone -mcmodel=kernel
 
 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' | grep -v crt))
 CRTI_OBJ     := $(OUT_DIR)/lib/crti.S.o
-CRTBEGIN_OBJ := $(shell $(CXX) $(LDFLAGS) -print-file-name=crtbegin.o)
-CRTEND_OBJ   := $(shell $(CXX) $(LDFLAGS) -print-file-name=crtend.o)
+CRTBEGIN_OBJ := $(shell $(CXX) $(LOCAL_LDFLAGS) -print-file-name=crtbegin.o)
+CRTEND_OBJ   := $(shell $(CXX) $(LOCAL_LDFLAGS) -print-file-name=crtend.o)
 CRTN_OBJ     := $(OUT_DIR)/lib/crtn.S.o
 OBJS := $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(CPPOBJS) $(ASMOBJS) $(CRTEND_OBJ) $(CRTN_OBJ)
 
@@ -36,20 +34,16 @@ isodir/boot/$(EXEC_NAME): $(OUT_DIR)$(EXEC_NAME)
 
 $(OUT_DIR)$(EXEC_NAME): OBJS := $(OBJS)
 $(OUT_DIR)$(EXEC_NAME): LDLIBS := -nostdlib -lgcc
-$(OUT_DIR)$(EXEC_NAME): LDFLAGS := $(LDFLAGS)
+$(OUT_DIR)$(EXEC_NAME): LDFLAGS := $(LOCAL_LDFLAGS)
 $(OUT_DIR)$(EXEC_NAME): $(OBJS) kernel/linker.ld
 	mkdir -p "$(@D)"
 	$(CXX) $(LDFLAGS) -o "$@" $(OBJS) $(LDLIBS)
 
-
 $(OUT_DIR)%.o: DEP_DIR := $(DEP_DIR)
-$(OUT_DIR)%.o: CXXFLAGS := $(CXXFLAGS)
+$(OUT_DIR)%.o: CXXFLAGS := $(LOCAL_CXXFLAGS)
 $(OUT_DIR)%.o: $(SRC_DIR)%
 	mkdir -p $(@D)
 	mkdir -p $(dir $(DEP_DIR)$*)
 	$(CXX) $(CXXFLAGS) -c "$<" -MMD -MT "$@" -MF "$(DEP_DIR)$*.d" -o "$@"
 
 -include $(DEP_DIR)*.d
-
-CXXFLAGS := $(OLD_CXXFLAGS)
-LDFLAGS := $(OLD_LDFLAGS)
diff --git a/kernel/src/elf64.cpp b/kernel/src/elf64.cpp
new file mode 100644
index 0000000..4a8bda3
--- /dev/null
+++ b/kernel/src/elf64.cpp
@@ -0,0 +1 @@
+#include "elf64.hpp"
diff --git a/kernel/src/elf64.hpp b/kernel/src/elf64.hpp
new file mode 100644
index 0000000..6f70f09
--- /dev/null
+++ b/kernel/src/elf64.hpp
@@ -0,0 +1 @@
+#pragma once
diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp
index 998357f..d07261d 100644
--- a/kernel/src/kernel.cpp
+++ b/kernel/src/kernel.cpp
@@ -4,6 +4,7 @@
 #include "serial.hpp"
 #include "interrupts.hpp"
 #include "ring3.hpp"
+#include "elf64.hpp"
 
 os::idt<32> idt;
 extern "C" os::tss TSS;
diff --git a/test_module/linker.ld b/test_module/linker.ld
new file mode 100644
index 0000000..f94ccb2
--- /dev/null
+++ b/test_module/linker.ld
@@ -0,0 +1,44 @@
+ENTRY(_start)
+
+SECTIONS {
+	. = 1M;
+
+	. = ALIGN(4K);
+	.text ALIGN(4K) : AT(ADDR(.text)) {
+		*(.text)
+		*(.text*)
+		*(.gnu.linkonce.t*)
+		. = ALIGN(8);
+		*(.init)
+		. = ALIGN(8);
+		*(.fini)
+		. = ALIGN(8);
+		*(.ctors)
+		. = ALIGN(8);
+		*(.dtors)
+	}
+	.rodata ALIGN(4K) : AT(ADDR(.rodata)) {
+		*(.rodata)
+		*(.rodata*)
+		*(.gnu.linkonce.r*)
+	}
+	.eh_frame ALIGN(4K) : AT(ADDR(.eh_frame)) {
+		*(.eh_frame)
+	}
+	.data ALIGN(4K) : AT(ADDR(.data)) {
+		*(.data)
+		*(.data*)
+		*(.gnu.linkonce.d*)
+	}
+	.bss ALIGN(4K) : AT(ADDR(.bss)) {
+		*(.bss)
+		*(COMMON)
+		*(.bss*)
+		*(.gnu.linkonce.b*)
+	}
+	. = ALIGN(4K);
+
+	/DISCARD/ : {
+		*(.comment)
+	}
+}
diff --git a/test_module/module.mk b/test_module/module.mk
index f8c3a2a..54e04aa 100644
--- a/test_module/module.mk
+++ b/test_module/module.mk
@@ -5,10 +5,39 @@
 # So, about the license. I don't think I have a copyright on this file's code, but,
 # since I gave it the CC0 license in case I do, that doesn't matter either way.
 
+SRC_DIR := test_module/src/
+OUT_DIR := test_module/out/
+DEP_DIR := test_module/dep/
+EXEC_NAME := test.elf64
+
 TO_ISO += isodir/boot/test-module
+TO_CLEAN += $(OUT_DIR) $(DEP_DIR)
+
+LOCAL_CXXFLAGS := $(CXXFLAGS) -O0
+LOCAL_LDFLAGS := $(LDFLAGS) -T test_module/linker.ld -z max-page-size=0x1000
+
+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'))
+OBJS := $(CPPOBJS) $(ASMOBJS)
+
+isodir/boot/test-module: $(OUT_DIR)$(EXEC_NAME)
+	mkdir -p "$(@D)"
+	objdump -d "$<" | \
+	grep '  [0-9a-e]\{6\}' | sed 's/  [^ \t]*\t//' | sed 's/\t.*//' | sed 's/[ \t]\+/ /g' | tr '\n' ' ' | \
+	sed 's/  / /g' | xargs -n 1 printf '\\\\x%s\n' | xargs -n 1 printf \
+	> "$@"
+
+$(OUT_DIR)$(EXEC_NAME): OBJS := $(OBJS)
+$(OUT_DIR)$(EXEC_NAME): LDLIBS := -nostdlib -lgcc
+$(OUT_DIR)$(EXEC_NAME): LDFLAGS := $(LOCAL_LDFLAGS)
+$(OUT_DIR)$(EXEC_NAME): $(OBJS) kernel/linker.ld
+	mkdir -p "$(@D)"
+	$(CXX) $(LDFLAGS) -o "$@" $(OBJS) $(LDLIBS)
+
+$(OUT_DIR)%.o: DEP_DIR := $(DEP_DIR)
+$(OUT_DIR)%.o: CXXFLAGS := $(LOCAL_CXXFLAGS)
+$(OUT_DIR)%.o: $(SRC_DIR)%
+	mkdir -p $(@D)
+	mkdir -p $(dir $(DEP_DIR)$*)
+	$(CXX) $(CXXFLAGS) -c "$<" -MMD -MT "$@" -MF "$(DEP_DIR)$*.d" -o "$@"
 
-isodir/boot/test-module: test_module/test.S
-	mkdir -p isodir/boot
-	export TMP="$$(mktemp)"; \
-	printf "$$($(CXX) $(CXX_ARGS) -c "$<" -o $$TMP && objdump $$TMP -d | grep -A 10000000000 '<_start>' | tail -n +2 | sed 's/^ *[0-9a-f]*:\t//' | sed 's/\t.*$$//' | tr -d '\n' | sed 's/  */ /g' | sed 's/^/ /' | sed 's/ $$//' | sed 's/ /\\x/g')" > isodir/boot/test-module; \
-	rm "$$TMP"
diff --git a/test_module/src/test.S b/test_module/src/test.S
new file mode 100644
index 0000000..d2d5b04
--- /dev/null
+++ b/test_module/src/test.S
@@ -0,0 +1,6 @@
+.section .text
+
+.globl print
+print:
+	syscall
+	ret
diff --git a/test_module/src/test.cpp b/test_module/src/test.cpp
new file mode 100644
index 0000000..c694e32
--- /dev/null
+++ b/test_module/src/test.cpp
@@ -0,0 +1,9 @@
+extern "C" void print(char c);
+
+extern "C" void _start() {
+	const char str[4] = "AH\n";
+	for (int i = 0; str[i] != '\0'; i++) {
+		print(str[i]);
+	}
+	while (true) {}
+}
diff --git a/test_module/test.S b/test_module/test.S
deleted file mode 100644
index 0a9f3fa..0000000
--- a/test_module/test.S
+++ /dev/null
@@ -1,15 +0,0 @@
-.section .text
-
-.globl _start
-_start:
-	mov $65, %rdi
-	syscall
-	mov $67, %rdi
-	syscall
-	mov $65, %rdi
-	syscall
-	mov $66, %rdi
-	syscall
-	mov $10, %rdi
-	syscall
-1:	jmp 1b
-- 
2.46.0