diff --git a/make.scm b/make.scm index dfef35a7..6abd251a 100755 --- a/make.scm +++ b/make.scm @@ -62,8 +62,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$ ((eq? libc mini-libc-mes.E) "mini-") (else "")) "guile") #:exit exit))) -;;(add-scaffold-test "t" #:libc mini-libc-mes.E) -(add-scaffold-test "t" #:libc libc-mes+tcc.E) +(add-scaffold-test "t" #:libc mini-libc-mes.E) +;;(add-scaffold-test "t" #:libc libc-mes+tcc.E) ;; tests/00: exit, functions without libc (add-scaffold-test "00-exit-0" #:libc #f) diff --git a/mlibc/include/dlfcn.h b/mlibc/include/dlfcn.h index 01c50fa1..0158a8e4 100644 --- a/mlibc/include/dlfcn.h +++ b/mlibc/include/dlfcn.h @@ -23,7 +23,22 @@ #if __GNUC__ && POSIX #undef __MES_DLFCN_H #include_next -#endif // (__GNUC__ && POSIX) + +#else // !(__GNUC__ && POSIX) + +#define RTLD_LAZY 0x00001 +#define RTLD_NOW 0x00002 +#define RTLD_BINDING_MASK 0x3 +#define RTLD_NOLOAD 0x00004 +#define RTLD_DEEPBIND 0x00008 +#define RTLD_GLOBAL 0x00100 +#define RTLD_LOCAL 0 +#define RTLD_NODELETE 0x01000 + +void *dlopen (char const *filename, int flags); +int dlclose (void *handle); + +#endif // !(__GNUC__ && POSIX) #endif // __MES_DLFCN_H diff --git a/mlibc/include/errno.h b/mlibc/include/errno.h index ca279261..36e027c7 100644 --- a/mlibc/include/errno.h +++ b/mlibc/include/errno.h @@ -26,6 +26,8 @@ #endif #undef __MES_ERRNO_H #include_next +#else // ! (__GNUC__ && POSIX) +extern int errno; #endif // ! (__GNUC__ && POSIX) #endif // __MES_ERRNO_H diff --git a/mlibc/include/signal.h b/mlibc/include/signal.h index c994ee7a..43f958ce 100644 --- a/mlibc/include/signal.h +++ b/mlibc/include/signal.h @@ -25,6 +25,184 @@ #include_next #else //! (__GNUC__ && POSIX) typedef int sigset_t; + +typedef int stack_t; + +typedef int pid_t; +typedef int uid_t; +typedef int clock_t; +typedef int sigval_t; + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO + +#define FPE_INTDIV 1 +#define FPE_INTOVF 2 +#define FPE_FLTDIV 3 +#define FPE_FLTOVF 4 +#define FPE_FLTUND 5 +#define FPE_FLTRES 6 +#define FPE_FLTINV 7 +#define FPE_FLTSUB 8 + +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 +#define SA_SIGINFO 0x00000004 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND + + +typedef struct siginfo_t { + int si_signo; + int si_errno; + int si_code; + int si_trapno; + pid_t si_pid; + uid_t si_uid; + int si_status; + clock_t si_utime; + clock_t si_stime; + sigval_t si_value; + int si_int; + void *si_ptr; + int si_overrun; + int si_timerid; + void *si_addr; + long si_band; + int si_fd; + short si_addr_lsb; + void *si_lower; + void *si_upper; + int si_pkey; + void *si_call_addr; + int si_syscall; + unsigned int si_arch; +} siginfo_t; + + +// typedef void __signalfn_t(int); +// typedef __signalfn_t *__sighandler_t; + +struct sigaction { + void (*sa_sigaction) (int, siginfo_t *, void *); + //__sighandler_t sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; +}; + + +#ifdef __i386__ + +#define EBX 0 +#define ECX 1 +#define EDX 2 +#define ESI 3 +#define EDI 4 +#define EBP 5 +#define EAX 6 +#define DS 7 +#define ES 8 +#define FS 9 +#define GS 10 +#define ORIG_EAX 11 +#define EIP 12 +#define CS 13 +#define EFL 14 +#define UESP 15 +#define SS 16 +#define FRAME_SIZE 17 + +/* Type for general register. */ +typedef int greg_t; + +/* Number of general registers. */ +#define NGREG 19 + +/* Container for all general registers. */ +typedef greg_t gregset_t[NGREG]; + +/* Definitions taken from the kernel headers. */ +struct _libc_fpreg +{ + unsigned short int significand[4]; + unsigned short int exponent; +}; + +struct _libc_fpstate +{ + unsigned long int cw; + unsigned long int sw; + unsigned long int tag; + unsigned long int ipoff; + unsigned long int cssel; + unsigned long int dataoff; + unsigned long int datasel; + struct _libc_fpreg _st[8]; + unsigned long int status; +}; + +/* Structure to describe FPU registers. */ +typedef struct _libc_fpstate *fpregset_t; + +typedef struct + { + gregset_t gregs; + /* Due to Linux's history we have to use a pointer here. The SysV/i386 + ABI requires a struct with the values. */ + fpregset_t fpregs; + unsigned long int oldmask; + unsigned long int cr2; + } mcontext_t; + +/* Userlevel context. */ +typedef struct ucontext + { + unsigned long int uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + sigset_t uc_sigmask; + struct _libc_fpstate __fpregs_mem; + } ucontext_t; +#endif // !__i386__ + +int sigaction (int signum, struct sigaction const *act, struct sigaction *oldact); +int sigemptyset (sigset_t *set); + #endif //! (__GNUC__ && POSIX) #endif // __MES_SIGNAL_H diff --git a/mlibc/include/sys/mman.h b/mlibc/include/sys/mman.h index 93dff0ab..6dfc20fa 100644 --- a/mlibc/include/sys/mman.h +++ b/mlibc/include/sys/mman.h @@ -23,7 +23,21 @@ #if __GNUC__ && POSIX #undef __MES_SYS_MMAN_H #include_next -#endif // (__GNUC__ && POSIX) +#else // !(__GNUC__ && POSIX) + +#ifndef __MES_SIZE_T +#define __MES_SIZE_T +typedef unsigned long size_t; +#endif + +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 + +int mprotect (void *addr, size_t len, int prot); + +#endif // !(__GNUC__ && POSIX) #endif // __MES_SYS_MMAN_H diff --git a/mlibc/include/sys/time.h b/mlibc/include/sys/time.h index 673cf56c..4e5b218f 100644 --- a/mlibc/include/sys/time.h +++ b/mlibc/include/sys/time.h @@ -23,7 +23,22 @@ #if __GNUC__ && POSIX #undef __MES_SYS_TIME_H #include_next -#endif // (__GNUC__ && POSIX) + +#else // !(__GNUC__ && POSIX) + +struct timeval { + long tv_sec; + long tv_usec; +}; + +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; + +int gettimeofday (struct timeval *tv, struct timezone *tz); + +#endif // !(__GNUC__ && POSIX) #endif // __MES_SYS_TIME_H diff --git a/mlibc/libc-gcc+tcc.c b/mlibc/libc-gcc+tcc.c new file mode 100644 index 00000000..d0c3bc29 --- /dev/null +++ b/mlibc/libc-gcc+tcc.c @@ -0,0 +1,183 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2016,2017 Jan Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ + +#define FULL_MALLOC 1 +#include +#include + +int errno; + +#include +#include +#include +#include +#include + +#define SYS_exit "0x01" +#define SYS_read "0x03" +#define SYS_write "0x04" +#define SYS_open "0x05" +#define SYS_close "0x06" +#define SYS_unlink "0x0a" +#define SYS_lseek "0x13" +#define SYS_access "0x21" +#define SYS_brk "0x2d" +#define SYS_fsync "0x76" +#define SYS_getcwd "0xb7" + +int +close (int fd) +{ + int r; + asm ( + "mov %0,%%ebx\n\t" + "mov $"SYS_close",%%eax\n\t" + "int $0x80" + : "=r" (r) + : "" (fd) + ); + return r; +} + +int +unlink (char const *file_name) +{ + int r; + asm ( + "mov %0,%%ebx\n\t" + "mov $"SYS_unlink",%%eax\n\t" + "int $0x80" + : "=r" (r) + : "" (file_name) + ); + return r; +} + +off_t +lseek (int fd, off_t offset, int whence) +{ + int r; + asm ( + "mov %1,%%ebx\n\t" + "mov %2,%%ecx\n\t" + "mov %3,%%edx\n\t" + + "mov $"SYS_lseek",%%eax\n\t" + "int $0x80\n\t" + + "mov %%eax,%0\n\t" + : "=r" (r) + : "" (fd), "" (offset), "" (whence) + : "eax", "ebx", "ecx", "edx" + ); + return r; +} + +char * +getcwd (char *buf, size_t size) +{ + int r; + asm ( + "mov %1,%%ebx\n\t" + "mov %2,%%ecx\n\t" + + "mov $"SYS_getcwd",%%eax\n\t" + "int $0x80\n\t" + + "mov %%eax,%0\n\t" + : "=r" (r) + : "" (buf), "" (size) + : "eax", "ebx", "ecx" + ); + return r; +} + +int dlclose (void *handle) +{ + return 0; +} + +void * +dlopen (char const *filename, int flags) +{ + return 0; +} + +int +mprotect (void *addr, size_t len, int prot) +{ + return 0; +} + +int +sigaction (int signum, struct sigaction const *act, struct sigaction *oldact) +{ + return 0; +} + +int +sigemptyset (sigset_t *set) +{ + return 0; +} + +char * +strcat (char *dest, char const *src) +{ + return 0; +} + +int +vfprintf (FILE* f, char const* format, va_list ap) +{ + int fd = (int)f; + char const *p = format; + while (*p) + if (*p != '%') + putchar (*p++); + else + { + p++; + char c = *p; + switch (c) + { + case '%': {fputc (*p, fd); break;} + case 'c': {char c; c = va_arg (ap, char); fputc (c, fd); break;} + case 'd': {int d; d = va_arg (ap, int); fputs (itoa (d), fd); break;} + case 's': {char *s; s = va_arg (ap, char *); fputs (s, fd); break;} + default: {fputc (*p, fd); break;} + } + p++; + } + va_end (ap); + return 0; +} + +int +__udivdi3 (int a, int b) +{ + return a / b; +} + +int +__umoddi3 (int a, int b) +{ + return a % b; +} diff --git a/mlibc/libc-gcc.c b/mlibc/libc-gcc.c index 6d7c6da4..0ee872e6 100644 --- a/mlibc/libc-gcc.c +++ b/mlibc/libc-gcc.c @@ -181,31 +181,28 @@ putchar (int c) return 0; } -void *g_malloc_base = 0; +char *g_brk = 0; void * malloc (size_t size) { - void *p = brk (0); - if (!g_malloc_base) g_malloc_base = p; - brk (p+size); + if (!g_brk) + g_brk = brk (0); + if (brk (g_brk + size) == -1) + return 0; + char *p = g_brk; + g_brk += size; return p; } +#if !FULL_MALLOC void * realloc (void *p, size_t size) { - (void)p; - brk (g_malloc_base + size); - return g_malloc_base; -} - -void -free (void *p) -{ - int *n = (int*)p-1; - //munmap ((void*)p, *n); + brk (g_brk + size); + return g_brk; } +#endif size_t strlen (char const* s) @@ -504,6 +501,7 @@ fdungetc (int c, int fd) #endif // POSIX #if __GNUC__ && !POSIX + void _start () { @@ -537,4 +535,5 @@ _start () ); exit (r); } + #endif // __GNUC__ && !POSIX diff --git a/mlibc/libc-mes+tcc.c b/mlibc/libc-mes+tcc.c index 0ada0c1d..2b8a0341 100644 --- a/mlibc/libc-mes+tcc.c +++ b/mlibc/libc-mes+tcc.c @@ -18,19 +18,21 @@ * along with Mes. If not, see . */ -#define FULL_MALLOC 1 -#include - #include #include #include #include #include #include +#include #include -void -close () +#if !__GNUC__ +#define FULL_MALLOC 1 +#include + +int +close (int fd) { asm ("mov____0x8(%ebp),%ebx !8"); @@ -38,16 +40,6 @@ close () asm ("int____$0x80"); } -char * -getcwd (char *buf, size_t size) -{ - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____0x8(%ebp),%ecx !12"); - - asm ("mov____$i32,%eax SYS_getcwd"); - asm ("int____$0x80"); -} - int unlink (char const *file_name) { @@ -68,6 +60,17 @@ lseek (int fd, off_t offset, int whence) asm ("int____$0x80"); } +char * +getcwd (char *buf, size_t size) +{ + asm ("mov____0x8(%ebp),%ebx !8"); + asm ("mov____0x8(%ebp),%ecx !12"); + + asm ("mov____$i32,%eax SYS_getcwd"); + asm ("int____$0x80"); +} +#endif // !__GNUC__ + int execvp (char const *file, char *const argv[]) @@ -134,6 +137,12 @@ fwrite (void const *ptr, size_t size, size_t nmemb, FILE *stream) return 0; } +int +gettimeofday (struct timeval *tv, struct timezone *tz) +{ + return 0; +} + struct tm * localtime (time_t const *timep) { diff --git a/mlibc/libc-mes.c b/mlibc/libc-mes.c index a81727a9..9aaf3909 100644 --- a/mlibc/libc-mes.c +++ b/mlibc/libc-mes.c @@ -322,7 +322,7 @@ malloc (size_t size) #if !FULL_MALLOC void * -realloc (void *p, int size) +realloc (void *p, size_t size) { brk (g_brk + size); return g_brk;