Browse Source

Add support for executing mm0-c.

Giovanni Mascellani 4 years ago
parent
commit
e743dee0ef

+ 1 - 1
.gitmodules

@@ -15,7 +15,7 @@
 	url = https://gitlab.com/giomasce/ipxe.git
 [submodule "contrib/mm0"]
 	path = contrib/mm0
-	url = https://github.com/digama0/mm0.git
+	url = https://github.com/giomasce/mm0.git
 [submodule "contrib/single_cream"]
 	path = contrib/single_cream
 	url = https://github.com/rain-1/single_cream.git

+ 1 - 1
contrib/mm0

@@ -1 +1 @@
-Subproject commit cdf4f7cfd75c44e00cd7a69a6d1789519967e75c
+Subproject commit 1eb268389afe782634b48e37b36a5495d62b8f7f

+ 1 - 1
contrib/tinycc

@@ -1 +1 @@
-Subproject commit b7967051a0a87dbd213ac66d25d5c92fd1fd8c9f
+Subproject commit 18deecb24253b8150b2fa785c325d3b6e8be5d31

+ 4 - 0
diskfs/run_tcc.c

@@ -26,6 +26,7 @@
 
 #define RUN_IPXE
 //#define RUN_SINGLE_CREAM
+//#define RUN_MM0_C
 
 int recursively_compile() {
 #if LEVEL == 10
@@ -50,6 +51,9 @@ int recursively_compile() {
 #elif LEVEL == 1 && defined(RUN_SINGLE_CREAM)
 #define ADD_TCC_SYMBOLS
     files[0] = ASMC_PREFIX "/run_tcc_sc.c";
+#elif LEVEL == 1 && defined(RUN_MM0_C)
+#define ADD_TCC_SYMBOLS
+    files[0] = ASMC_PREFIX "/run_tcc_mm0_c.c";
 #else
     files[0] = ASMC_PREFIX "/run_tcc.c";
 #endif

+ 0 - 6
diskfs/run_tcc_ipxe.c

@@ -28,12 +28,6 @@
 #define ONE_SOURCE 1
 #include "tcc.h"
 
-// Silence some internal tcc warnings
-#undef free
-#undef malloc
-#undef realloc
-#undef strdup
-
 #define ASMC_PREFIX "/disk1"
 #define IPXE_PREFIX ASMC_PREFIX "/ipxe/src"
 #define IPXE_TEMP "/ram/ipxe"

+ 112 - 0
diskfs/run_tcc_mm0_c.c

@@ -0,0 +1,112 @@
+/* This file is part of asmc, a bootstrapping OS with minimal seed
+   Copyright (C) 2019 Giovanni Mascellani <gio@debian.org>
+   https://gitlab.com/giomasce/asmc
+
+   This program 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.
+
+   This program 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 this program.  If not, see <https://www.gnu.org/licenses/>. */
+
+#include "run_tcc.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#define TCC_TARGET_I386 1
+#define __i386__ 1
+#define USE_SOFTFLOAT 1
+#define ONE_SOURCE 1
+#include "tcc.h"
+
+#define ASMC_PREFIX "/disk1"
+#define MM0_C_PREFIX ASMC_PREFIX "/mm0/mm0-c"
+#define MM0_C_TEMP "/ram/mm0-c"
+
+const char *includes[] = {
+    ASMC_PREFIX,
+    ASMC_PREFIX "/stdlib",
+};
+
+const char *sources[][2] = {
+    {MM0_C_PREFIX "/main.c", MM0_C_TEMP "/main.o"},
+};
+
+char *mm0_c_argv[] = {
+    "mm0-c",
+    "/disk1/mm0/examples/peano.mmb",
+};
+
+int main(int argc, char *argv[]) {
+ restart:
+    printf("Here is where we compile mm0-c!\n");
+
+    int res;
+    TCCState *state;
+
+    // First compile all files
+    for (int j = 0; j < sizeof(sources) / sizeof(sources[0]); j++) {
+        state = tcc_new();
+        tcc_set_options(state, "-nostdinc -nostdlib");
+        tcc_set_output_type(state, TCC_OUTPUT_OBJ);
+        char buf[1024];
+        sprintf(buf, "%d", __get_handles());
+        tcc_define_symbol(state, "__HANDLES", buf);
+        for (int i = 0; i < sizeof(includes) / sizeof(includes[0]); i++) {
+            res = tcc_add_include_path(state, includes[i]);
+            if (res) {
+                printf("tcc_add_include_path() failed...\n");
+                return 1;
+            }
+        }
+        res = tcc_add_file(state, sources[j][0]);
+        if (res) {
+            printf("tcc_add_file() failed...\n");
+            return 1;
+        }
+        res = tcc_output_file(state, sources[j][1]);
+        if (res) {
+            printf("tcc_output_file() failed...\n");
+            return 1;
+        }
+        tcc_delete(state);
+    }
+
+    // Then link everything together
+    state = tcc_new();
+    tcc_set_options(state, "-nostdinc -nostdlib");
+    tcc_set_output_type(state, TCC_OUTPUT_MEMORY);
+    for (int i = 0; i < sizeof(sources) / sizeof(sources[0]); i++) {
+        res = tcc_add_file(state, sources[i][1]);
+        if (res) {
+            printf("tcc_add_file() failed...\n");
+            return 1;
+        }
+    }
+    res = tcc_relocate(state, TCC_RELOCATE_AUTO);
+    if (res) {
+        printf("tcc_relocate() failed...\n");
+        return 1;
+    }
+    int (*start)(int, char *[]) = tcc_get_symbol(state, "_start");
+    if (!start) {
+        printf("tcc_get_symbol() failed...\n");
+        return 1;
+    }
+
+    printf("Jumping into mm0-c!\n");
+    res = start(sizeof(mm0_c_argv)/sizeof(mm0_c_argv[0]), mm0_c_argv);
+    printf("mm0-c returned %d!\n", res);
+    tcc_delete(state);
+
+    return res;
+}

+ 0 - 6
diskfs/run_tcc_sc.c

@@ -28,12 +28,6 @@
 #define ONE_SOURCE 1
 #include "tcc.h"
 
-// Silence some internal tcc warnings
-#undef free
-#undef malloc
-#undef realloc
-#undef strdup
-
 #define ASMC_PREFIX "/disk1"
 #define SC_PREFIX ASMC_PREFIX "/sc/src"
 #define SC_TEMP "/ram/sc"

+ 3 - 0
diskfs/stdlib/asmc_types.h

@@ -23,6 +23,7 @@
 
 typedef int ssize_t;
 typedef unsigned int size_t;
+typedef long off_t;
 
 // tinycc expects a very early definition of memmove, otherwise it
 // fails (probably because it tries to define it internally, but then
@@ -35,4 +36,6 @@ typedef struct {
     int ungetted;
 } FILE;
 
+#define __builtin_unreachable()
+
 #endif

+ 1 - 0
diskfs/stdlib/errno.h

@@ -13,6 +13,7 @@ int __errno = 0;
 // Defined by POSIX
 #define EINVAL 50
 #define ENOENT 51
+#define ENOMEM 52
 
 // Defined by me
 #define ENOTIMPL 100

+ 38 - 3
diskfs/stdlib/sys/mman.h

@@ -3,12 +3,19 @@
 
 #include "asmc_types.h"
 #include "errno.h"
+#include "stdio.h"
+#include "unistd.h"
 
 #define PROT_NONE 0
 #define PROT_EXEC (1 << 0)
 #define PROT_READ (1 << 1)
 #define PROT_WRITE (1 << 2)
 
+#define MAP_FIXED (1 << 0)
+#define MAP_PRIVATE (1 << 1)
+#define MAP_SHARED (1 << 2)
+#define MAP_FILE (1 << 3)
+
 #define MAP_FAILED NULL
 
 int mprotect(void *addr, size_t len, int prot) {
@@ -21,10 +28,38 @@ int mprotect(void *addr, size_t len, int prot) {
     }
 }
 
-// STUB
 void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) {
-    __unimplemented();
-    return MAP_FAILED;
+    // Ignore MAP_FILE
+    flags &= ~MAP_FILE;
+    if (addr != 0 || prot != PROT_READ || flags != MAP_PRIVATE) {
+        errno = ENOTIMPL;
+        return MAP_FAILED;
+    }
+    void *ret = malloc(len);
+    if (len == 0) {
+        return ret;
+    }
+    if (ret == NULL) {
+        errno = ENOMEM;
+        return MAP_FAILED;
+    }
+    char *pos = (char*) ret;
+    off_t cur_pos = lseek(fildes, 0, SEEK_CUR);
+    lseek(fildes, off, SEEK_SET);
+    do {
+        ssize_t res = read(fildes, pos, 1);
+        if (!res) {
+            *pos = '\0';
+        }
+        pos++;
+    } while (--len);
+    lseek(fildes, cur_pos, SEEK_SET);
+    return ret;
+}
+
+int munmap(void *addr, size_t len) {
+    free(addr);
+    return 0;
 }
 
 #endif

+ 40 - 0
diskfs/stdlib/sys/stat.h

@@ -4,6 +4,8 @@
 #include "asmc.h"
 #include "errno.h"
 #include "sys/types.h"
+#include <time.h>
+#include "unistd.h"
 
 #define S_IRWXU 0700
 #define S_IRUSR 0400
@@ -21,6 +23,44 @@
 #define S_ISGID 02000
 #define S_ISVTX 01000
 
+struct stat {
+    dev_t st_dev;
+    ino_t st_ino;
+    mode_t st_mode;
+    nlink_t st_nlink;
+    uid_t st_uid;
+    gid_t st_gid;
+    dev_t st_rdev;
+    off_t st_size;
+    struct timespec st_atim;
+    struct timespec st_mtim;
+    struct timespec st_ctim;
+    blksize_t st_blksize;
+    blkcnt_t st_blocks;
+};
+
+int fstat(int fildes, struct stat *buf) {
+    buf->st_dev = 0;
+    buf->st_ino = 0;
+    buf->st_mode = 0;
+    buf->st_nlink = 1;
+    buf->st_uid = 0;
+    buf->st_gid = 0;
+    buf->st_rdev = 0;
+    off_t cur_pos = lseek(fildes, 0, SEEK_CUR);
+    buf->st_size = lseek(fildes, 0, SEEK_END);
+    lseek(fildes, cur_pos, SEEK_SET);
+    buf->st_atim.tv_sec = 0;
+    buf->st_atim.tv_nsec = 0;
+    buf->st_mtim.tv_sec = 0;
+    buf->st_mtim.tv_nsec = 0;
+    buf->st_ctim.tv_sec = 0;
+    buf->st_ctim.tv_nsec = 0;
+    buf->st_blksize = 512;
+    buf->st_blocks = (buf->st_size+511)/512;
+    return 0;
+}
+
 // STUB
 int chmod(const char *path, mode_t mode) {
     __unimplemented();

+ 10 - 3
diskfs/stdlib/sys/types.h

@@ -1,9 +1,16 @@
 #ifndef __SYS_TYPES_H
 #define __SYS_TYPES_H
 
-typedef long off_t;
-typedef int mode_t;
+#include "asmc_types.h"
+
+typedef unsigned int mode_t;
 typedef int pid_t;
-typedef int uid_t;
+typedef unsigned int uid_t;
+typedef unsigned int gid_t;
+typedef unsigned int dev_t;
+typedef unsigned int ino_t;
+typedef unsigned int nlink_t;
+typedef int blksize_t;
+typedef int blkcnt_t;
 
 #endif

+ 5 - 0
diskfs/stdlib/time.h

@@ -17,6 +17,11 @@ struct tm {
     int tm_isdst;
 };
 
+struct timespec {
+    time_t tv_sec;
+    time_t tv_nsec;
+};
+
 // STUB
 struct tm *localtime(const time_t *time) {
     __unimplemented();

+ 6 - 4
diskfs/stdlib/unistd.h

@@ -1,6 +1,12 @@
 #ifndef __UNISTD_H
 #define __UNISTD_H
 
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+off_t lseek(int fildes, off_t offset, int whence);
+
 #include "asmc.h"
 #include "sys/stat.h"
 #include "errno.h"
@@ -72,8 +78,4 @@ int ftruncate(int fildes, off_t length) {
     return -1;
 }
 
-#define SEEK_SET 0
-#define SEEK_CUR 1
-#define SEEK_END 2
-
 #endif