From fcf5923cc0d407a788135f5534a63dd3274939e4 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 1 Oct 2022 20:59:22 +0200 Subject: [PATCH] WIP: Add a C Library, let's try to compile a Hosted GCC cross-compiler using this! --- .gitignore | 4 +- Makefile | 9 ++-- libs/libc/Makefile | 76 +++++++++++++++++++++++++++++++ libs/libc/bin/libc.a | Bin 0 -> 7858 bytes libs/libc/crt0.asm | 29 ++++++++++++ libs/libc/crti.asm | 11 +++++ libs/libc/crtn.asm | 7 +++ libs/libc/include/errno.h | 0 libs/libc/include/luna/syscall.h | 17 +++++++ libs/libc/include/stdio.h | 36 +++++++++++++++ libs/libc/include/stdlib.h | 25 ++++++++++ libs/libc/include/string.h | 23 ++++++++++ libs/libc/include/sys/types.h | 4 ++ libs/libc/include/time.h | 0 libs/libc/include/unistd.h | 15 ++++++ libs/libc/src/luna/syscall.cpp | 10 ++++ libs/libc/src/stdio.cpp | 45 ++++++++++++++++++ libs/libc/src/stdlib.cpp | 40 ++++++++++++++++ libs/libc/src/string.cpp | 47 +++++++++++++++++++ libs/libc/src/unistd.cpp | 21 +++++++++ tools/install-headers.sh | 13 ++++++ 21 files changed, 427 insertions(+), 5 deletions(-) create mode 100644 libs/libc/Makefile create mode 100644 libs/libc/bin/libc.a create mode 100644 libs/libc/crt0.asm create mode 100644 libs/libc/crti.asm create mode 100644 libs/libc/crtn.asm create mode 100644 libs/libc/include/errno.h create mode 100644 libs/libc/include/luna/syscall.h create mode 100644 libs/libc/include/stdio.h create mode 100644 libs/libc/include/stdlib.h create mode 100644 libs/libc/include/string.h create mode 100644 libs/libc/include/sys/types.h create mode 100644 libs/libc/include/time.h create mode 100644 libs/libc/include/unistd.h create mode 100644 libs/libc/src/luna/syscall.cpp create mode 100644 libs/libc/src/stdio.cpp create mode 100644 libs/libc/src/stdlib.cpp create mode 100644 libs/libc/src/string.cpp create mode 100644 libs/libc/src/unistd.cpp create mode 100755 tools/install-headers.sh diff --git a/.gitignore b/.gitignore index 058e67a8..1fb154f7 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ initrd/boot/moon.elf kernel/bin/moon.elf initrd/sys/moon.sym initrd/bin/** -apps/bin/** \ No newline at end of file +apps/bin/** +base/usr/include/** +base/usr/lib/** \ No newline at end of file diff --git a/Makefile b/Makefile index 20ab9997..e06ab762 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,13 @@ -build: $(LUNA_ROOT)/kernel/bin/moon.elf apps-build +build: $(LUNA_ROOT)/kernel/bin/moon.elf apps-build libc-build -clean: moon-clean initrd-clean apps-clean +clean: moon-clean initrd-clean apps-clean libc-clean initrd-clean: rm -f $(LUNA_ROOT)/initrd/boot/moon.elf $(LUNA_ROOT)/Luna.iso rm -rf $(LUNA_ROOT)/initrd/bin -install: $(LUNA_ROOT)/initrd/boot/moon.elf apps-install +install: $(LUNA_ROOT)/initrd/boot/moon.elf apps-install libc-install include kernel/Makefile -include apps/Makefile \ No newline at end of file +include apps/Makefile +include libs/libc/Makefile \ No newline at end of file diff --git a/libs/libc/Makefile b/libs/libc/Makefile new file mode 100644 index 00000000..e48f0f1d --- /dev/null +++ b/libs/libc/Makefile @@ -0,0 +1,76 @@ +LIBC_DIR := $(LUNA_ROOT)/libs/libc +LIBC_SRC := $(LIBC_DIR)/src +LIBC_OBJ := $(LIBC_DIR)/lib +LIBC_BIN := $(LIBC_DIR)/bin + +LIBC_CC := x86_64-elf-gcc +LIBC_CXX := x86_64-elf-g++ +LIBC_NASM := nasm +LIBC_AR := x86_64-elf-ar + +LIBC_CFLAGS := -Wall -Wextra -Werror -Os -ffreestanding -nostdlib -fno-omit-frame-pointer -mno-mmx -mno-sse -mno-sse2 -I$(LIBC_DIR)/include -isystem $(LIBC_DIR)/include +LIBC_CXXFLAGS := -fno-rtti -fno-exceptions +LIBC_NASMFLAGS := -felf64 + +rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) + +LIBC_CXX_SRC = $(call rwildcard,$(LIBC_SRC),*.cpp) +LIBC_C_SRC = $(call rwildcard,$(LIBC_SRC),*.c) +LIBC_NASM_SRC = $(call rwildcard,$(LIBC_SRC),*.asm) + +LIBC_OBJS = $(patsubst $(LIBC_SRC)/%.cpp, $(LIBC_OBJ)/%.cpp.o, $(LIBC_CXX_SRC)) +LIBC_OBJS += $(patsubst $(LIBC_SRC)/%.c, $(LIBC_OBJ)/%.c.o, $(LIBC_C_SRC)) +LIBC_OBJS += $(patsubst $(LIBC_SRC)/%.asm, $(LIBC_OBJ)/%.asm.o, $(LIBC_NASM_SRC)) + +$(LIBC_OBJ)/%.cpp.o: $(LIBC_SRC)/%.cpp + @mkdir -p $(@D) + $(LIBC_CXX) $(LIBC_CFLAGS) $(LIBC_CXXFLAGS) -o $@ -c $^ + +$(LIBC_OBJ)/%.c.o: $(LIBC_SRC)/%.c + @mkdir -p $(@D) + $(LIBC_CC) $(LIBC_CFLAGS) -o $@ -c $^ + +$(LIBC_OBJ)/%.asm.o: $(LIBC_SRC)/%.asm + @mkdir -p $(@D) + $(LIBC_NASM) $(LIBC_NASMFLAGS) -o $@ $^ + +$(LIBC_BIN)/libc.a: $(LIBC_OBJS) + @mkdir -p $(@D) + $(LIBC_AR) rcs $@ $(LIBC_OBJS) + +$(LIBC_BIN)/crt0.o: $(LIBC_DIR)/crt0.asm + @mkdir -p $(@D) + $(LIBC_NASM) $(LIBC_NASMFLAGS) -o $@ $^ + +$(LIBC_BIN)/crti.o: $(LIBC_DIR)/crti.asm + @mkdir -p $(@D) + $(LIBC_NASM) $(LIBC_NASMFLAGS) -o $@ $^ + +$(LIBC_BIN)/crtn.o: $(LIBC_DIR)/crtn.asm + @mkdir -p $(@D) + $(LIBC_NASM) $(LIBC_NASMFLAGS) -o $@ $^ + +libc-build: $(LIBC_BIN)/crt0.o $(LIBC_BIN)/crti.o $(LIBC_BIN)/crtn.o $(LIBC_BIN)/libc.a + +$(LUNA_ROOT)/base/usr/lib/libc.a: $(LIBC_BIN)/libc.a + @mkdir -p $(@D) + cp $^ $@ + +$(LUNA_ROOT)/base/usr/lib/crt0.o: $(LIBC_BIN)/crt0.o + @mkdir -p $(@D) + cp $^ $@ + +$(LUNA_ROOT)/base/usr/lib/crti.o: $(LIBC_BIN)/crti.o + @mkdir -p $(@D) + cp $^ $@ + +$(LUNA_ROOT)/base/usr/lib/crtn.o: $(LIBC_BIN)/crtn.o + @mkdir -p $(@D) + cp $^ $@ + +libc-install: $(LUNA_ROOT)/base/usr/lib/libc.a $(LUNA_ROOT)/base/usr/lib/crt0.o $(LUNA_ROOT)/base/usr/lib/crti.o $(LUNA_ROOT)/base/usr/lib/crtn.o + +libc-clean: + rm -rf $(LIBC_OBJ)/* + rm -rf $(LIBC_BIN)/* + rm -f $(LUNA_ROOT)/base/usr/lib/libc.a \ No newline at end of file diff --git a/libs/libc/bin/libc.a b/libs/libc/bin/libc.a new file mode 100644 index 0000000000000000000000000000000000000000..e9905a6c478ae3301c50dec87d1b5a8ea8a27a68 GIT binary patch literal 7858 zcmdT}O>9(E6u#xRK#LU(0rBTGqJo-Xrj*(e#8Li+gcvk7=>kHh!yDQ#{mIM&i!l)+ zF_grFg$ougSh!$eT)S|AsX<(rpmD*{n3#}|7<8dsnAG##cfL2bxAR~IjggbSckcb} zIp^Mc?!D*SH|^e4td>T1uih3cq+DNLZ{Ln=b|4!B@+aiJgJ65MPZfq&8)F_frtNg& zr~P?jI`*eO>wY$-nP=nY#?+tjaJ)2i#t5s0k*P)1N;m-q5Ugmy(rDEjJ61bWD-|o1 ztSOF6RwENmk42^!DVrQKe9O~G(FES;9_LrN=#Kx8jNsk;zXu2 zHI4q^(Vy9#fmyZR$0m#(c4~Ue4QM-mEdJ zO<`s(_ibU|`=~R2Vb|LH`CaXW`LAyOI-B6D^5=Uk_B*h%{U%yon7?}akHXfu*};P| zbA_2d3p2mmg2_WO-xNMN+@|HLM`s7wQfQmIu)Z*V?c5L1%JW^&zjMu?@1wK1tFz|7 zo;^E*EeBp7+#2M1GPz9Fm`CjxWe>gcrfHk*YTMMYvi+h=tV?j&UY0f}2PP_(s0VDX zVh<~a-jJ39@K@J%eYoUc=ZZlwE>*No0~gwimu=tEx#C#d4x5*N3pwtL0q>19SZ02k z_h4IH+F*q`q-C9hb8e3)&N}D!nBp&5i^gz{-HN}gc%XcX;zzY^=O^WDiodUTGOzlk z#Ib7fbjg~kon^w8%k$TKOm8_j`XD~y;I4e2_!8lGNWEGhPQS2U;`GZAPo92x*TdNz!BR)h%xsf zblXbo?i6`9b|-x}PI50EfervmwP63FgqWM#pCun zc}nFeNB)H3>s0~g0JK>i*vGvU#CdI%GH~dD=!1-ufj?={x;)Mn@NN&6k0@?B{jhVt z^zQz72U9qUAdD9e@2Bek3i)_o(Ktr9ablN;(=S6FPXAOqoc=lM;q=eP9!~#U@o@U* zLA$qNpSZ;RKrHRvI<1S4RYAl==z@cARzYd^*5h&WqPO3F+P$?|{j_^4_3xFN((bL( zI`S{P8F2oD)9$TT)PLMZ&}-%1npH=&D`yU3|MWj`j)%No`{(%~?)yLO-g;OA%0VhB z_w^-Aj7`>4Q<9td1{&X6bAA2sPhCOtxv6VeeGqwDjPI?;LYj#jR$y`hZ}d}0Q@@3< zOXLoo0Tm0f9OIEIcea5X;}GwHu*bdQ>VB!ZTnEVA@a$=I5ra-EISjED zxq-xaA%+8IoqVI>+@lcXI{WUr?N}p1wj1fIMOuh<5s= z44g5YGr^e$j{ZR$4{~0-nH&E?+3YWqfwj6gm-Tu$`z?4l{ddH}>Axutr~l4*IQ@6Y z!|A`zJe>Z!>f!X?j~-6{-7P2npT4u6*71{ZKd{~{1z_Ai#7iuA+}BV0&T3X4xezw9 zUO&{oS1wEY&YD(xKY4b!&j_b|XYn_fJ1W@fch-#?iydBBHT!y4&Gg!mS z)!gs+j4NGYpL@y0=m!@YQm-(kYIPBV&sxbL9U_ldOJbkR<`BvUY6tc}$vEqa7XK5d z;eUjT39Qz?ACozr2PFpLjJQ-^nHcRB2277kBKk&BT3GP)(_&z=`e`wc`u7_HM|Ifb zoCRYL>uE9YvQBhZ1zU}QH&pM6a`f9u44l^faW`_w_dnLxUpp(WaffH0HhlfR0k|xf A3;+NC literal 0 HcmV?d00001 diff --git a/libs/libc/crt0.asm b/libs/libc/crt0.asm new file mode 100644 index 00000000..be8192e0 --- /dev/null +++ b/libs/libc/crt0.asm @@ -0,0 +1,29 @@ +section .text + +extern _init +extern main +extern _fini +extern exit + +global _start +_start: + ; Set up end of the stack frame linked list. + xor rbp, rbp + push rbp ; rip=0 + push rbp ; rbp=0 + mov rbp, rsp + + call _init + + mov rdi, 0 ; argc = 0 + mov rsi, 0 ; argv = 0 + + call main + + push rax + + call _fini + + pop rdi + + call exit \ No newline at end of file diff --git a/libs/libc/crti.asm b/libs/libc/crti.asm new file mode 100644 index 00000000..6b5aed06 --- /dev/null +++ b/libs/libc/crti.asm @@ -0,0 +1,11 @@ +section .init +global _init +_init: + push rbp + mov rbp, rsp + +section .fini +global _fini +_fini: + push rbp + mov rbp, rsp \ No newline at end of file diff --git a/libs/libc/crtn.asm b/libs/libc/crtn.asm new file mode 100644 index 00000000..5d8b3e55 --- /dev/null +++ b/libs/libc/crtn.asm @@ -0,0 +1,7 @@ +section .init + pop rbp + ret + +section .fini + pop rbp + ret \ No newline at end of file diff --git a/libs/libc/include/errno.h b/libs/libc/include/errno.h new file mode 100644 index 00000000..e69de29b diff --git a/libs/libc/include/luna/syscall.h b/libs/libc/include/luna/syscall.h new file mode 100644 index 00000000..938008f0 --- /dev/null +++ b/libs/libc/include/luna/syscall.h @@ -0,0 +1,17 @@ +#ifndef _SYSCALL_H +#define _SYSCALL_H + +#define SYS_exit 0 + +#ifdef __cplusplus +extern "C" +{ +#endif + + void __syscall0(int sys_num); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libc/include/stdio.h b/libs/libc/include/stdio.h new file mode 100644 index 00000000..6baf5713 --- /dev/null +++ b/libs/libc/include/stdio.h @@ -0,0 +1,36 @@ +#ifndef _STDIO_H +#define _STDIO_H + +#include +#include + +#define SEEK_SET 0 + +typedef struct +{ + int unused; +} FILE; + +#ifdef __cplusplus +extern "C" +{ +#endif + + extern FILE* stderr; +#define stderr stderr + int fclose(FILE*); + int fflush(FILE*); + FILE* fopen(const char*, const char*); + int fprintf(FILE*, const char*, ...); + size_t fread(void*, size_t, size_t, FILE*); + int fseek(FILE*, long, int); + long ftell(FILE*); + size_t fwrite(const void*, size_t, size_t, FILE*); + void setbuf(FILE*, char*); + int vfprintf(FILE*, const char*, va_list); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libc/include/stdlib.h b/libs/libc/include/stdlib.h new file mode 100644 index 00000000..7c27024d --- /dev/null +++ b/libs/libc/include/stdlib.h @@ -0,0 +1,25 @@ +#ifndef _STDLIB_H +#define _STDLIB_H + +#include + +#define noreturn __attribute__((noreturn)) + +#ifdef __cplusplus +extern "C" +{ +#endif + + noreturn void abort(); + noreturn void exit(int); + int atexit(void (*)(void)); + int atoi(const char*); + void free(void*); + char* getenv(const char*); + void* malloc(size_t); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libc/include/string.h b/libs/libc/include/string.h new file mode 100644 index 00000000..a20b2fe7 --- /dev/null +++ b/libs/libc/include/string.h @@ -0,0 +1,23 @@ +#ifndef _STRING_H +#define _STRING_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + void* memcpy(void*, const void*, size_t); + void* memset(void*, int, size_t); + char* strcpy(char*, const char*); + size_t strlen(const char*); + char* strcpy(char*, const char*); + char* strchr(const char*, int); + char* strcat(char*, const char*); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libc/include/sys/types.h b/libs/libc/include/sys/types.h new file mode 100644 index 00000000..6147106a --- /dev/null +++ b/libs/libc/include/sys/types.h @@ -0,0 +1,4 @@ +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H +typedef long int pid_t; +#endif \ No newline at end of file diff --git a/libs/libc/include/time.h b/libs/libc/include/time.h new file mode 100644 index 00000000..e69de29b diff --git a/libs/libc/include/unistd.h b/libs/libc/include/unistd.h new file mode 100644 index 00000000..cdc2e435 --- /dev/null +++ b/libs/libc/include/unistd.h @@ -0,0 +1,15 @@ +#ifndef _UNISTD_H +#define _UNISTD_H +#include +#ifdef __cplusplus +extern "C" +{ +#endif + int execv(const char*, char* const[]); + int execve(const char*, char* const[], char* const[]); + int execvp(const char*, char* const[]); + pid_t fork(void); +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/libs/libc/src/luna/syscall.cpp b/libs/libc/src/luna/syscall.cpp new file mode 100644 index 00000000..3328d381 --- /dev/null +++ b/libs/libc/src/luna/syscall.cpp @@ -0,0 +1,10 @@ +#include +#include + +extern "C" +{ + void __syscall0(int sys_num) + { + asm volatile("int $0x42" : : "a"(sys_num)); + } +} \ No newline at end of file diff --git a/libs/libc/src/stdio.cpp b/libs/libc/src/stdio.cpp new file mode 100644 index 00000000..0b548b8e --- /dev/null +++ b/libs/libc/src/stdio.cpp @@ -0,0 +1,45 @@ +#include + +extern "C" +{ + int fclose(FILE*) + { + return -1; + } + int fflush(FILE*) + { + return -1; + } + FILE* fopen(const char*, const char*) + { + return 0; + } + int fprintf(FILE*, const char*, ...) + { + return -1; + } + size_t fread(void*, size_t, size_t, FILE*) + { + return 0; + } + int fseek(FILE*, long, int) + { + return -1; + } + long ftell(FILE*) + { + return -1; + } + size_t fwrite(const void*, size_t, size_t, FILE*) + { + return 0; + } + void setbuf(FILE*, char*) + { + return; + } + int vfprintf(FILE*, const char*, va_list) + { + return -1; + } +} \ No newline at end of file diff --git a/libs/libc/src/stdlib.cpp b/libs/libc/src/stdlib.cpp new file mode 100644 index 00000000..31f7d6a5 --- /dev/null +++ b/libs/libc/src/stdlib.cpp @@ -0,0 +1,40 @@ +#include +#include + +#define maybe_unused __attribute__((maybe_unused)) +#define unused __attribute__((unused)) + +extern "C" +{ + noreturn void abort() + { + exit(-1); + } + + noreturn void exit(int) + { + __syscall0(SYS_exit); + __builtin_unreachable(); + } + + int atexit(void (*)(void)) + { + return -1; + } + int atoi(const char*) + { + return 0; + } + void free(void*) + { + return; + } + char* getenv(const char*) + { + return 0; + } + void* malloc(size_t) + { + return 0; + } +} \ No newline at end of file diff --git a/libs/libc/src/string.cpp b/libs/libc/src/string.cpp new file mode 100644 index 00000000..d776c0e5 --- /dev/null +++ b/libs/libc/src/string.cpp @@ -0,0 +1,47 @@ +#include + +extern "C" +{ + void* memcpy(void* dest, const void* src, size_t n) + { + for (size_t i = 0; i < n; ++i) { *((char*)dest + i) = *((char*)src + i); } + return dest; + } + + void* memset(void* dest, int c, size_t n) + { + for (size_t i = 0; i < n; ++i) { *((char*)dest + i) = (char)c; } + return dest; + } + + size_t strlen(const char* s) + { + const char* i = s; + for (; *i; ++i) + ; + return (i - s); + } + + char* strcpy(char* dest, const char* src) + { + memcpy(dest, src, strlen(src) + 1); + return dest; + } + + char* strcat(char* dest, const char* src) + { + size_t dest_len = strlen(dest); + size_t i; + + for (i = 0; *(src + i); i++) *(char*)(dest + dest_len + i) = *(char*)(src + i); + + *(char*)(dest + dest_len + i) = '\0'; + + return dest; + } + + char* strchr(const char*, int) + { + return 0; + } +} \ No newline at end of file diff --git a/libs/libc/src/unistd.cpp b/libs/libc/src/unistd.cpp new file mode 100644 index 00000000..7e2dc820 --- /dev/null +++ b/libs/libc/src/unistd.cpp @@ -0,0 +1,21 @@ +#include + +extern "C" +{ + int execv(const char*, char* const[]) + { + return -1; + } + int execve(const char*, char* const[], char* const[]) + { + return -1; + } + int execvp(const char*, char* const[]) + { + return -1; + } + pid_t fork(void) + { + return -1; + } +} \ No newline at end of file diff --git a/tools/install-headers.sh b/tools/install-headers.sh new file mode 100755 index 00000000..26b7d736 --- /dev/null +++ b/tools/install-headers.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +set -e +source $(dirname $0)/env.sh + +cd $LUNA_ROOT + +mkdir -p base +mkdir -p base/usr/include +mkdir -p base/usr/include/moon + +cp -RT libs/libc/include base/usr/include +cp -RT kernel/include base/usr/include/moon \ No newline at end of file