From 5db066eb5184cc45e7634838b5b0b8c67cb2ae25 Mon Sep 17 00:00:00 2001 From: Danny Holman Date: Wed, 5 Jun 2024 13:47:01 -0500 Subject: libc: create a skeleton libc and build targets Create build targets for a skeleton libc that only includes enough functionality to get a cross compiler running. Signed-off-by: Danny Holman --- Makefile | 26 +++++++ include/stdint.h | 32 ++++++++ include/unistd.h | 143 ++++++++++++++++++++++++++++++++++++ libc/Makefile | 70 ++++++++++++++++++ libc/arch/i386/crti.s | 14 ++++ libc/arch/i386/crtn.s | 7 ++ libc/arch/i386/include/bits/types.h | 41 +++++++++++ libc/arch/i386/make.config | 6 ++ libc/init.c | 2 + libc/unistd.c | 4 + 10 files changed, 345 insertions(+) create mode 100644 Makefile create mode 100644 include/stdint.h create mode 100644 include/unistd.h create mode 100644 libc/Makefile create mode 100644 libc/arch/i386/crti.s create mode 100644 libc/arch/i386/crtn.s create mode 100644 libc/arch/i386/include/bits/types.h create mode 100644 libc/arch/i386/make.config create mode 100644 libc/init.c create mode 100644 libc/unistd.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..373bc3c --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +ROOT:=$(PWD) +SYS_INCLUDE:=-I$(ROOT)/include +SYS_ROOT?=$(ROOT)/sysroot +export SYS_INCLUDE +export SYS_ROOT +export ROOT + +ARCH?=i386 +export ARCH + +SUBDIRS?=libc \ + +.PHONY: all install clean + +all: + for d in $(SUBDIRS); do $(MAKE) -C $$d; done + +install: + install -d $(SYS_ROOT)/usr + install -d $(SYS_ROOT)/lib + install -d $(SYS_ROOT)/bin + install -d $(SYS_ROOT)/sbin + for d in $(SUBDIRS); do $(MAKE) -C $$d install; done + +clean: + for d in $(SUBDIRS); do $(MAKE) -C $$d clean; done diff --git a/include/stdint.h b/include/stdint.h new file mode 100644 index 0000000..4f6e71d --- /dev/null +++ b/include/stdint.h @@ -0,0 +1,32 @@ +#ifndef STDINT_H +#define STDINT_H + +#include + +#define INT8_MIN (-1-0x7F) +#define INT16_MIN (-1-0x7FFF) +#define INT32_MIN (-1-0x7FFFFFFF) +#define INT64_MIN (-1-0x7FFFFFFFFFFFFFFF) + +#define INT8_MAX (0x7F) +#define INT16_MAX (0x7FFF) +#define INT32_MAX (0x7FFFFFFF) +#define INT64_MAX (0x7FFFFFFFFFFFFFFF) + +#define UINT8_MAX (0xFF) +#define UINT16_MAX (0xFFFF) +#define UINT32_MAX (0xFFFFFFFF) +#define UINT64_MAX (0xFFFFFFFFFFFFFFFF) + +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST64_MIN INT64_MIN + +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST64_MAX INT64_MAX + +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +#endif diff --git a/include/unistd.h b/include/unistd.h new file mode 100644 index 0000000..8c7eae4 --- /dev/null +++ b/include/unistd.h @@ -0,0 +1,143 @@ +#ifndef UNISTD_H +#define UNISTD_H + +#include +#include +#include + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#define SEEK_DATA 3 +#define SEEK_HOLE 4 + +#define NULL ((void*)0) + +#define F_OK 0 +#define R_OK 4 +#define W_OK 2 +#define X_OK 1 + +int pipe(); +int pipe2(); +int close(int fildes); +int dup(int fildes); +int dup2(); +int dup3(); +off_t lseek(); +int fsync(); +int fdatasync(); + +ssize_t read(int fildes, void *buf, size_t nbyte); +ssize_t write(int fildes, const void *buf, size_t nbyte); +ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset); +ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset); + +int chown(const char *path, uid_t owner, gid_t group); +int fchown(int fildes, uid_t owner, gid_t group); +int lchown(const char *path, uid_t owner, gid_t group); +int fchownat(int fildes, const char *path, uid_t owner, gid_t group); + +int link(const char *target, const char *lpath); +int linkat(int target_fd, const char *tpath, int link_fd, const char *lpath); +int symlink(const char *target, const char *lpath); +int symlinkat(const char *target, int fildes, const char *lpath); +ssize_t readlink(const char* __restrict path, char* __restrict buf, size_t bufsz); +ssize_t readlinkat(int fildes, const char* __restrict path, char* __restrict buf, size_t bufsz); +int unlink(const char *lpath); +int unlinkat(int fildes, const char *lpath, int flag); +int rmdir(const char *path); +int truncate(const char *path, off_t length); +int ftruncate(int fildes, off_t length); + +int access(const char *path, int amode); +int faccessat(int fildes, const char *path, int amode, int flag); + +int chdir(const char *path); +int fchdir(int fildes); +char* getcwd(char *buf, size_t bufsz); + +unsigned int alarm(unsigned int seconds); +unsigned int sleep(unsigned int seconds); +unsigned int ualarm(useconds_t usec); +unsigned int usleep(useconds_t usec); +int pause(void); + +pid_t fork(void); +pid_t vfork(void); +void _exit(int status); +int execve(const char *pathname, char* const argv[], char* const envp[]); +int execv(const char *pathname, char* const argv[]); +int execle(const char *pathname, const char *argv, ...); +int execl(const char *pathname, const char *argv, ...); +int execvp(const char *pathname, char* const argv[]); +int execvpe(const char *pathname, char* const argv[], char* const envp[]); +int execlp(const char *pathname, char* const argv[], ...); +int fexecve(int fildes, char* const argv[], char* const envp[]); + +pid_t getpid(void); +pid_t getppid(void); +pid_t getpgrp(void); +pid_t getpgid(pid_t); +int setpgid(pid_t pid, pid_t pgid); +pid_t setsid(void); +pid_t getsid(pid_t pid); +char* ttyname(int fildes); +int ttyname_r(int fildes, char *buf, size_t bufsz); +int isatty(int fildes); +pid_t tcgetpgrp(int fildes); + +uid_t getuid(void); +uid_t geteuid(void); +gid_t getgid(void); +gid_t getegid(void); +int getgroups(int gidsetsize, gid_t grouplist[]); +int setuid(uid_t uid); +int seteuid(uid_t euid); +int setgid(gid_t gid); +int setegid(gid_t egid); + +char* getlogin(void); +int getlogin_r(char *buf, size_t bufsz); +char* ctermid(char *buf); + +long int pathconf(const char *path, int name); +long int fpathconf(int fildes, int name); +long int sysconf(int name); +size_t confstr(int name, char *buf, size_t bufsz); + +int setreuid(uid_t ruid, uid_t euid); +int setregid(gid_t rgid, gid_t egid); +int lockf(int fildes, int op, off_t length); + +int nice(int incr); +void sync(void); +pid_t setpgrp(void); +void swab(const void* __restrict from, void* __restrict to, ssize_t n); + +int brk(void *addr); +void* sbrk(intptr_t incr); + +int vhangup(void); +int chroot(const char *path); +int getpagesize(void); +int getdtablesize(void); + +int gethostname(char *buf, size_t bufsz); +int sethostname(const char *name, size_t len); +int getdomainname(char *buf, size_t bufsz); +int setdomainname(const char *name, size_t len); +int daemon(int nochdir, int noclose); + +char* getusershell(void); +void setusershell(void); +void endusershell(void); + +int acct(const char *path); +int getentropy(void *buffer, size_t bufsz); + +#endif diff --git a/libc/Makefile b/libc/Makefile new file mode 100644 index 0000000..cc7fa8d --- /dev/null +++ b/libc/Makefile @@ -0,0 +1,70 @@ +INCLUDE?=$(SYS_INCLUDE) +CFLAGS?=-fPIC +LDFLAGS?=-nostdlib -shared +LIBS?=-lgcc + +# -- Do not edit below this line -- + +CC:=i686-boxos-gcc +VERSION:="$(shell git describe --abbrev=4 --dirty --always --tags)" +INCLUDE:=$(INCLUDE) +CFLAGS:=$(CFLAGS) -Wall -Wextra -DVERSION=\"$(VERSION)\" -ggdb +LDFLAGS:=$(LDFLAGS) +LIBS:=$(LIBS) + +ARCHDIR=arch/$(ARCH) + +include $(ARCHDIR)/make.config + +CFLAGS:=$(CFLAGS) $(LIBC_ARCH_CFLAGS) +LDFLAGS:=$(LDFLAGS) $(LIBC_ARCH_LDFLAGS) +LIBS:=$(LIBS) $(LIBC_ARCH_LIBS) + +LIBC=libc.so + +LIBC_OBJS=$(LIBC_ARCH_OBJS) \ + init.o \ + unistd.o \ + +OBJS=$(ARCHDIR)/crti.o \ + $(LIBC_OBJS) \ + $(ARCHDIR)/crtn.o \ + +LINK_LIST=$(LDFLAGS) \ + $(OBJS) \ + $(LIBS) \ + +.PHONY: all clean install install-headers +.SUFFIXES: .o .c .s + +all: $(LIBC) + +$(LIBC): $(OBJS) + @$(CC) -o $@ $(LINK_LIST) + @echo [LD] $@ + +.c.o: + @$(CC) -MD -c $< -o $@ $(CFLAGS) $(INCLUDE) + @echo [CC] $@ + +.s.o: + @$(CC) -MD -c $< -o $@ $(CFLAGS) $(INCLUDE) + @echo [AS] $@ + +install: install-headers + install -m 755 $(LIBC) $(SYS_ROOT)/lib + +install-headers: + install -d $(SYS_ROOT)/usr/include + install -d $(SYS_ROOT)/usr/include/sys + install -d $(SYS_ROOT)/usr/include/arpa + for f in $(ROOT)/include/*; do install -m 644 "$$f" $(SYS_ROOT)/usr/include/; done + for f in $(ROOT)/include/sys/*; do install -m 644 "$$f" $(SYS_ROOT)/usr/include/sys/; done + for f in $(ROOT)/include/arpa/*; do install -m 644 "$$f" $(SYS_ROOT)/usr/include/arpa/; done + +clean: + $(RM) $(LIBC) + $(RM) $(OBJS) *.o */*.o */*/*.o + $(RM) $(OBJS:.o=.d) *.d */*.d */*/*.d + +-include $(OBJS:.o=.d) diff --git a/libc/arch/i386/crti.s b/libc/arch/i386/crti.s new file mode 100644 index 0000000..906414b --- /dev/null +++ b/libc/arch/i386/crti.s @@ -0,0 +1,14 @@ +.section .init + +.global _init +.type _init, @function +_init: + pushl %ebp + movl %esp, %ebp + +.section .fini + +.global _fini +_fini: + pushl %ebp + movl %esp, %ebp diff --git a/libc/arch/i386/crtn.s b/libc/arch/i386/crtn.s new file mode 100644 index 0000000..447afb1 --- /dev/null +++ b/libc/arch/i386/crtn.s @@ -0,0 +1,7 @@ +.section .init + popl %ebp + ret + +.section .fini + popl %ebp + ret diff --git a/libc/arch/i386/include/bits/types.h b/libc/arch/i386/include/bits/types.h new file mode 100644 index 0000000..99946ff --- /dev/null +++ b/libc/arch/i386/include/bits/types.h @@ -0,0 +1,41 @@ +#ifndef BITS_TYPES_H + +typedef unsigned char __u_char; +typedef unsigned short __u_short; +typedef unsigned int __u_int; +typedef unsigned long __u_long; + +typedef signed char __int8_t; +typedef signed short int __int16_t; +typedef signed int __int32_t; +typedef signed long __int64_t; + +typedef unsigned char __uint8_t; +typedef unsigned short int __uint16_t; +typedef unsigned int __uint32_t; +typedef unsigned long __uint64_t; + +typedef __int8_t __int_least8_t; +typedef __int16_t __int_least16_t; +typedef __int32_t __int_least32_t; +typedef __int64_t __int_least64_t; + +typedef __uint8_t __uint_least8_t; +typedef __uint16_t __uint_least16_t; +typedef __uint32_t __uint_least32_t; +typedef __uint64_t __uint_least64_t; + +typedef __int8_t int8_t; +typedef __int16_t int16_t; +typedef __int32_t int32_t; +typedef __int64_t int64_t; + +typedef __uint8_t uint8_t; +typedef __uint16_t uint16_t; +typedef __uint32_t uint32_t; +typedef __uint64_t uint64_t; + +typedef __int32_t intptr_t; +typedef __uint32_t uintptr_t; + +#endif diff --git a/libc/arch/i386/make.config b/libc/arch/i386/make.config new file mode 100644 index 0000000..25c1254 --- /dev/null +++ b/libc/arch/i386/make.config @@ -0,0 +1,6 @@ +LIBC_ARCH_INCLUDE=$(ARCHDIR)/include +LIBC_ARCH_CFLAGS=-I$(LIBC_ARCH_INCLUDE) +LIBC_ARCH_LDFLAGS= +LIBC_ARCH_LIBS= + +LIBC_ARCH_OBJS= diff --git a/libc/init.c b/libc/init.c new file mode 100644 index 0000000..b6c636b --- /dev/null +++ b/libc/init.c @@ -0,0 +1,2 @@ +void libc_init(void) { +} diff --git a/libc/unistd.c b/libc/unistd.c new file mode 100644 index 0000000..5cca686 --- /dev/null +++ b/libc/unistd.c @@ -0,0 +1,4 @@ +#include + +void _exit(int status) { +} -- cgit v1.2.3