From 784838e368393b469fccbd071c0d8a98032c8a86 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sun, 10 Mar 2019 16:52:05 -0400 Subject: [PATCH] hurd: Initial support. This adds minimal Hurd support by implementing the _exit function. * AUTHORS: Update. * .gitignore: Ignore a.out, core, .config. * include/sys/wait.h (W_EXITCODE): New define. * lib/gnu/x86-mes-gcc/crt1.c: New file. * lib/gnu/x86-mes-gcc/mini.c: New file. * lib/gnu/hurd-start.c: New file. * lib/gnu/_exit.c: New file. * include/gnu/syscall.h: New file. * include/gnu/hurd.h: New file. * lib/gnu/_exit.c: New file. * lib/gnu/exec-startup-get-data.c: New file. * lib/gnu/hurd-start.c: New file. * lib/gnu/proc-mark-exit.c: New file. * lib/gnu/syscall.c: New file. * lib/gnu/task-get-special-port.c: New file. * lib/gnu/task-terminate.c: New file. * lib/gnu/vm-statistics.c: New file. * build-aux/configure-lib.sh (libc_mini_SOURCES): Add Hurd sources. * build-aux/build.sh.in (CPPFLAGS): Add lib to includes, to find linux crt1.c. * build-aux/test-c.sh: Always use at least -l c+mini for GNU. * lib/tests/scaffold/30-exit-42.exit: New file. * lib/tests/scaffold/30-exit-42.c: New test. * build-aux/check-mescc.sh (TESTS): Add it. * lib/tests/scaffold/30-exit-0.c (main): Move from 00-exit-0.c; Rewrite, use _exit. * include/gnu/hurd-types.h: Import from GNU C Library. * include/mach/mach-init.h: Likewise. * lib/mach/mach-init.c: Likewise. * lib/mach/mach_host_self.S: Likewise. * lib/mach/mach_msg_trap.S: Likewise. * lib/mach/mach_reply_port.S: Likewise. * lib/mach/mach_task_self.S: Likewise. * lib/mach/mach_thread_self.S: Likewise. * lib/mach/msg.c: Likewise. --- .gitignore | 3 + AUTHORS | 7 + build-aux/build.sh.in | 9 + build-aux/cflags.sh | 6 + build-aux/check-mescc.sh | 3 +- build-aux/configure-lib.sh | 20 + build-aux/test-c.sh | 5 + include/gnu/hurd-types.h | 393 ++++++++++++++++++ include/gnu/hurd.h | 51 +++ include/gnu/syscall.h | 115 +++++ include/mach/mach-init.h | 52 +++ include/sys/wait.h | 3 +- lib/gnu/_exit.c | 38 ++ lib/gnu/exec-startup-get-data.c | 57 +++ lib/gnu/hurd-start.c | 47 +++ lib/gnu/proc-mark-exit.c | 28 ++ lib/gnu/syscall.c | 99 +++++ lib/gnu/task-get-special-port.c | 37 ++ lib/gnu/task-terminate.c | 27 ++ lib/gnu/vm-statistics.c | 41 ++ lib/gnu/x86-mes-gcc/crt1.c | 43 ++ lib/gnu/x86-mes-gcc/mini.c | 23 + lib/mach/mach-init.c | 52 +++ lib/mach/mach_host_self.S | 3 + lib/mach/mach_msg_trap.S | 3 + lib/mach/mach_reply_port.S | 3 + lib/mach/mach_task_self.S | 3 + lib/mach/mach_thread_self.S | 19 + lib/mach/msg.c | 145 +++++++ .../scaffold/{00-exit-0.c => 30-exit-0.c} | 37 +- lib/tests/scaffold/30-exit-42.c | 26 ++ lib/tests/scaffold/30-exit-42.exit | 1 + 32 files changed, 1363 insertions(+), 36 deletions(-) create mode 100644 include/gnu/hurd-types.h create mode 100644 include/gnu/hurd.h create mode 100644 include/gnu/syscall.h create mode 100644 include/mach/mach-init.h create mode 100644 lib/gnu/_exit.c create mode 100644 lib/gnu/exec-startup-get-data.c create mode 100644 lib/gnu/hurd-start.c create mode 100644 lib/gnu/proc-mark-exit.c create mode 100644 lib/gnu/syscall.c create mode 100644 lib/gnu/task-get-special-port.c create mode 100644 lib/gnu/task-terminate.c create mode 100644 lib/gnu/vm-statistics.c create mode 100644 lib/gnu/x86-mes-gcc/crt1.c create mode 100644 lib/gnu/x86-mes-gcc/mini.c create mode 100644 lib/mach/mach-init.c create mode 100644 lib/mach/mach_host_self.S create mode 100644 lib/mach/mach_msg_trap.S create mode 100644 lib/mach/mach_reply_port.S create mode 100644 lib/mach/mach_task_self.S create mode 100644 lib/mach/mach_thread_self.S create mode 100644 lib/mach/msg.c rename lib/tests/scaffold/{00-exit-0.c => 30-exit-0.c} (51%) create mode 100644 lib/tests/scaffold/30-exit-42.c create mode 100644 lib/tests/scaffold/30-exit-42.exit diff --git a/.gitignore b/.gitignore index 9b635664..e7ae9341 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,6 @@ /body-hello-mes /exit-42 /hello-mes +core +/.config +a.out diff --git a/AUTHORS b/AUTHORS index 7349a3d0..858c53ad 100644 --- a/AUTHORS +++ b/AUTHORS @@ -73,6 +73,13 @@ mes/module/srfi/srfi-26.scm GNU FDL in texinfo from GNU doc/fdl-1.3.texi +Hurd and Mach support from GNU C Library +include/gnu/hurd-types.h +include/mach/mach-init.h +lib/mach/msg.c +lib/mach/mach-init.c +lib/mach/*.S + * legalese Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen diff --git a/build-aux/build.sh.in b/build-aux/build.sh.in index 907e4bba..05a520ba 100644 --- a/build-aux/build.sh.in +++ b/build-aux/build.sh.in @@ -65,10 +65,17 @@ fi " AM_CPPFLAGS=" -D HAVE_CONFIG_H=1 +-I ${srcdest}lib -I include -I ${srcdest}include -I ${srcdest}include/$mes_kernel/$mes_cpu " + if test $mes_kernel = gnu; then + AM_CPPFLAGS="$AM_CPPFLAGS +-I /usr/include +" + fi + ${SHELL} ${srcdest}build-aux/build-lib.sh cp crt1.o .. fi @@ -85,6 +92,7 @@ fi AM_CPPFLAGS=" -D HAVE_CONFIG_H=1 +-I ${srcdest}lib -I include -I ${srcdest}include -I ${srcdest}include/$mes_kernel/$mes_cpu @@ -108,6 +116,7 @@ fi fi AM_CPPFLAGS=" -D HAVE_CONFIG_H=1 +-I ${srcdest}lib -I include -I ${srcdest}include -I ${srcdest}include/$mes_kernel/$mes_cpu diff --git a/build-aux/cflags.sh b/build-aux/cflags.sh index 835a5f83..2ce778a7 100644 --- a/build-aux/cflags.sh +++ b/build-aux/cflags.sh @@ -22,6 +22,12 @@ AM_CPPFLAGS=" -I ${srcdest}include/$mes_kernel/$mes_cpu " +if test $mes_kernel = gnu; then + AM_CPPFLAGS="$AM_CPPFLAGS +-I /usr/include +" +fi + AM_CFLAGS= if test $mes_libc = mes; then diff --git a/build-aux/check-mescc.sh b/build-aux/check-mescc.sh index 8abd9d7a..68865e8b 100755 --- a/build-aux/check-mescc.sh +++ b/build-aux/check-mescc.sh @@ -24,7 +24,6 @@ set -u TESTS=" lib/tests/scaffold/t.c -lib/tests/scaffold/00-exit-0.c lib/tests/scaffold/01-return-0.c lib/tests/scaffold/02-return-1.c lib/tests/scaffold/03-call.c @@ -77,6 +76,8 @@ lib/tests/scaffold/23-pointer-sub.c lib/tests/scaffold/23-pointer.c lib/tests/mes/30-oputs.c lib/tests/string/30-strlen.c +lib/tests/scaffold/30-exit-0.c +lib/tests/scaffold/30-exit-42.c lib/tests/scaffold/32-call-wrap.c lib/tests/scaffold/32-compare.c lib/tests/scaffold/33-and-or.c diff --git a/build-aux/configure-lib.sh b/build-aux/configure-lib.sh index c9d0e98c..af1803ad 100644 --- a/build-aux/configure-lib.sh +++ b/build-aux/configure-lib.sh @@ -41,6 +41,26 @@ lib/stdlib/exit.c lib/stdlib/puts.c lib/string/strlen.c " + + if test $mes_kernel = gnu; then + libc_mini_shared_SOURCES="$libc_mini_shared_SOURCES +lib/gnu/_exit.c +lib/gnu/exec-startup-get-data.c +lib/gnu/hurd-start.c +lib/gnu/proc-mark-exit.c +lib/gnu/syscall.c +lib/gnu/task-get-special-port.c +lib/gnu/task-terminate.c +lib/gnu/vm-statistics.c +lib/mach/mach-init.c +lib/mach/mach_host_self.S +lib/mach/mach_msg_trap.S +lib/mach/mach_reply_port.S +lib/mach/mach_task_self.S +lib/mach/mach_thread_self.S +lib/mach/msg.c +" + fi fi libc_mini_SOURCES="$libc_mini_shared_SOURCES" diff --git a/build-aux/test-c.sh b/build-aux/test-c.sh index 49c6f385..00844075 100755 --- a/build-aux/test-c.sh +++ b/build-aux/test-c.sh @@ -52,6 +52,11 @@ else LIBS='-l c' fi +if test $mes_kernel = gnu\ + && test -z "$LIBS"; then + LIBS="-l c-mini" +fi + if test $mes_libc = system; then crt1= LIBS='-l mes' diff --git a/include/gnu/hurd-types.h b/include/gnu/hurd-types.h new file mode 100644 index 00000000..a156b64e --- /dev/null +++ b/include/gnu/hurd-types.h @@ -0,0 +1,393 @@ +/* C declarations for Hurd server interfaces + Copyright (C) 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2002, + 2010 Free Software Foundation, Inc. + +This file is part of the GNU Hurd. + +The GNU Hurd 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 2, or (at your option) +any later version. + +The GNU Hurd 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 the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _HURD_TYPES_H +#define _HURD_TYPES_H + +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 32 +#endif + +#include /* For struct timespec. */ +#include /* For mach_port_t et al. */ +#include /* For mach_msg_id_t et al. */ +#include /* For pid_t and uid_t. */ + +/* A string identifying this release of the GNU Hurd. Our + interpretation of the term "release" is that it refers to a set of + server interface definitions. A "version" in Posix terminology is + a distribution of the Hurd; there may be more than one distribution + without changing the release number. */ +#define HURD_RELEASE "0.0" + + +/* Simple type declarations */ + +/* These types identify certain kinds of ports used by the Hurd. */ +typedef mach_port_t file_t; +typedef mach_port_t fsys_t; +typedef mach_port_t io_t; +typedef mach_port_t process_t; +typedef mach_port_t auth_t; +typedef mach_port_t socket_t; +typedef mach_port_t pf_t; /* Protocol family */ +typedef mach_port_t addr_port_t; +typedef mach_port_t startup_t; +typedef mach_port_t fs_notify_t; +typedef mach_port_t exec_startup_t; +typedef mach_port_t interrupt_t; +typedef mach_port_t proccoll_t; +typedef mach_port_t ctty_t; + +#include /* Defines `error_t'. */ + +/* These names exist only because of MiG deficiencies. + You should not use them in C source; use the normal C types instead. */ +typedef char *data_t; +typedef const char *const_data_t; +typedef char string_t [1024]; +typedef int *intarray_t; +typedef const int *const_intarray_t; +typedef int *fd_mask_t; +typedef const int *const_fd_mask_t; +typedef mach_port_t *portarray_t; +typedef const mach_port_t *const_portarray_t; +typedef pid_t *pidarray_t; +typedef const pid_t *const_pidarray_t; +typedef uid_t *idarray_t; +typedef const uid_t *const_idarray_t; +#if 0 +typedef __loff_t *off_array_t; +typedef const __loff_t *const_off_array_t; +#endif +typedef struct rusage rusage_t; +typedef struct flock flock_t; +typedef struct utsname utsname_t; +#if _FILE_OFFSET_BITS == 64 +typedef struct stat io_statbuf_t; +typedef struct statfs fsys_statfsbuf_t; +#else +typedef struct stat64 io_statbuf_t; +typedef struct statfs64 fsys_statfsbuf_t; +#endif +typedef struct timespec timespec_t; + + +/* Parameters and flags in RPC calls */ + +/* Many such parameters and flags are also defined in various libc + headers. */ + +/* Bits for flags in fs.defs:file_exec_paths and exec.defs:exec_* calls: */ +#define EXEC_NEWTASK 0x00000001 /* Create new task; kill old one. */ +#define EXEC_SECURE 0x00000002 /* Use secure values of portarray, etc. */ +#define EXEC_DEFAULTS 0x00000004 /* Use defaults for unspecified ports. */ +#define EXEC_SIGTRAP 0x00000008 /* Simulate SIGTRAP on startup. */ +/* This flag is passed through by the exec server but not examined by it. */ +#define EXEC_STACK_ARGS 0x00000010 /* Use arguments from stack, not RPC. */ + +/* Bits for flags in fs.defs:file_set_translator call: */ +#define FS_TRANS_FORCE 0x00000001 /* Must use translator(no sht circuit) */ +#define FS_TRANS_EXCL 0x00000002 /* Don't do it if already translated. */ +#define FS_TRANS_SET 0x00000004 /* Set or clear translator */ +#define FS_TRANS_ORPHAN 0x00000008 /* Orphan the active translator. */ + +/* Values for retry field in fs.defs:dir_lookup call: */ +enum retry_type +{ + FS_RETRY_NORMAL = 1, /* Retry normally if retry_name is not null. */ + FS_RETRY_REAUTH = 2, /* Retry after reauthenticating retry port. + Even if the retry name is null, a retry + is still necessary with this code after the + reauthentication is complete. */ + FS_RETRY_MAGICAL = 3, /* Retry string is magical. */ + /* "tty" means controlling tty; + + "fd/%u" means file descriptor N; + + "machtype/..." means replace `machtype' with the numbers in decimal + returned by the user's kernel as the cpu_type (N) and + cpu_subtype (M) (producing N/M/...) and then retry + as for FS_RETRY_NORMAL. + + "/..." means retry "...", but starting from the users root directory. + + "pid/..." means replace `pid' with the PID of the current process in %u + format and then retry as for FS_RETRY_NORMAL. + */ +}; +typedef enum retry_type retry_type; + +/* Types for fs_notify.defs:dir_changed call: */ +enum dir_changed_type +{ + DIR_CHANGED_NULL, /* Always sent first for sync. */ + DIR_CHANGED_NEW, /* Specified name has been added. */ + DIR_CHANGED_UNLINK, /* Specified name has been removed. */ + DIR_CHANGED_RENUMBER, /* Name has been the target of rename. */ +}; +typedef enum dir_changed_type dir_changed_type_t; + +/* Types for fs_notify.defs:file_changed call: */ +enum file_changed_type +{ + FILE_CHANGED_NULL, /* Always sent first for sync. */ + FILE_CHANGED_WRITE, /* File data has been written. */ + FILE_CHANGED_EXTEND, /* File has grown. */ + FILE_CHANGED_TRUNCATE, /* File has been truncated. */ + FILE_CHANGED_META, /* Stat information has changed, and none + of the previous three apply. Not sent + for changes in node times. */ +}; +typedef enum file_changed_type file_changed_type_t; + +/* Select types for io.defs:io_select call: */ +#define SELECT_READ 0x00000001 +#define SELECT_WRITE 0x00000002 +#define SELECT_URG 0x00000004 + +/* Flags for fsys.defs:fsys_goaway. Also, these flags are sent as the + oldtrans_flags in fs.defs:file_set_translator to describe how to + terminate the old translator. */ +#define FSYS_GOAWAY_NOWAIT 0x00000001 /* Return immediately. */ +#define FSYS_GOAWAY_NOSYNC 0x00000002 /* Don't update physical media. */ +#define FSYS_GOAWAY_FORCE 0x00000004 /* Go away despite current users. */ +#define FSYS_GOAWAY_UNLINK 0x00000008 /* Go away only if non-directory. */ +#define FSYS_GOAWAY_RECURSE 0x00000010 /* Shutdown children too. */ + +/* Types of ports the terminal driver can run on top of; + used in term.defs:term_get_bottom_type. */ +enum term_bottom_type +{ + TERM_ON_MACHDEV, + TERM_ON_HURDIO, + TERM_ON_MASTERPTY, +}; + +/* Types of storage, as returned by file_get_storage_info. + + STORAGE_DEVICE is a mach device_t (for random access devices) + STORAGE_HURD_FILE is a hurd file_t (as if a file were mapped) + STORAGE_TASK is a task_t (the storage is in the vm of the task) + STORAGE_MEMORY is a memory object port + STORAGE_ZERO is a fixed-size constant source of zeros + STORAGE_INTERLEAVE is a set of other storage types interleaved at a fixed + interval + STORAGE_CONCAT is a set of other storage types concatenated end-to-end + STORAGE_LAYER is a set of storage types, representing the same address + range; all will be written too, and will be read in turn until one + succeeds + STORAGE_REMAP is a layer on top of another store that remaps its blocks + STORAGE_COPY is a memory snapshot of another store + STORAGE_NETWORK means that the file is stored elsewhere on the + network; all the remaining fields contan type-specific information. + STORAGE_OTHER means none of these apply; and should be used when no + meaningful answer can be given + + The vectors returned by file_get_storage_info encode each of the above + (note that the first int is always the storage type). There are four: + ports, ints, offsets (off_t), and data (char); each type of store uses the + following entries in each vector: + + -type- -ports- -ints- -offsets- -data- -kids- + device DEVICE TY, FL, BS, NR, NL, ML NR * (OFFS, LEN) NL + ML - + file FILE TY, FL, BS, NR, NL, ML NR * (OFFS, LEN) NL + ML - + memory MEMOBJ TY, FL, BS, NR, NL, ML NR * (OFFS, LEN) NL + ML - + task TASK TY, FL, BS, NR, NL, ML NR * (OFFS, LEN) NL + ML - + (the data for the above is a name (incl '\0') and a misc data block) + null - TY, FL SIZE - - + (BS is 1) + ileave - TY, FL, IL, NC - - NC + (BS is the LCM of its children; SIZE is the minimum of theirs * IL) + concat - TY, FL, NC - - NC + (BS is the LCM of its children; SIZE is the sum of theirs) + layer - TY, FL, NC - - NC + (BS is the LCM of its children; SIZE is the minimum of theirs) + remap - TY, FL, NR NR * (OFFS, LEN) - 1 + (BS and SIZE are that of the child) + copy - TY, FL, SIZE - DATA - + (DATA is preceded by padding to the next page boundary, and is + SIZE bytes long itself) + + For ileave, concat, and layer, the children are encoded following the parent. + The first int must always be TY. + + key: TY = type code, FL = flags, BS = block size, NR = num runs, + NL = name len, ML = misc len, NC = num children, + IL = interleave (bytes), SIZE = Size of storage (blocks), + LEN = run length (blocks), OFFS = run offset (blocks), + + The NR * (OFFS, LEN) offsets for some of the types is the set of block + ranges in the underlying address space that, concatenated, make up the + contents of the storage -- for instance, doing file_get_storage_info on a + file may return storage of type STORAGE_DEVICE, and the accompanying block + ranges are the set of blocks on the given device that correspond to that + file. Any OFFS == -1 designates a hole in the address range. Note that + the total size (SIZE) for these types is the sum of their LEN's. + + The optional NAME returned by some types (if NL != 0) is a type specific + name for the same object referenced by the port also returned. E.g.: + device -- The mach device name + file -- The file name (unreliable, as the root may not be the same) + task -- The pid + Unless it is MACH_PORT_NULL, the port should generally be used instead of + trying to regenerate it from the associated name, which is intended more for + printing messages, etc. */ +enum file_storage_class +{ + STORAGE_OTHER, + STORAGE_DEVICE, + STORAGE_HURD_FILE, + STORAGE_NETWORK, + STORAGE_MEMORY, + STORAGE_TASK, + STORAGE_ZERO, + STORAGE_CONCAT, + STORAGE_INTERLEAVE, + STORAGE_LAYER, + STORAGE_REMAP, + STORAGE_COPY, +}; + +/* Flags for the flags word returned by some types . */ +#define STORAGE_MUTATED 0x00000001 /* data as stored is munged from file */ + +/* Data types */ + +#include +#include +#ifndef THREAD_SCHED_INFO +#include +#endif + +/* Flags sent in proc_getprocinfo request. */ +#define PI_FETCH_TASKINFO 0x0001 +#define PI_FETCH_TASKEVENTS 0x0020 +#define PI_FETCH_THREADS 0x0002 +#define PI_FETCH_THREAD_BASIC 0x0004 +#define PI_FETCH_THREAD_SCHED 0x0008 +#define PI_FETCH_THREAD_WAITS 0x0010 + +struct procinfo +{ + int state; + uid_t owner; + pid_t ppid; + pid_t pgrp; + pid_t session; + pid_t logincollection; + int exitstatus; + int sigcode; + + int nthreads; /* size of pi_threadinfos */ + + struct task_basic_info taskinfo; + struct task_events_info taskevents; +#ifdef TASK_SCHED_TIMESHARE_INFO + struct policy_timeshare_base timeshare_base_info; +#endif + struct + { + int died; /* this thread died in the middle of call */ + mach_msg_id_t rpc_block; /* thread is blocked on this RPC */ + struct thread_basic_info pis_bi; +#ifdef THREAD_SCHED_INFO + struct thread_sched_info pis_si; +#else + struct policy_infos pis_pi; +#endif + } threadinfos[0]; +}; +typedef int *procinfo_t; +typedef const int *const_procinfo_t; + +/* Bits in struct procinfo state: */ +#define PI_STOPPED 0x00000001 /* Proc server thinks is stopped. */ +#define PI_EXECED 0x00000002 /* Has called proc_exec. */ +#define PI_WAITING 0x00000004 /* Process is waiting for child to exit */ +#define PI_ORPHAN 0x00000008 /* Process group is orphaned. */ +#define PI_NOMSG 0x00000010 /* Process has no message port. */ +#define PI_SESSLD 0x00000020 /* Session leader. */ +#define PI_NOTOWNED 0x0000040 /* Process has no owner. */ +#define PI_NOPARENT 0x0000080 /* Hasn't identified a parent. */ +#define PI_ZOMBIE 0x00000100 /* Has no associated task. */ +#define PI_TRACED 0x00000200 /* Process is being traced */ +#define PI_GETMSG 0x00000400 /* Process is blocked in proc_getmsgport. */ +#define PI_LOGINLD 0x00000800 /* Process is leader of login collection */ + + +/* Conventions */ + + +/* st_fstype in struct stat and fsys_stb_type in fsys_statfsbuf is one of: */ +#define FSTYPE_UFS 0x00000000 /* 4.x BSD Fast File System */ +#define FSTYPE_NFS 0x00000001 /* Network File System ala Sun */ +#define FSTYPE_GFS 0x00000002 /* GNU file system */ +#define FSTYPE_LFS 0x00000003 /* Logging File System ala Sprite */ +#define FSTYPE_SYSV 0x00000004 /* Old U*x filesystem ala System V */ +#define FSTYPE_FTP 0x00000005 /* Transparent FTP */ +#define FSTYPE_TAR 0x00000006 /* Transparent TAR */ +#define FSTYPE_AR 0x00000007 /* Transparent AR */ +#define FSTYPE_CPIO 0x00000008 /* Transparent CPIO */ +#define FSTYPE_MSLOSS 0x00000009 /* MS-DOS */ +#define FSTYPE_CPM 0x0000000a /* CP/M */ +#define FSTYPE_HFS 0x0000000b /* Don't ask */ +#define FSTYPE_DTFS 0x0000000c /* used by desktop to provide more info */ +#define FSTYPE_GRFS 0x0000000d /* GNU Remote File System */ +#define FSTYPE_TERM 0x0000000e /* GNU Terminal driver */ +#define FSTYPE_DEV 0x0000000f /* GNU Special file server */ +#define FSTYPE_PROC 0x00000010 /* /proc filesystem ala Version 9 */ +#define FSTYPE_IFSOCK 0x00000011 /* PF_LOCAL socket naming point */ +#define FSTYPE_AFS 0x00000012 /* Andrew File System 3.xx */ +#define FSTYPE_DFS 0x00000013 /* Distributed File Sys (OSF) == AFS 4.xx */ +#define FSTYPE_PROC9 0x00000014 /* /proc filesystem ala Plan 9 */ +#define FSTYPE_SOCKET 0x00000015 /* io_t that isn't a file but a socket */ +#define FSTYPE_MISC 0x00000016 /* generic trivfs server */ +#define FSTYPE_EXT2FS 0x00000017 /* Linux filesystem by Remy Card */ +#define FSTYPE_HTTP 0x00000018 /* Transparent HTTP */ +#define FSTYPE_MEMFS 0x00000019 /* In-core filesystem */ +#define FSTYPE_ISO9660 0x0000001a /* ISO9660 */ + +/* Standard port assignments for file_exec_paths and exec_* */ +enum + { + INIT_PORT_CWDIR, + INIT_PORT_CRDIR, + INIT_PORT_AUTH, + INIT_PORT_PROC, + INIT_PORT_CTTYID, + /* If MACH_PORT_NULL is given for the bootstrap port, + the bootstrap port of the old task is used. */ + INIT_PORT_BOOTSTRAP, + INIT_PORT_MAX + }; + +/* Standard ints for file_exec_paths and exec_* */ +enum + { + INIT_UMASK, + INIT_SIGMASK, + INIT_SIGIGN, + INIT_SIGPENDING, + INIT_TRACEMASK, + INIT_INT_MAX, + }; + +#endif // _HURD_TYPES_H diff --git a/include/gnu/hurd.h b/include/gnu/hurd.h new file mode 100644 index 00000000..1ed66790 --- /dev/null +++ b/include/gnu/hurd.h @@ -0,0 +1,51 @@ +/* + * GNU Mes --- Maxwell Equations of Software + * 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 . + */ + +#ifndef __MES_GNU_HURD_H +#define __MES_GNU_HURD_H + +#define _GNU_SOURCE 1 +#define __USE_GNU 1 + +#include +#include +#include + +struct hurd_startup_data + { + int flags; + mach_port_t *dtable; + mach_msg_type_number_t dtablesize; + mach_port_t *portarray; + mach_msg_type_number_t portarraysize; + int *intarray; + mach_msg_type_number_t intarraysize; + vm_address_t stack_base; + vm_size_t stack_size; + vm_address_t phdr; + vm_size_t phdrsz; + vm_address_t user_entry; + }; + +extern mach_port_t *_hurd_init_dtable; +extern mach_msg_type_number_t _hurd_init_dtablesize; +extern struct hurd_startup_data _hurd_startup_data; + +#endif // __MES_GNU_HURD_H diff --git a/include/gnu/syscall.h b/include/gnu/syscall.h new file mode 100644 index 00000000..7365ed0a --- /dev/null +++ b/include/gnu/syscall.h @@ -0,0 +1,115 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * 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 . + */ + +#ifndef __MES_GNU_SYSCALL_H +#define __MES_GNU_SYSCALL_H + +#define _GNU_SOURCE 1 +#define __USE_GNU 1 + +#include +#include +#include +#include +#include + +// mach/mach.defs +enum + { + SYS__task_terminate = 2008, + SYS__vm_statistics = 2030, + SYS__task_get_special_port = 2058, + }; + +// hurd/process.defs +enum + { + SYS__proc_mark_exit = 24025, + }; + +// hurd/startup.defs +enum + { + SYS__exec_startup_get_info = 30500, + }; + +extern mach_msg_type_t mach_msg_type_int32; + +struct mach_msg +{ + mach_msg_header_t header; +}; + +struct mach_msg_1 +{ + mach_msg_header_t header; + mach_msg_type_t type_one; int one; +}; + +struct mach_msg_2 +{ + mach_msg_header_t header; + mach_msg_type_t type_one; int one; + mach_msg_type_t type_two; int two; +}; + +struct mach_msg_startup_info +{ + mach_msg_header_t header; + mach_msg_type_t RetCodeType; + kern_return_t RetCode; + mach_msg_type_t user_entryType; + vm_address_t user_entry; + mach_msg_type_t phdrType; + vm_address_t phdr; + mach_msg_type_t phdr_sizeType; + vm_size_t phdr_size; + mach_msg_type_t stack_baseType; + vm_address_t stack_base; + mach_msg_type_t stack_sizeType; + vm_size_t stack_size; + mach_msg_type_t flagsType; + int flags; + mach_msg_type_long_t argvType; + char *argv; + mach_msg_type_long_t envpType; + char *envp; + mach_msg_type_long_t dtableType; + mach_port_t *dtable; + mach_msg_type_long_t portarrayType; + mach_port_t *portarray; + mach_msg_type_long_t intarrayType; + int *intarray; +}; + +kern_return_t __syscall (mach_port_t port, int sys_call); +kern_return_t __syscall2 (mach_port_t port, int sys_call, int one, int two); +kern_return_t __syscall_get (mach_port_t port, int sys_call, mach_msg_header_t *message, size_t size); + +// mach.defs +kern_return_t __task_terminate (mach_port_t task); +kern_return_t __task_get_special_port (mach_port_t task, int which, mach_port_t *port); +kern_return_t __vm_statistics (mach_port_t task, vm_statistics_data_t *vm_stats); + +// process.defs +kern_return_t __proc_mark_exit (mach_port_t process, int one, int two); +kern_return_t __exec_startup_get_data (mach_port_t bootstrap, struct hurd_startup_data *data); + +#endif // __MES_GNU_SYSCALL_H diff --git a/include/mach/mach-init.h b/include/mach/mach-init.h new file mode 100644 index 00000000..3cced775 --- /dev/null +++ b/include/mach/mach-init.h @@ -0,0 +1,52 @@ +/* Declarations and macros for the basic Mach things set at startup. + Copyright (C) 1993-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _MACH_INIT_H + +#define _MACH_INIT_H 1 + +#include + +/* Return the current task's task port. */ +extern mach_port_t __mach_task_self (void); +extern mach_port_t mach_task_self (void); + +/* This cache is initialized at startup. */ +extern mach_port_t __mach_task_self_; +#define __mach_task_self() (__mach_task_self_ + 0) /* Not an lvalue. */ +#define mach_task_self() (__mach_task_self ()) + +/* This cache is initialized at startup. */ +extern mach_port_t __mach_host_self_; +#define __mach_host_self() (__mach_host_self_ + 0) /* Not an lvalue. */ +#define mach_host_self() (__mach_host_self ()) + +/* Kernel page size. */ +extern vm_size_t __vm_page_size; +extern vm_size_t vm_page_size; + +/* Round the address X up to a page boundary. */ +#define round_page(x) \ + ((((vm_offset_t) (x) + __vm_page_size - 1) / __vm_page_size) * \ + __vm_page_size) + +/* Truncate the address X down to a page boundary. */ +#define trunc_page(x) \ + ((((vm_offset_t) (x)) / __vm_page_size) * __vm_page_size) + +#endif /* mach_init.h */ diff --git a/include/sys/wait.h b/include/sys/wait.h index 37d58a96..4cff86fc 100644 --- a/include/sys/wait.h +++ b/include/sys/wait.h @@ -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. * @@ -31,6 +31,7 @@ typedef int pid_t; #endif #define WNOHANG 1 +#define W_EXITCODE(status, signal) ((status) << 8 | (signal)) pid_t waitpid (pid_t pid, int *status_ptr, int options); pid_t wait (int *status_ptr); diff --git a/lib/gnu/_exit.c b/lib/gnu/_exit.c new file mode 100644 index 00000000..bca85d5c --- /dev/null +++ b/lib/gnu/_exit.c @@ -0,0 +1,38 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * 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 . + */ + +/** Commentary: + Inspired by implementation in GNU C Library: + _hurd_exit + Copyright (C) 1993-2016 Free Software Foundation, Inc. + */ + +#include +#include +#include +#include + +void +_exit (int status) +{ + __proc_mark_exit (_hurd_startup_data.portarray[INIT_PORT_PROC], status, 0); + __task_terminate (__mach_task_self ()); + while (1) {* (int *) 0 = 0;} +} diff --git a/lib/gnu/exec-startup-get-data.c b/lib/gnu/exec-startup-get-data.c new file mode 100644 index 00000000..0a065601 --- /dev/null +++ b/lib/gnu/exec-startup-get-data.c @@ -0,0 +1,57 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * 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 . + */ + +#include + +static void +mach_startup_info2hurd_startup_data (struct mach_msg_startup_info *info, + struct hurd_startup_data *data) +{ + data->flags = info->flags; + data->dtable = info->dtable; + data->dtablesize = info->dtableType.msgtl_number; + data->portarray = info->portarray; + data->portarraysize = info->portarrayType.msgtl_number; + data->intarray = info->intarray; + data->intarraysize = info->intarrayType.msgtl_number; + data->stack_base = info->stack_base; + data->stack_size = info->stack_size; + data->phdr = info->phdr; + data->phdrsz = info->phdr_size; + data->user_entry = info->user_entry; +} + +kern_return_t +__exec_startup_get_data (mach_port_t bootstrap, struct hurd_startup_data *data) +{ + union message + { + mach_msg_header_t header; + struct mach_msg_startup_info info; + }; + union message message; + message.header.msgh_size = sizeof (struct mach_msg); + kern_return_t result = __syscall_get (bootstrap, SYS__exec_startup_get_info, + &message.header, sizeof (message)); + + + mach_startup_info2hurd_startup_data (&message.info, data); + return result; +} diff --git a/lib/gnu/hurd-start.c b/lib/gnu/hurd-start.c new file mode 100644 index 00000000..fea1eb6c --- /dev/null +++ b/lib/gnu/hurd-start.c @@ -0,0 +1,47 @@ +/* -*-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 . + */ + +/** Commentary: + Inspired by implementation in GNU C Library: + Initialization code run first thing by the ELF startup code. For i386/Hurd. + Copyright (C) 1995-2016 Free Software Foundation, Inc. + */ + +#include +#include + +#include +#include +#include +#include + +struct hurd_startup_data _hurd_startup_data; + +void __mach_init (void); + +void +_hurd_start () +{ + mach_port_t bootstrap; + __mach_init (); + __task_get_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT, + &bootstrap); + __exec_startup_get_data (bootstrap, &_hurd_startup_data); +} diff --git a/lib/gnu/proc-mark-exit.c b/lib/gnu/proc-mark-exit.c new file mode 100644 index 00000000..da3d7ac1 --- /dev/null +++ b/lib/gnu/proc-mark-exit.c @@ -0,0 +1,28 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * 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 . + */ + +#include +#include + +kern_return_t +__proc_mark_exit (mach_port_t process, int status, int signal) +{ + return __syscall2 (process, SYS__proc_mark_exit, W_EXITCODE (status, 0), signal); +} diff --git a/lib/gnu/syscall.c b/lib/gnu/syscall.c new file mode 100644 index 00000000..01052986 --- /dev/null +++ b/lib/gnu/syscall.c @@ -0,0 +1,99 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * 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 . + */ + +#include + +#include + +mach_msg_type_t mach_msg_type_int32 = + { + .msgt_name = (unsigned char) MACH_MSG_TYPE_INTEGER_32, // msgt_name + .msgt_size = 32, // msgt_size + .msgt_number = 1, // msgt_number + .msgt_inline = 1, // msgt_inline + .msgt_longform = 0, // msgt_longform + .msgt_deallocate = 0, // msgt_deallocate + .msgt_unused = 0 // msgt_unused + }; + +kern_return_t +__syscall (mach_port_t port, int sys_call) +{ + struct mach_msg message = + { + { + MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE), + 0, + port, + {__mach_reply_port (),}, + 0, + sys_call, + } + }; + return __mach_msg (&message.header, + MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, + sizeof (message), + sizeof (message), + message.header.msgh_local_port, + MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL); +} + +kern_return_t +__syscall2 (mach_port_t port, int sys_call, int one, int two) +{ + struct mach_msg_2 message = + { + { + MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE), + 0, + port, + {__mach_reply_port (),}, + 0, + sys_call, + }, + mach_msg_type_int32, one, + mach_msg_type_int32, two, + }; + return __mach_msg (&message.header, + MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, + sizeof (message), + sizeof (message), + message.header.msgh_local_port, + MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL); +} + +kern_return_t +__syscall_get (mach_port_t port, int sys_call, mach_msg_header_t *message, size_t size) +{ + message->msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); + message->msgh_remote_port = port; + message->msgh_local_port = __mach_reply_port (); + message->msgh_seqno = 0; + message->msgh_id = sys_call; + return __mach_msg (message, + MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, + message->msgh_size, + size, + message->msgh_local_port, + MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL); +} diff --git a/lib/gnu/task-get-special-port.c b/lib/gnu/task-get-special-port.c new file mode 100644 index 00000000..487dfc22 --- /dev/null +++ b/lib/gnu/task-get-special-port.c @@ -0,0 +1,37 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * 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 . + */ + +#include + +kern_return_t +__task_get_special_port (mach_port_t task, int which, mach_port_t *port) +{ + struct mach_msg_2 message = {0}; + message.header.msgh_size = sizeof (struct mach_msg_1); + message.type_one = mach_msg_type_int32; + message.one = which; + message.type_two = mach_msg_type_int32; + message.two = 0; + kern_return_t result = __syscall_get (task, SYS__task_get_special_port, + &message.header, sizeof (message)); + if (result == KERN_SUCCESS) + *port = message.two; + return result; +} diff --git a/lib/gnu/task-terminate.c b/lib/gnu/task-terminate.c new file mode 100644 index 00000000..bc30c236 --- /dev/null +++ b/lib/gnu/task-terminate.c @@ -0,0 +1,27 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * 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 . + */ + +#include + +kern_return_t +__task_terminate (mach_port_t task) +{ + return __syscall (task, SYS__task_terminate); +} diff --git a/lib/gnu/vm-statistics.c b/lib/gnu/vm-statistics.c new file mode 100644 index 00000000..1c164fe4 --- /dev/null +++ b/lib/gnu/vm-statistics.c @@ -0,0 +1,41 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * 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 . + */ + +#include + +struct mach_msg_int32_vm_statistics_data +{ + mach_msg_header_t header; + mach_msg_type_t type_one; int one; + mach_msg_type_t type_two; vm_statistics_data_t two; +}; + +kern_return_t +__vm_statistics (mach_port_t task, vm_statistics_data_t *vm_stats) +{ + struct mach_msg_int32_vm_statistics_data message = {0}; + message.header.msgh_size = sizeof (struct mach_msg); + message.type_one = mach_msg_type_int32; + message.type_two = mach_msg_type_int32; + kern_return_t result = __syscall_get (task, SYS__vm_statistics, + &message.header, sizeof (message)); + *vm_stats = message.two; + return result; +} diff --git a/lib/gnu/x86-mes-gcc/crt1.c b/lib/gnu/x86-mes-gcc/crt1.c new file mode 100644 index 00000000..0485c64a --- /dev/null +++ b/lib/gnu/x86-mes-gcc/crt1.c @@ -0,0 +1,43 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018,2019 Jan (janneke) 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 . + */ + +#if 0 +#include +#else // FIXME +#define __MES_LIB_MINI_H 1 + +char **environ; +int __stdin; +int __stdout; +int __stderr; +#endif + +void _hurd_start (void); +void _posix_start (void); + +void +_start () +{ + _hurd_start (); + _posix_start (); +} + +#define _start _posix_start +#include diff --git a/lib/gnu/x86-mes-gcc/mini.c b/lib/gnu/x86-mes-gcc/mini.c new file mode 100644 index 00000000..a0c42d88 --- /dev/null +++ b/lib/gnu/x86-mes-gcc/mini.c @@ -0,0 +1,23 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * 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 . + */ + +#include "mes/lib-mini.h" + +// your mini mach here diff --git a/lib/mach/mach-init.c b/lib/mach/mach-init.c new file mode 100644 index 00000000..53e73f0a --- /dev/null +++ b/lib/mach/mach-init.c @@ -0,0 +1,52 @@ +/* Copyright (C) 1992-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#define _GNU_SOURCE 1 +#define __USE_GNU 1 + +#include +#include +//#include +#include + +mach_port_t __mach_task_self_; +mach_port_t __mach_host_self_; +vm_size_t __vm_page_size = 0; + +void +__mach_init (void) +{ + kern_return_t err; + + __mach_task_self_ = (__mach_task_self) (); + __mach_host_self_ = (__mach_host_self) (); +#if 0 + __mig_init (0); +#endif + +#ifdef HAVE_HOST_PAGE_SIZE + if (err = __host_page_size (__mach_host_self (), &__vm_page_size)) + _exit (err); +#else + { + vm_statistics_data_t stats; + if (err = __vm_statistics (__mach_task_self (), &stats)) + _exit (err); + __vm_page_size = stats.pagesize; + } +#endif +} diff --git a/lib/mach/mach_host_self.S b/lib/mach/mach_host_self.S new file mode 100644 index 00000000..f70792c0 --- /dev/null +++ b/lib/mach/mach_host_self.S @@ -0,0 +1,3 @@ +#include +kernel_trap (__mach_host_self,-29,0) +// weak_alias (__mach_host_self, mach_host_self) diff --git a/lib/mach/mach_msg_trap.S b/lib/mach/mach_msg_trap.S new file mode 100644 index 00000000..d440c05f --- /dev/null +++ b/lib/mach/mach_msg_trap.S @@ -0,0 +1,3 @@ +#include +kernel_trap (__mach_msg_trap,-25,7) +// weak_alias (__mach_msg_trap, mach_msg_trap) diff --git a/lib/mach/mach_reply_port.S b/lib/mach/mach_reply_port.S new file mode 100644 index 00000000..9a27b196 --- /dev/null +++ b/lib/mach/mach_reply_port.S @@ -0,0 +1,3 @@ +#include +kernel_trap (__mach_reply_port,-26,0) +// weak_alias (__mach_reply_port, mach_reply_port) diff --git a/lib/mach/mach_task_self.S b/lib/mach/mach_task_self.S new file mode 100644 index 00000000..6ce20529 --- /dev/null +++ b/lib/mach/mach_task_self.S @@ -0,0 +1,3 @@ +#include +kernel_trap (__mach_task_self,-28,0) +// weak_alias (__mach_task_self, mach_task_self) diff --git a/lib/mach/mach_thread_self.S b/lib/mach/mach_thread_self.S new file mode 100644 index 00000000..75a8097b --- /dev/null +++ b/lib/mach/mach_thread_self.S @@ -0,0 +1,19 @@ +#if 1 +#include +kernel_trap (__mach_thread_self,-27,0) +// weak_alias (__mach_thread_self, mach_thread_self) +#else + .globl __mach_thread_self + .type __mach_thread_self,@function + .align 1<<4 +__mach_thread_self: .cfi_startproc + movl $ -27,%eax + .byte 0x9a + .long 0 + .word 0x7 + ret + .cfi_endproc + .size __mach_thread_self,.-__mach_thread_self + .weak mach_thread_self + mach_thread_self = __mach_thread_self +#endif diff --git a/lib/mach/msg.c b/lib/mach/msg.c new file mode 100644 index 00000000..79b19ed7 --- /dev/null +++ b/lib/mach/msg.c @@ -0,0 +1,145 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989, 1995 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +#include +#include + +#ifdef MACH_MSG_OVERWRITE +/* In variants with this feature, the actual system call is + __mach_msg_overwrite_trap. */ +mach_msg_return_t +__mach_msg_trap (mach_msg_header_t *msg, + mach_msg_option_t option, + mach_msg_size_t send_size, + mach_msg_size_t rcv_size, + mach_port_t rcv_name, + mach_msg_timeout_t timeout, + mach_port_t notify) +{ + return __mach_msg_overwrite_trap (msg, option, send_size, + rcv_size, rcv_name, timeout, notify, + MACH_MSG_NULL, 0); +} +weak_alias (__mach_msg_trap, mach_msg_trap) + +/* See comments below in __mach_msg. */ +mach_msg_return_t +__mach_msg_overwrite (mach_msg_header_t *msg, + mach_msg_option_t option, + mach_msg_size_t send_size, + mach_msg_size_t rcv_size, + mach_port_t rcv_name, + mach_msg_timeout_t timeout, + mach_port_t notify, + mach_msg_header_t *rcv_msg, + mach_msg_size_t rcv_msg_size) + +{ + mach_msg_return_t ret; + + /* Consider the following cases: + 1. Errors in pseudo-receive (eg, MACH_SEND_INTERRUPTED + plus special bits). + 2. Use of MACH_SEND_INTERRUPT/MACH_RCV_INTERRUPT options. + 3. RPC calls with interruptions in one/both halves. + */ + + ret = __mach_msg_overwrite_trap (msg, option, send_size, + rcv_size, rcv_name, timeout, notify, + rcv_msg, rcv_msg_size); + if (ret == MACH_MSG_SUCCESS) + return MACH_MSG_SUCCESS; + + if (!(option & MACH_SEND_INTERRUPT)) + while (ret == MACH_SEND_INTERRUPTED) + ret = __mach_msg_overwrite_trap (msg, option, send_size, + rcv_size, rcv_name, timeout, notify, + rcv_msg, rcv_msg_size); + + if (!(option & MACH_RCV_INTERRUPT)) + while (ret == MACH_RCV_INTERRUPTED) + ret = __mach_msg_overwrite_trap (msg, option & ~MACH_SEND_MSG, + 0, rcv_size, rcv_name, timeout, notify, + rcv_msg, rcv_msg_size); + + return ret; +} +weak_alias (__mach_msg_overwrite, mach_msg_overwrite) +#endif + +mach_msg_return_t +__mach_msg (mach_msg_header_t *msg, + mach_msg_option_t option, + mach_msg_size_t send_size, + mach_msg_size_t rcv_size, + mach_port_t rcv_name, + mach_msg_timeout_t timeout, + mach_port_t notify) +{ + mach_msg_return_t ret; + + /* Consider the following cases: + 1. Errors in pseudo-receive (eg, MACH_SEND_INTERRUPTED + plus special bits). + 2. Use of MACH_SEND_INTERRUPT/MACH_RCV_INTERRUPT options. + 3. RPC calls with interruptions in one/both halves. + */ + + ret = __mach_msg_trap (msg, option, send_size, + rcv_size, rcv_name, timeout, notify); + if (ret == MACH_MSG_SUCCESS) + return MACH_MSG_SUCCESS; + + if (!(option & MACH_SEND_INTERRUPT)) + while (ret == MACH_SEND_INTERRUPTED) + ret = __mach_msg_trap (msg, option, send_size, + rcv_size, rcv_name, timeout, notify); + + if (!(option & MACH_RCV_INTERRUPT)) + while (ret == MACH_RCV_INTERRUPTED) + ret = __mach_msg_trap (msg, option & ~MACH_SEND_MSG, + 0, rcv_size, rcv_name, timeout, notify); + + return ret; +} +// weak_alias (__mach_msg, mach_msg) + +mach_msg_return_t +__mach_msg_send (mach_msg_header_t *msg) +{ + return __mach_msg (msg, MACH_SEND_MSG, + msg->msgh_size, 0, MACH_PORT_NULL, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); +} +// weak_alias (__mach_msg_send, mach_msg_send) + +mach_msg_return_t +__mach_msg_receive (mach_msg_header_t *msg) +{ + return __mach_msg (msg, MACH_RCV_MSG, + 0, msg->msgh_size, msg->msgh_local_port, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); +} +// weak_alias (__mach_msg_receive, mach_msg_receive) diff --git a/lib/tests/scaffold/00-exit-0.c b/lib/tests/scaffold/30-exit-0.c similarity index 51% rename from lib/tests/scaffold/00-exit-0.c rename to lib/tests/scaffold/30-exit-0.c index 6684ae47..3f6fff10 100644 --- a/lib/tests/scaffold/00-exit-0.c +++ b/lib/tests/scaffold/30-exit-0.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. * @@ -21,37 +21,6 @@ int main () { -#if __i386__ - -#if __MESC__ - asm ("mov____$i32,%ebx %0"); - asm ("mov____$i32,%eax SYS_exit"); - asm ("int____$0x80"); -#elif __TINYC__ - asm ("mov $0,%ebx"); - asm ("mov $1,%eax"); - asm ("int $128"); -#else // !__TINYC__ - asm ("mov $0,%ebx"); - asm ("mov $1,%eax"); - asm ("int $0x80"); -#endif // !__TINYC__ - -#elif __x86_64__ - -#if __MESC__ - asm ("mov____$i32,%rdi %0"); - asm ("mov____$i32,%rax SYS_exit"); - asm ("syscall"); -#elif __TINYC__ - asm ("mov $0,%rdi"); - asm ("mov $0x3c,%rax"); - asm ("syscall"); -#else // !__TINYC__ - asm ("mov $0,%rdi"); - asm ("mov $60,%rax"); - asm ("syscall"); -#endif // !__TINYC__ - -#endif // ! __x86_64__ + _exit (0); + return 1; } diff --git a/lib/tests/scaffold/30-exit-42.c b/lib/tests/scaffold/30-exit-42.c new file mode 100644 index 00000000..3fffab20 --- /dev/null +++ b/lib/tests/scaffold/30-exit-42.c @@ -0,0 +1,26 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * 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 . + */ + +int +main () +{ + _exit (42); + return 0; +} diff --git a/lib/tests/scaffold/30-exit-42.exit b/lib/tests/scaffold/30-exit-42.exit new file mode 100644 index 00000000..d81cc071 --- /dev/null +++ b/lib/tests/scaffold/30-exit-42.exit @@ -0,0 +1 @@ +42