scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 6220d3865e26ca9a5de3afa960939de22f1bd2f7
parent 083a917d528f85907c5e4a2994f723a91995ca99
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 18 Jan 2023 11:48:35 +0100

build: Add initial support for CONF=amd64-freebsd

This is only the basic skeleton to build amd64 FreeBSD. Additional
work is required to have a working libc. It is only checked that
the build finish correctly but we cannot be sure that all the
constants defined in this commit are correct. The errno.h file was
verified and the _exit() syscall was also checked.

Diffstat:
Ainclude/bits/freebsd/amd64/arch/sigaction.h | 15+++++++++++++++
Ainclude/bits/freebsd/amd64/arch/stdint.h | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/freebsd/amd64/arch/time.h | 5+++++
Ainclude/bits/freebsd/sys.h | 34++++++++++++++++++++++++++++++++++
Ainclude/bits/freebsd/sys/cdefs.h | 1+
Ainclude/bits/freebsd/sys/errno.h | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/bits/freebsd/sys/signal.h | 27+++++++++++++++++++++++++++
Ainclude/bits/freebsd/sys/stdio.h | 7+++++++
Ainclude/bits/freebsd/sys/stdlib.h | 2++
Mscripts/amd64.mk | 1+
Ascripts/build/conf/amd64-freebsd.mk | 5+++++
Mscripts/libc-dirs | 1+
Mscripts/proto.amd64 | 4++++
Msrc/libc/arch/Makefile | 1+
Msrc/libc/arch/amd64/Makefile | 1+
Asrc/libc/arch/amd64/freebsd/.gitignore | 2++
Asrc/libc/arch/amd64/freebsd/Makefile | 26++++++++++++++++++++++++++
Asrc/libc/arch/amd64/freebsd/crt.s | 1+
Asrc/libc/arch/amd64/freebsd/deps.mk | 1+
Asrc/libc/arch/amd64/freebsd/gensys.sh | 31+++++++++++++++++++++++++++++++
Asrc/libc/arch/amd64/freebsd/syscall.lst | 3+++
Asrc/libc/arch/freebsd/Makefile | 6++++++
Asrc/libc/objs/amd64-freebsd.mk | 27+++++++++++++++++++++++++++
23 files changed, 414 insertions(+), 0 deletions(-)

