mlibc: Tinycc support: gcc -nostdinc -nostdlib.
authorJan Nieuwenhuizen <janneke@gnu.org>
Thu, 27 Jul 2017 21:44:22 +0000 (23:44 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Thu, 27 Jul 2017 21:44:22 +0000 (23:44 +0200)
* mlibc/libc-gcc+tcc.c: New file.
* mlibc/include/dlfcn.h:
* mlibc/include/errno.h:
* mlibc/include/signal.h:
* mlibc/include/sys/mman.h:
* mlibc/include/sys/time.h:  Add tcc declarations.

make.scm
mlibc/include/dlfcn.h
mlibc/include/errno.h
mlibc/include/signal.h
mlibc/include/sys/mman.h
mlibc/include/sys/time.h
mlibc/libc-gcc+tcc.c [new file with mode: 0644]
mlibc/libc-gcc.c
mlibc/libc-mes+tcc.c
mlibc/libc-mes.c

index dfef35a73f932c4ac7f210801a072a73503b849a..6abd251a84078f873f61de2a9462900f490cb62d 100755 (executable)
--- 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)
index 01c50fa1430705846513d1a4c04901982104be76..0158a8e4024e10652d5be92e786c38216963e47a 100644 (file)
 #if __GNUC__ && POSIX
 #undef __MES_DLFCN_H
 #include_next <dlfcn.h>
-#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
 
index ca27926149b962709ead0ea38b7a663842b54b61..36e027c75a9d00d8bc4705fd36adff6fb542537b 100644 (file)
@@ -26,6 +26,8 @@
 #endif
 #undef __MES_ERRNO_H
 #include_next <errno.h>
+#else // ! (__GNUC__ && POSIX)
+extern int errno;
 #endif // ! (__GNUC__ && POSIX)
 
 #endif // __MES_ERRNO_H
index c994ee7a1007c5f958ff2057b9035f857b5389d6..43f958ce6163253df3265bfc15fcdd92b65d8b28 100644 (file)
 #include_next <signal.h>
 #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
index 93dff0ab99251eb8978378c9ac7b3e427c9771a7..6dfc20fa038e8563d58034eb48a2317ea0905348 100644 (file)
 #if __GNUC__ && POSIX
 #undef __MES_SYS_MMAN_H
 #include_next <sys/mman.h>
-#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
 
index 673cf56cffe89c12071aaee530be187f5268879e..4e5b218f12437c481a37dcb2a753d0c90e2059be 100644 (file)
 #if __GNUC__ && POSIX
 #undef __MES_SYS_TIME_H
 #include_next <sys/time.h>
-#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 (file)
index 0000000..d0c3bc2
--- /dev/null
@@ -0,0 +1,183 @@
+/* -*-comment-start: "//";comment-end:""-*-
+ * Mes --- Maxwell Equations of Software
+ * Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#define FULL_MALLOC 1
+#include <libc-gcc.c>
+#include <libc-mes+tcc.c>
+
+int errno;
+
+#include <unistd.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+
+#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;
+}
index 6d7c6da41e7955f18f21a9b6903f4858ae5ddec4..0ee872e612de57a909d7666fb44d4749d0a46044 100644 (file)
@@ -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
index 0ada0c1dd336bc88f0634403e1c7f0b82df85d51..2b8a034193a5cf84e9108ca124e2b96de11215fb 100644 (file)
  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#define FULL_MALLOC 1
-#include <libc-mes.c>
-
 #include <setjmp.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <sys/time.h>
 #include <unistd.h>
 
-void
-close ()
-{
-  asm ("mov____0x8(%ebp),%ebx !8");
-
-  asm ("mov____$i32,%eax SYS_close");
-  asm ("int____$0x80");
-}
+#if !__GNUC__
+#define FULL_MALLOC 1
+#include <libc-mes.c>
 
-char *
-getcwd (char *buf, size_t size)
+int
+close (int fd)
 {
   asm ("mov____0x8(%ebp),%ebx !8");
-  asm ("mov____0x8(%ebp),%ecx !12");
 
-  asm ("mov____$i32,%eax SYS_getcwd");
+  asm ("mov____$i32,%eax SYS_close");
   asm ("int____$0x80");
 }
 
@@ -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)
 {
index a81727a9b6fc0f77bf2a6b1b41b45740a65fcd0a..9aaf3909cd318734c27d6759e794e000e4e91324 100644 (file)
@@ -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;