diff --git a/.gitignore b/.gitignore index 017b7400..58cb2afb 100644 --- a/.gitignore +++ b/.gitignore @@ -58,12 +58,14 @@ /scaffold/hello /scaffold/main /scaffold/micro-mes +/scaffold/read /scaffold/tiny-mes /scaffold/argv-m2 /scaffold/hello-m2 /scaffold/main-m2 /scaffold/micro-mes-m2 +/scaffold/read-m2 /scaffold/tiny-mes-m2 /.config.make diff --git a/include/linux/x86/syscall.h b/include/linux/x86/syscall.h index e8de351a..346548cf 100644 --- a/include/linux/x86/syscall.h +++ b/include/linux/x86/syscall.h @@ -20,24 +20,41 @@ #ifndef __MES_LINUX_X86_SYSCALL_H #define __MES_LINUX_X86_SYSCALL_H 1 -// libc-mini -// #define SYS_exit 0x01 -// #define SYS_write 0x04 +/* libc-mini */ +#ifndef SYS_exit +// CONSTANT SYS_exit 0x01 +#define SYS_exit 0x01 +#endif +#ifndef SYS_write +// CONSTANT SYS_write 0x04 +#define SYS_write 0x04 +#endif -// libc +/* libc */ +// CONSTANT SYS_fork 0x02 #define SYS_fork 0x02 +// CONSTANT SYS_read 0x03 #define SYS_read 0x03 +// CONSTANT SYS_open 0x05 #define SYS_open 0x05 +// CONSTANT SYS_waitpid 0x07 #define SYS_waitpid 0x07 +// CONSTANT SYS_wait4 0x72 #define SYS_wait4 0x72 +// CONSTANT SYS_execve 0x0b #define SYS_execve 0x0b +// CONSTANT SYS_chmod 0x0f #define SYS_chmod 0x0f +// CONSTANT SYS_access 0x21 #define SYS_access 0x21 +// CONSTANT SYS_brk 0x2d #define SYS_brk 0x2d +// CONSTANT SYS_ioctl 0x36 #define SYS_ioctl 0x36 +// CONSTANT SYS_fsync 0x76 #define SYS_fsync 0x76 -// libc+tcc +/* libc+tcc */ #define SYS_close 0x06 #define SYS_time 0x0d #define SYS_lseek 0x13 @@ -47,7 +64,7 @@ #define SYS_stat 0x6a #define SYS_getcwd 0xb7 -// libc+gnu +/* libc+gnu */ #define SYS_chdir 0x0c #define SYS_link 0x09 @@ -73,19 +90,19 @@ #define SYS_getdents 0x8d #define SYS_clock_gettime 0x109 -// bash +/* bash */ #define SYS_setuid 0x17 #define SYS_geteuid 0x31 #define SYS_getegid 0x32 #define SYS_setgid 0x3e #define SYS_getppid 0x40 -// make+POSIX +/* make+POSIX */ #define SYS_sigprocmask 0x7e -// tar +/* tar */ #define SYS_symlink 0x53 #define SYS_readlink 0x55 #define SYS_mknod 0x0e -#endif // __MES_LINUX_X86_SYSCALL_H +#endif /* __MES_LINUX_X86_SYSCALL_H */ diff --git a/include/m2/lib.h b/include/m2/lib.h index 620ef193..f9ecfc78 100644 --- a/include/m2/lib.h +++ b/include/m2/lib.h @@ -27,4 +27,7 @@ int __stdout; int __stderr; int errno; +// CONSTANT EOF 0xffffffff +// CONSTANT __FILEDES_MAX 512 + #endif /* __M2_LIB_H */ diff --git a/lib/linux/brk.c b/lib/linux/brk.c index 9566f19c..88a4f999 100644 --- a/lib/linux/brk.c +++ b/lib/linux/brk.c @@ -24,5 +24,5 @@ long brk (void *addr) { - return _sys_call1 (SYS_brk, (long) addr); + return _sys_call1 (SYS_brk, addr); } diff --git a/lib/linux/read.c b/lib/linux/read.c index 4db3877f..34e65949 100644 --- a/lib/linux/read.c +++ b/lib/linux/read.c @@ -26,21 +26,22 @@ ssize_t read (int filedes, void *buffer, size_t size) { - ssize_t bytes = _sys_call3 (SYS_read, (int) filedes, (long) buffer, (long) size); + ssize_t bytes = _sys_call3 (SYS_read, filedes, buffer, size); if (__mes_debug () > 4) { if (bytes == 1) { eputs ("read fd="); - eputs (itoa ((int) filedes)); + eputs (itoa (filedes)); eputs (" c="); - eputc (*(char *) buffer); + char *s = buffer; + eputc (s[0]); eputs ("\n"); } else { eputs ("read fd="); - eputs (itoa ((int) filedes)); + eputs (itoa (filedes)); eputs (" bytes="); eputs (itoa (bytes)); eputs ("\n"); diff --git a/lib/linux/x86-mes-m2/syscall.c b/lib/linux/x86-mes-m2/syscall.c new file mode 100644 index 00000000..3b8b624c --- /dev/null +++ b/lib/linux/x86-mes-m2/syscall.c @@ -0,0 +1,139 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU 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. + * + * GNU 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 GNU Mes. If not, see . + */ + +#include +#include + +int errno; + +int +__sys_call (int sys_call) +{ + asm ("mov____0x8(%ebp),%eax !-4"); + asm ("int____$0x80"); +} + +int +__sys_call1 (int sys_call, int one) +{ + asm ("mov____0x8(%ebp),%eax !-4"); + asm ("mov____0x8(%ebp),%ebx !-8"); + asm ("int____$0x80"); +} + +int +__sys_call2 (int sys_call, int one, int two) +{ + asm ("mov____0x8(%ebp),%eax !-4"); + asm ("mov____0x8(%ebp),%ebx !-8"); + asm ("mov____0x8(%ebp),%ecx !-12"); + asm ("int____$0x80"); +} + +int +__sys_call3 (int sys_call, int one, int two, int three) +{ + asm ("mov____0x8(%ebp),%eax !-4"); + asm ("mov____0x8(%ebp),%ebx !-8"); + asm ("mov____0x8(%ebp),%ecx !-12"); + asm ("mov____0x8(%ebp),%edx !-16"); + asm ("int____$0x80"); +} + +int +__sys_call4 (int sys_call, int one, int two, int three, int four) +{ + asm ("mov____0x8(%ebp),%eax !-4"); + asm ("mov____0x8(%ebp),%ebx !-8"); + asm ("mov____0x8(%ebp),%ecx !-12"); + asm ("mov____0x8(%ebp),%edx !-16"); + asm ("mov____0x8(%ebp),%esi !-20"); + asm ("int____$0x80"); +} + +int +_sys_call (int sys_call) +{ + int r = __sys_call (sys_call); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +int +_sys_call1 (int sys_call, int one) +{ + int r = __sys_call1 (sys_call, one); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +int +_sys_call2 (int sys_call, int one, int two) +{ + int r = __sys_call2 (sys_call, one, two); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +int +_sys_call3 (int sys_call, int one, int two, int three) +{ + int r = __sys_call3 (sys_call, one, two, three); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +int +_sys_call4 (int sys_call, int one, int two, int three, int four) +{ + int r = __sys_call4 (sys_call, one, two, three, four); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} diff --git a/lib/m2/malloc.c b/lib/m2/malloc.c new file mode 100644 index 00000000..4c3488d0 --- /dev/null +++ b/lib/m2/malloc.c @@ -0,0 +1,36 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2018,2019,2021 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU 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. + * + * GNU 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 GNU Mes. If not, see . + */ + +#include +#include + +char *__brk = 0; + +void * +malloc (size_t size) +{ + if (!__brk) + __brk = cast_long_to_charp (brk (0)); + if (brk (__brk + size) == -1) + return 0; + char *p = __brk; + __brk = __brk + size; + return p; +} diff --git a/lib/m2/mes_open.c b/lib/m2/mes_open.c new file mode 100644 index 00000000..a0e06998 --- /dev/null +++ b/lib/m2/mes_open.c @@ -0,0 +1,29 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU 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. + * + * GNU 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 GNU Mes. If not, see . + */ + +int +mes_open (char *file_name, int flags, int mask) +{ + __ungetc_init (); + int filedes = open (file_name, flags, mask); + if (filedes > 2) + __ungetc_clear (filedes); + return filedes; +} diff --git a/lib/m2/open.c b/lib/m2/open.c new file mode 100644 index 00000000..a240f1a4 --- /dev/null +++ b/lib/m2/open.c @@ -0,0 +1,33 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU 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. + * + * GNU 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 GNU Mes. If not, see . + */ + +#include +#include +#include + +int +open (char *file_name, int flags, int mask) +{ + int r = _sys_call3 (SYS_open, file_name, flags, mask); + __ungetc_init (); + if (r > 2) + __ungetc_clear (r); + return r; +} diff --git a/lib/m2/read.c b/lib/m2/read.c new file mode 100644 index 00000000..b1d911a1 --- /dev/null +++ b/lib/m2/read.c @@ -0,0 +1,31 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2019,2020 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU 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. + * + * GNU 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 GNU Mes. If not, see . + */ + +#include +#include +#include +#include + +long +read (int filedes, void *buffer, long size) +{ + long bytes = _sys_call3 (SYS_read, filedes, buffer, size); + return bytes; +} diff --git a/lib/stdio/putchar.c b/lib/stdio/putchar.c index 7bd5ef63..a247423c 100644 --- a/lib/stdio/putchar.c +++ b/lib/stdio/putchar.c @@ -23,6 +23,7 @@ int putchar (int c) { - write (STDOUT, (char *) &c, 1); + char *p = &c; + write (__stdout, p, 1); return 0; } diff --git a/lib/string/memset.c b/lib/string/memset.c index cca90095..223276de 100644 --- a/lib/string/memset.c +++ b/lib/string/memset.c @@ -1,6 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * GNU Mes --- Maxwell Equations of Software - * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen + * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen * * This file is part of GNU Mes. * @@ -20,11 +20,21 @@ #include +char * +_memset (char *s, int c, size_t n) +{ + char *p = s; + while (n != 0) + { + n = n - 1; + s[0] = c; + s = s + 1; + } + return p; +} + void * memset (void *s, int c, size_t n) { - char *p = s; - while (n--) - *p++ = c; - return s; + return _memset (s, c, n); } diff --git a/scaffold/read.c b/scaffold/read.c index 58b28ef9..81bc33eb 100644 --- a/scaffold/read.c +++ b/scaffold/read.c @@ -1,6 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * GNU Mes --- Maxwell Equations of Software - * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen + * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen * * This file is part of GNU Mes. * @@ -23,12 +23,12 @@ #include int -main (int argc, char *argv[]) +main (int argc, char **argv) { - __stdin = open ("scaffold/read.data", 0); + __stdin = open ("scaffold/read.data", 0, 0); int c = getchar (); if (c != 'm') - return 1; + return c; while (c != EOF) { putchar (c); diff --git a/scaffold/read.kaem b/scaffold/read.kaem new file mode 100644 index 00000000..5bd2083d --- /dev/null +++ b/scaffold/read.kaem @@ -0,0 +1,72 @@ +#! /bin/sh +# Copyright © 2019 Jan (janneke) Nieuwenhuizen +# +# This file is part of GNU Mes. +# +# GNU 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. +# +# GNU 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 GNU Mes. If not, see . + +# Usage: +# kaem --verbose --strict --file scaffold/read.kaem +# scaffold/read-m2 + +mes_cpu=${mes_cpu:-x86} +stage0_cpu=${stage0_cpu:-x86} + +M2-Planet \ + --debug \ + --architecture ${stage0_cpu} \ + -f include/m2/lib.h \ + -f lib/linux/${mes_cpu}-mes-m2/crt1.c \ + -f lib/linux/${mes_cpu}-mes-m2/_exit.c \ + -f lib/linux/${mes_cpu}-mes-m2/_write.c \ + -f lib/linux/${mes_cpu}-mes-m2/syscall.c \ + -f include/linux/${mes_cpu}/syscall.h \ + -f lib/m2/cast.c \ + -f lib/string/strlen.c \ + -f lib/mes/mini-write.c \ + -f lib/mes/eputs.c \ + -f lib/linux/brk.c \ + -f lib/m2/malloc.c \ + -f lib/string/memset.c \ + -f lib/m2/read.c \ + -f lib/mes/fdgetc.c \ + -f lib/stdio/getchar.c \ + -f lib/stdio/putchar.c \ + -f lib/m2/open.c \ + -f lib/m2/mes_open.c \ + -f scaffold/read.c \ + -o scaffold/read.M1 + +blood-elf -f scaffold/read.M1 -o scaffold/read.blood-elf-M1 + +M1 \ + --architecture ${stage0_cpu} \ + --little-endian \ + -f lib/m2/${mes_cpu}/${mes_cpu}_defs.M1 \ + -f lib/${mes_cpu}-mes/${mes_cpu}.M1 \ + -f lib/linux/${mes_cpu}-mes-m2/crt1.M1 \ + -f scaffold/read.M1 \ + -f scaffold/read.blood-elf-M1 \ + -o scaffold/read.hex2 + +hex2 \ + --architecture ${stage0_cpu} \ + --little-endian \ + --base-address 0x1000000 \ + -f lib/m2/${mes_cpu}/ELF-${mes_cpu}.hex2 \ + -f scaffold/read.hex2 \ + -o scaffold/read-m2 + +echo Now run: scaffold/read-m2 +./scaffold/read-m2