diff --git a/include/bits/freebsd/amd64/arch/sigaction.h b/include/bits/freebsd/amd64/arch/sigaction.h @@ -0,0 +1,15 @@ +typedef unsigned int sigset_t; +typedef struct siginfo siginfo_t; + +struct sigaction { + union { + void (*__sa_handler)(int); + void (*__sa_sigaction)(int, siginfo_t *, void *); + } __sigaction_u; + + sigset_t sa_mask; + int sa_flags; +}; + +#define sa_handler __sigaction_u.__sa_handler +#define sa_sigaction __sigaction_u.__sa_sigaction diff --git a/include/bits/freebsd/amd64/arch/stdint.h b/include/bits/freebsd/amd64/arch/stdint.h @@ -0,0 +1,112 @@ +#define INT8_MAX 0x7F +#define INT8_MIN (-INT8_MAX-1) +#define UINT8_MAX 0xFF + +#define INT16_MAX 0x7FFF +#define INT16_MIN (-INT16_MAX-1) +#define UINT16_MAX 0xFFFF + +#define INT32_MAX 0x7FFFFFFF +#define INT32_MIN (-INT32_MAX-1) +#define UINT32_MAX 0xFFFFFFFF + +#define INT64_MAX 0x7FFFFFFFFFFFFFFF +#define INT64_MIN (-INT64_MAX-1) +#define UINT64_MAX 0xFFFFFFFFFFFFFFFF + +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define UINT_LEAST8_MAX UINT8_MAX + +#define INT_LEAST16_MIN INT32_MIN +#define INT_LEAST16_MAX INT32_MAX +#define UINT_LEAST16_MAX UINT32_MAX + +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define UINT_LEAST32_MAX UINT32_MAX + +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +#define INT_FAST8_MIN INT32_MIN +#define INT_FAST8_MAX INT32_MAX +#define UINT_FAST8_MAX UINT32_MAX + +#define INT_FAST16_MIN INT32_MIN +#define INT_FAST16_MAX INT32_MAX +#define UINT_FAST16_MAX UINT32_MAX + +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define UINT_FAST32_MAX UINT32_MAX + +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST64_MAX UINT64_MAX + +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX + +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX + +#define SIG_ATOMIC_MIN INT32_MIN +#define SIG_ATOMIC_MAX INT32_MAX + +#define SIZE_MAX UINT64_MAX + +#define INT8_C(x) x +#define INT16_C(x) x +#define INT32_C(x) x +#define INT64_C(x) x ## LL + +#define UINT8_C(x) x +#define UINT16_C(x) x +#define UINT32_C(x) x ## U +#define UINT64_C(x) x ## ULL + +#define INTMAX_C(x) x ## LL +#define UINTMAX_C(x) x ## ULL + +typedef signed char int8_t; +typedef short int16_t; +typedef int int32_t; +typedef long int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned uint32_t; +typedef unsigned long uint64_t; + +typedef signed char int_least8_t; +typedef short int_least16_t; +typedef int int_least32_t; +typedef long int_least64_t; + +typedef unsigned char uint_least8_t; +typedef unsigned short uint_least16_t; +typedef unsigned uint_least32_t; +typedef unsigned long uint_least64_t; + +typedef int int_fast8_t; +typedef int int_fast16_t; +typedef int int_fast32_t; +typedef int int_fast64_t; + +typedef unsigned uint_fast8_t; +typedef unsigned uint_fast16_t; +typedef unsigned uint_fast32_t; +typedef unsigned long uint_fast64_t; + +typedef long intptr_t; +typedef unsigned long uintptr_t; + +typedef long intmax_t; +typedef unsigned long uintmax_t; diff --git a/include/bits/freebsd/amd64/arch/time.h b/include/bits/freebsd/amd64/arch/time.h @@ -0,0 +1,5 @@ +#define _MAXYEAR 9999 + +typedef long time_t; +typedef long clock_t; +typedef long __suseconds_t; diff --git a/include/bits/freebsd/sys.h b/include/bits/freebsd/sys.h @@ -0,0 +1,34 @@ +#define O_RDONLY 0x00000000 +#define O_WRONLY 0x00000001 +#define O_RDWR 0x00000002 +#define O_ACCMODE 0x00000003 + +#define O_CLOEXEC 0x00010000 +#define O_EXCL 0x00000800 +#define O_TRUNC 0x00000400 +#define O_CREAT 0x00000200 +#define O_APPEND 0x00000008 + +#define AT_FDCWD -100 +#define CLOCKS_PER_SEC ((clock_t) 100) +#define RUSAGE_SELF 0 + +#define F_OK 0 +#define X_OK 1 +#define R_OK 4 +#define W_OK 2 + +typedef int pid_t; + +struct sigaction; +struct rusage; + +extern int _execve(const char *, const char *[], char *const []); +extern int _fork(void); +extern pid_t _getpid(void); +extern int _kill(pid_t, int); +extern int _sigaction(int, struct sigaction *, struct sigaction *); +extern pid_t _wait4(pid_t, int *, int, struct rusage *); +extern pid_t _waitpid(pid_t, int *, int); + +extern char **_environ; diff --git a/include/bits/freebsd/sys/cdefs.h b/include/bits/freebsd/sys/cdefs.h @@ -0,0 +1 @@ +/* nothing for Openbsd */ diff --git a/include/bits/freebsd/sys/errno.h b/include/bits/freebsd/sys/errno.h @@ -0,0 +1,101 @@ +extern int errno; +extern char *const _sys_errlist[]; + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* Input/output error */ +#define ENXIO 6 /* Device not configured */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file descriptor */ +#define ECHILD 10 /* No child processes */ +#define EDEADLK 11 /* Resource deadlock avoided */ +#define ENOMEM 12 /* Cannot allocate memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* Operation not supported by device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* Too many open files in system */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Inappropriate ioctl for device */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only filesystem */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Numerical argument out of domain */ +#define ERANGE 34 /* Result too large */ +#define EAGAIN 35 /* Resource temporarily unavailable */ +#define EINPROGRESS 36 /* Operation now in progress */ +#define EALREADY 37 /* Operation already in progress */ +#define ENOTSOCK 38 /* Socket operation on non-socket */ +#define EDESTADDRREQ 39 /* Destination address required */ +#define EMSGSIZE 40 /* Message too long */ +#define EPROTOTYPE 41 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 42 /* Protocol not available */ +#define EPROTONOSUPPORT 43 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define EOPNOTSUPP 45 /* Operation not supported */ +#define EPFNOSUPPORT 46 /* Protocol family not supported */ +#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */ +#define EADDRINUSE 48 /* Address already in use */ +#define EADDRNOTAVAIL 49 /* Can't assign requested address */ +#define ENETDOWN 50 /* Network is down */ +#define ENETUNREACH 51 /* Network is unreachable */ +#define ENETRESET 52 /* Network dropped connection on reset */ +#define ECONNABORTED 53 /* Software caused connection abort */ +#define ECONNRESET 54 /* Connection reset by peer */ +#define ENOBUFS 55 /* No buffer space available */ +#define EISCONN 56 /* Socket is already connected */ +#define ENOTCONN 57 /* Socket is not connected */ +#define ESHUTDOWN 58 /* Can't send after socket shutdown */ +#define ETOOMANYREFS 59 /* Too many references: can't splice */ +#define ETIMEDOUT 60 /* Operation timed out */ +#define ECONNREFUSED 61 /* Connection refused */ +#define ELOOP 62 /* Too many levels of symbolic links */ +#define ENAMETOOLONG 63 /* File name too long */ +#define EHOSTDOWN 64 /* Host is down */ +#define EHOSTUNREACH 65 /* No route to host */ +#define ENOTEMPTY 66 /* Directory not empty */ +#define EPROCLIM 67 /* Too many processes */ +#define EUSERS 68 /* Too many users */ +#define EDQUOT 69 /* Disc quota exceeded */ +#define ESTALE 70 /* Stale NFS file handle */ +#define EREMOTE 71 /* Too many levels of remote in path */ +#define EBADRPC 72 /* RPC struct is bad */ +#define ERPCMISMATCH 73 /* RPC version wrong */ +#define EPROGUNAVAIL 74 /* RPC prog. not avail */ +#define EPROGMISMATCH 75 /* Program version wrong */ +#define EPROCUNAVAIL 76 /* Bad procedure for program */ +#define ENOLCK 77 /* No locks available */ +#define ENOSYS 78 /* Function not implemented */ +#define EFTYPE 79 /* Inappropriate file type or format */ +#define EAUTH 80 /* Authentication error */ +#define ENEEDAUTH 81 /* Need authenticator */ +#define EIDRM 82 /* Identifier removed */ +#define ENOMSG 83 /* No message of desired type */ +#define EOVERFLOW 84 /* Value too large to be stored in data type */ +#define ECANCELED 85 /* Operation canceled */ +#define EILSEQ 86 /* Illegal byte sequence */ +#define ENOATTR 87 /* Attribute not found */ +#define EDOOFUS 88 /* Programming error */ +#define EBADMSG 89 /* Bad message */ +#define EMULTIHOP 90 /* Multihop attempted */ +#define ENOLINK 91 /* Link has been severed */ +#define EPROTO 92 /* Protocol error */ +#define ENOTCAPABLE 93 /* Capabilities insufficient */ +#define ECAPMODE 94 /* Not permitted in capability mode */ +#define ENOTRECOVERABLE 95 /* State not recoverable */ +#define EOWNERDEAD 96 /* Previous owner died */ +#define EINTEGRITY 97 /* Integrity check failed */ +#define EUNKNOWN 98 /* Unknown error */ diff --git a/include/bits/freebsd/sys/signal.h b/include/bits/freebsd/sys/signal.h @@ -0,0 +1,27 @@ +typedef int sig_atomic_t; + +#define SIG_ERR ((void (*)(int)) -1) +#define SIG_DFL ((void (*)(int)) 0) +#define SIG_IGN ((void (*)(int)) 1) + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGABRT 6 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGSEGV 11 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTOP 17 +#define SIGTSTP 18 +#define SIGCONT 19 +#define SIGCHLD 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGUSR1 30 +#define SIGUSR2 31 + +#define __NR_SIGNALS 32 diff --git a/include/bits/freebsd/sys/stdio.h b/include/bits/freebsd/sys/stdio.h @@ -0,0 +1,7 @@ +#define BUFSIZ 512 +#define FILENAME_MAX 256 +#define FOPEN_MAX 16 + +#define TMP_MAX 25 +#define _TMPNAME "/tmp/tmp.0000000" +#define L_tmpnam sizeof(_TMPNAME) diff --git a/include/bits/freebsd/sys/stdlib.h b/include/bits/freebsd/sys/stdlib.h @@ -0,0 +1,2 @@ +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 diff --git a/scripts/amd64.mk b/scripts/amd64.mk @@ -4,6 +4,7 @@ x86_64 amd64: +@$(MAKE) `$(SCRIPTDIR)/config` CONF=amd64-netbsd src/libc src/libcrt +@$(MAKE) `$(SCRIPTDIR)/config` CONF=amd64-dragonfly src/libc src/libcrt +@$(MAKE) `$(SCRIPTDIR)/config` CONF=amd64-darwin src/libc src/libcrt + +@$(MAKE) `$(SCRIPTDIR)/config` CONF=amd64-freebsd src/libc src/libcrt install-x86_64 install-amd64: amd64 $(SCRIPTDIR)/install -p $(SCRIPTDIR)/proto.amd64 $(ROOT) diff --git a/scripts/build/conf/amd64-freebsd.mk b/scripts/build/conf/amd64-freebsd.mk @@ -0,0 +1,5 @@ +ARCH = amd64 +ABI = sysv +SYS = freebsd +FORMAT = elf +O = 6F diff --git a/scripts/libc-dirs b/scripts/libc-dirs @@ -7,6 +7,7 @@ lib/scc/ppc32-linux lib/scc/i386-linux lib/scc/arm32-linux lib/scc/arm64-linux +lib/scc/amd64-freebsd lib/scc/amd64-netbsd lib/scc/amd64-linux lib/scc/amd64-openbsd diff --git a/scripts/proto.amd64 b/scripts/proto.amd64 @@ -8,6 +8,10 @@ d 755 lib/scc/amd64-dragonfly f 644 lib/scc/amd64-dragonfly/crt.o f 644 lib/scc/amd64-dragonfly/libc.a f 644 lib/scc/amd64-dragonfly/libcrt.a +d 755 lib/scc/amd64-freebsd +f 644 lib/scc/amd64-freebsd/crt.o +f 644 lib/scc/amd64-freebsd/libc.a +f 644 lib/scc/amd64-freebsd/libcrt.a d 755 lib/scc/amd64-linux f 644 lib/scc/amd64-linux/crt.o f 644 lib/scc/amd64-linux/libc.a diff --git a/src/libc/arch/Makefile b/src/libc/arch/Makefile @@ -7,6 +7,7 @@ DIRS =\ arm64\ arm\ i386\ + freebsd\ ppc\ netbsd\ openbsd\ diff --git a/src/libc/arch/amd64/Makefile b/src/libc/arch/amd64/Makefile @@ -4,6 +4,7 @@ PROJECTDIR = ../../../.. DIRS =\ darwin\ dragonfly\ + freebsd\ linux\ netbsd\ openbsd\ diff --git a/src/libc/arch/amd64/freebsd/.gitignore b/src/libc/arch/amd64/freebsd/.gitignore @@ -0,0 +1,2 @@ +_exit.c +_sys_errlist.c diff --git a/src/libc/arch/amd64/freebsd/Makefile b/src/libc/arch/amd64/freebsd/Makefile @@ -0,0 +1,26 @@ +.POSIX: + +PROJECTDIR =../../../../.. +include $(PROJECTDIR)/scripts/rules.mk +include ../../../rules.mk + +GENOBJS =\ + _exit.$O\ + +OBJS =\ + $(GENOBJS)\ + _sys_errlist.$O\ + +GENSRC = $(GENOBJS:.$O=.s) + +all: $(OBJS) $(CRT) + +$(CRT): ../crt-posix.s + +$(GENSRC): syscall.lst + ./gensys.sh $(@:.s=) + +clean: + rm -f $(GENSRC) _sys_errlist.c + +include deps.mk diff --git a/src/libc/arch/amd64/freebsd/crt.s b/src/libc/arch/amd64/freebsd/crt.s @@ -0,0 +1 @@ + .include "../crt-posix.s" diff --git a/src/libc/arch/amd64/freebsd/deps.mk b/src/libc/arch/amd64/freebsd/deps.mk @@ -0,0 +1 @@ +#deps diff --git a/src/libc/arch/amd64/freebsd/gensys.sh b/src/libc/arch/amd64/freebsd/gensys.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +# +# This job is very easy because app and kernel ABI are identical +# until the 4th parameter, so we only have to set the syscall +# number in rax + +sed -n " + s/[ ]*#.*// + /$1/p" syscall.lst | +while read num name nargs +do +cat <<EOF > $name.s + .file "$name.s" + + .globl $name +$name: + `case $nargs in 4|5|6) + echo "movq %rcx,%r10" + ;; + esac` + movq \$$num,%rax + syscall + jb 1f + retq + +1: movq %rax,(errno) + movq \$-1,%rax + retq +EOF +done diff --git a/src/libc/arch/amd64/freebsd/syscall.lst b/src/libc/arch/amd64/freebsd/syscall.lst @@ -0,0 +1,3 @@ +#Tab 15 +#number name nargs +1 _exit 1 diff --git a/src/libc/arch/freebsd/Makefile b/src/libc/arch/freebsd/Makefile @@ -0,0 +1,6 @@ +.POSIX: +PROJECTDIR = ../../../.. +include $(PROJECTDIR)/scripts/rules.mk +include ../../rules.mk + +NODEP = 1 diff --git a/src/libc/objs/amd64-freebsd.mk b/src/libc/objs/amd64-freebsd.mk @@ -0,0 +1,27 @@ +include objs/common-objs.mk + +OBJS =\ + $(COMMON_OBJS)\ + arch/amd64/freebsd/_exit.$O\ + arch/amd64/freebsd/crt.$O\ + arch/amd64/longjmp.$O\ + arch/amd64/memchr.$O\ + arch/amd64/memcmp.$O\ + arch/amd64/memcpy.$O\ + arch/amd64/memmove.$O\ + arch/amd64/memset.$O\ + arch/amd64/setjmp.$O\ + arch/amd64/strchr.$O\ + arch/amd64/strcmp.$O\ + arch/amd64/strcpy.$O\ + arch/posix/_open.$O\ + arch/posix/_systime.$O\ + arch/posix/_tzone.$O\ + arch/posix/clock.$O\ + arch/posix/getenv.$O\ + arch/posix/raise.$O\ + arch/posix/signal.$O\ + arch/posix/system.$O\ + arch/posix/time.$O\ + arch/posix/tmpfile.$O\ + string/strlen.$O\