diff --git a/.gitignore b/.gitignore index e0b0fdb1..12843de4 100644 --- a/.gitignore +++ b/.gitignore @@ -59,12 +59,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 /src/mes 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/lib/linux/x86-mes-m2/syscall.c b/lib/linux/x86-mes-m2/syscall.c new file mode 100644 index 00000000..7f3d1d33 --- /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 !-24"); + 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/brk.c b/lib/m2/brk.c new file mode 100644 index 00000000..12ab3ce5 --- /dev/null +++ b/lib/m2/brk.c @@ -0,0 +1,28 @@ +/* -*-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 + +int /*long*/ +brk (void *addr) +{ + return _sys_call1 (SYS_brk, addr); +} diff --git a/lib/m2/fdgetc.c b/lib/m2/fdgetc.c new file mode 100644 index 00000000..4b2362c7 --- /dev/null +++ b/lib/m2/fdgetc.c @@ -0,0 +1,84 @@ +/* -*-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 +#include +#include +#include +#include + +// CONSTANT __FILEDES_MAX 512 + +int errno; +int *__ungetc_buf; + +int +__ungetc_p (int filedes) +{ + return __ungetc_buf[filedes] >= 0; +} + +void +__ungetc_init () +{ + if (__ungetc_buf == 0) + { + int save_errno = errno; + __ungetc_buf = malloc ((__FILEDES_MAX + 1) * sizeof (int)); + errno = save_errno; + memset (__ungetc_buf, -1, (__FILEDES_MAX + 1) * sizeof (int)); + } +} + +void +__ungetc_clear (int filedes) +{ + __ungetc_buf[filedes] = -1; +} + +void +__ungetc_set (int filedes, int c) +{ + __ungetc_buf[filedes] = c; +} + +int +fdgetc (int fd) +{ + __ungetc_init (); + + char c; + int i = __ungetc_buf[fd]; + if (i >= 0) + __ungetc_buf[fd] = -1; + else + { + int r = read (fd, &c, 1); + if (r < 1) + return -1; + i = c; + } + if (i < 0) + i = i + 256; + + return i; +} diff --git a/lib/m2/malloc.c b/lib/m2/malloc.c new file mode 100644 index 00000000..8aaa7d00 --- /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 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 (int size) +{ + if (!__brk) + __brk = brk (0); + if (brk (__brk + size) == -1) + return 0; + char *p = __brk; + __brk = __brk + size; + return p; +} diff --git a/lib/m2/memset.c b/lib/m2/memset.c new file mode 100644 index 00000000..2c09ca99 --- /dev/null +++ b/lib/m2/memset.c @@ -0,0 +1,34 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 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 + +void * +memset (void *s, int c, int n) +{ + char *p = s; + while (n) + { + n = n -1; + p[0] = c; + p = p + 1; + } + return s; +} diff --git a/lib/m2/open.c b/lib/m2/open.c index 7f6b1b5f..a240f1a4 100644 --- a/lib/m2/open.c +++ b/lib/m2/open.c @@ -1,6 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * GNU Mes --- Maxwell Equations of Software - * Copyright © 2019 Jan (janneke) Nieuwenhuizen + * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen * * This file is part of GNU Mes. * @@ -18,4 +18,16 @@ * along with GNU Mes. If not, see . */ -int open (char *file_name, int flags, int mask); +#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/putchar.c b/lib/m2/putchar.c new file mode 100644 index 00000000..8cd3eb91 --- /dev/null +++ b/lib/m2/putchar.c @@ -0,0 +1,28 @@ +/* -*-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 + +int +putchar (int c) +{ + write (__stdout, &c, 1); + return 0; +} diff --git a/lib/m2/read.c b/lib/m2/read.c index 033ee359..9c529f30 100644 --- a/lib/m2/read.c +++ b/lib/m2/read.c @@ -1,6 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * GNU Mes --- Maxwell Equations of Software - * Copyright © 2019 Jan (janneke) Nieuwenhuizen + * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen * * This file is part of GNU Mes. * @@ -18,4 +18,14 @@ * along with GNU Mes. If not, see . */ -int read (int filedes, void *buffer, int size); +#include +#include +#include +#include + +int +read (int filedes, void *buffer, int size) +{ + int bytes = _sys_call3 (SYS_read, filedes, buffer, size); + return bytes; +} diff --git a/scaffold/read.c b/scaffold/read.c index 58b28ef9..9fb9dff1 100644 --- a/scaffold/read.c +++ b/scaffold/read.c @@ -22,13 +22,15 @@ #include #include +// CONSTANT EOF 0xffffffff + 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..15e4a5e5 --- /dev/null +++ b/scaffold/read.kaem @@ -0,0 +1,66 @@ +#!/bin/bash +# Copyright (C) 2019 Jeremiah Orians +# 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 + +M2-Planet \ + --debug \ + --architecture x86 \ + -f lib/linux/x86-mes-m2/crt1.c \ + -f lib/linux/x86-mes-m2/mini.c \ + -f lib/linux/x86-mes-m2/syscall.c \ + -f include/linux/x86/syscall.h \ + -f lib/m2/brk.c \ + -f lib/m2/malloc.c \ + -f lib/m2/memset.c \ + -f lib/m2/read.c \ + -f lib/m2/fdgetc.c \ + -f lib/stdio/getchar.c \ + -f lib/m2/write.c \ + -f lib/m2/putchar.c \ + -f lib/m2/open.c \ + -f lib/m2/mes_open.c \ + -f lib/m2/strlen.c \ + -f lib/m2/write.c \ + -f lib/m2/eputs.c \ + -f scaffold/read.c \ + -o scaffold/read.M1 + +blood-elf -f scaffold/read.M1 -o scaffold/read.blood-elf-M1 + +M1 \ + --LittleEndian \ + --architecture x86 \ + -f lib/m2/x86/x86_defs.M1 \ + -f lib/x86-mes/x86.M1 \ + -f lib/linux/x86-mes-m2/crt1.M1 \ + -f scaffold/read.M1 \ + -f scaffold/read.blood-elf-M1 \ + -o scaffold/read.hex2 + +hex2 \ + --LittleEndian \ + --architecture x86 \ + --BaseAddress 0x1000000 \ + --exec_enable \ + -f lib/x86-mes/elf32-header.hex2 \ + -f scaffold/read.hex2 \ + -o scaffold/read-m2 + +echo Now run: scaffold/read-m2