diff --git a/CMakeLists.txt b/CMakeLists.txt index e540d7b..0e043f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,7 +213,6 @@ if(NEWLIB) -DLLVM_INCLUDE_TESTS=OFF -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON -DCOMPILER_RT_BUILD_BUILTINS=ON - -DCOMPILER_RT_BAREMETAL_BUILD=ON -DCOMPILER_RT_BUILD_XRAY=OFF -DCOMPILER_RT_BUILD_LIBFUZZER=OFF -DCOMPILER_RT_BUILD_MEMPROF=OFF diff --git a/file_system/file_system.c b/file_system/file_system.c index 484ba8c..8a11607 100644 --- a/file_system/file_system.c +++ b/file_system/file_system.c @@ -51,8 +51,7 @@ D_File *create_directory(Path *name, uint32_t mode) { new_file->type = DIRECTORY; new_file->child = NULL; new_file->hard_links = 0; - // directory where user has full permissions - new_file->mode = S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR; + new_file->mode = mode | S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR; return new_file; } @@ -61,6 +60,13 @@ int link_file_to_folder(D_File *folder, D_File *file) { // TODO set proper error number return -1; }; + + // Check if file already exists in this directory to prevent duplicates + D_File *existing = find_file_in_dir(folder, (Path){.path = file->name, .length = namelen(file->name, FS_NAME_LENGTH)}); + if (existing != NULL) { + return -1; + } + // set file parent to folder file->parent = folder; // increase the number of hard links to the file @@ -70,18 +76,24 @@ int link_file_to_folder(D_File *folder, D_File *file) { file->next = NULL; } else { D_File *current = folder->child; - if (namecmp(file->name, FS_NAME_LENGTH, current->name, FS_NAME_LENGTH) < - 0) { + int cmp_first = namecmp(file->name, FS_NAME_LENGTH, current->name, FS_NAME_LENGTH); + if (cmp_first < 0) { file->next = current; folder->child = file; + } else if (cmp_first == 0) { + file->hard_links -= 1; + return -1; } else { + // Find correct position to insert while (current->next != NULL) { - if (namecmp(file->name, FS_NAME_LENGTH, current->next->name, - FS_NAME_LENGTH) < 0) { + int cmp_next = namecmp(file->name, FS_NAME_LENGTH, current->next->name, FS_NAME_LENGTH); + if (cmp_next < 0) { break; - } else { - current = current->next; + } else if (cmp_next == 0) { + file->hard_links -= 1; + return -1; } + current = current->next; } file->next = current->next; current->next = file; @@ -163,11 +175,12 @@ D_File *create_directories(D_File *directory, Path path, char prevent_up) { directory = candidate_dir; continue; } - D_File *new_dir = dandelion_alloc(sizeof(D_File), _Alignof(D_File)); - new_dir->type = DIRECTORY; - memcpy(new_dir->name, current_path.path, current_path.length); - new_dir->name[current_path.length] = '\0'; - new_dir->child = NULL; + uint32_t dir_mode = S_IRUSR | S_IWUSR | S_IXUSR; + D_File *new_dir = create_directory(¤t_path, dir_mode); + if (new_dir == NULL) { + return NULL; + } + int error = link_file_to_folder(directory, new_dir); if (error < 0) { dandelion_free(new_dir); @@ -416,9 +429,12 @@ int fs_initialize(int *argc, char ***argv, char ***environ) { fs_root->parent = NULL; fs_root->child = NULL; fs_root->hard_links = 1; + // Set proper root directory mode + //fs_root->mode = S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR; // create stdio folder and stdout/stderr file - D_File *stdio_folder = dandelion_alloc(sizeof(D_File), _Alignof(D_File)); + Path stdio_path = path_from_string("stdio"); + D_File *stdio_folder = create_directory(&stdio_path, S_IRUSR | S_IWUSR | S_IXUSR); if (stdio_folder == NULL) { dandelion_exit(ENOMEM); return -1; diff --git a/libc_extension/CMakeLists.txt b/libc_extension/CMakeLists.txt index 89b8e8f..cd5701d 100644 --- a/libc_extension/CMakeLists.txt +++ b/libc_extension/CMakeLists.txt @@ -12,6 +12,7 @@ target_sources(${LIBC_EXTENSION} include/netdb.h include/sys/cpuset.h include/sys/dirent.h + include/sys/mman.h include/sys/sched.h include/sys/socket.h include/sys/statvfs.h diff --git a/libc_extension/dirent.c b/libc_extension/dirent.c index f795cdf..c23212e 100644 --- a/libc_extension/dirent.c +++ b/libc_extension/dirent.c @@ -51,3 +51,6 @@ long int telldir(DIR *dir) { extern void dandelion_seekdir(DIR *dir, long int index); void seekdir(DIR *dir, long int index) { return dandelion_seekdir(dir, index); } +int dirfd(DIR *dirp) { + return -1; +} diff --git a/libc_extension/include/sys/mman.h b/libc_extension/include/sys/mman.h new file mode 100644 index 0000000..535e7eb --- /dev/null +++ b/libc_extension/include/sys/mman.h @@ -0,0 +1,64 @@ +/* sys/mman.h + +Copyright 1996, 1997, 1998, 2000, 2001 Red Hat, Inc. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#ifndef _SYS_MMAN_H_ +#define _SYS_MMAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include + +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 + +#define MAP_FILE 0 +#define MAP_SHARED 1 +#define MAP_PRIVATE 2 +#define MAP_TYPE 0xF +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS + /* Non-standard flag */ +#if 0 /* Not yet implemented */ +#define MAP_NORESERVE 0x4000 /* Don't reserve swap space for this mapping. +Page protection must be set explicitely +to access page. */ +#endif +#define MAP_AUTOGROW 0x8000 /* Grow underlying object to mapping size. +File must be opened for writing. */ + +#define MAP_FAILED ((void *)-1) + + /* + * Flags for msync. + */ +#define MS_ASYNC 1 +#define MS_SYNC 2 +#define MS_INVALIDATE 4 + +#ifndef __INSIDE_CYGWIN__ + extern void *mmap (void *__addr, size_t __len, int __prot, int __flags, int __fd, off_t __off); +#endif + extern int munmap (void *__addr, size_t __len); + extern int mprotect (void *__addr, size_t __len, int __prot); + extern int msync (void *__addr, size_t __len, int __flags); + extern int mlock (const void *__addr, size_t __len); + extern int munlock (const void *__addr, size_t __len); + +#ifdef __cplusplus +}; +#endif /* __cplusplus */ + +#endif /* _SYS_MMAN_H_ */ \ No newline at end of file diff --git a/newlib_shim/newlib-cygwin-3.5.3.patch b/newlib_shim/newlib-cygwin-3.5.3.patch index eebcbf6..90449af 100644 --- a/newlib_shim/newlib-cygwin-3.5.3.patch +++ b/newlib_shim/newlib-cygwin-3.5.3.patch @@ -159,3 +159,33 @@ index c99ad395d..109112630 100644 #endif /* defined(__rtems__) */ #endif /* __GNU_VISIBLE */ +diff --git a/newlib/libc/include/limits.h a/newlib/libc/include/limits.h +index 893f108..f07076d 100644 +--- a/newlib/libc/include/limits.h ++++ b/newlib/libc/include/limits.h +@@ -145,3 +145,7 @@ + #ifndef PATH_MAX + #define PATH_MAX 4096 + #endif ++ ++#ifndef SSIZE_MAX ++#define SSIZE_MAX LONG_MAX ++#endif ++ +diff --git a/newlib/libc/include/sys/time.h b/newlib/libc/include/sys/time.h +index 5a3dec7ab..980f3378d 100644 +--- a/newlib/libc/include/sys/time.h ++++ b/newlib/libc/include/sys/time.h +@@ -440,6 +440,9 @@ int futimesat (int, const char *, const struct timeval [2]); + int _gettimeofday (struct timeval *__p, void *__tz); + #endif + ++time_t time(time_t *tloc); ++int utime(const char *filename, const struct utimbuf *times); ++ + __END_DECLS + + #endif /* !_KERNEL */ +-- +2.50.1 + diff --git a/newlib_shim/pthread.c b/newlib_shim/pthread.c index d9f5783..c76bb6f 100644 --- a/newlib_shim/pthread.c +++ b/newlib_shim/pthread.c @@ -86,20 +86,48 @@ int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) { return EINVAL; } int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr) { - return EAGAIN; + (void)attr; + *cond = _PTHREAD_COND_INITIALIZER; + return 0; +} + +int pthread_cond_destroy(pthread_cond_t *cond) { + pthread_cond_t current = *cond; + if ((current & DESTROYED) == 0) + return EINVAL; + *cond &= ~DESTROYED; + return 0; } -int pthread_cond_destroy(pthread_cond_t *cond) { return EINVAL; } + int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex) { - return ENOTRECOVERABLE; + if ((*cond & DESTROYED) == 0 || (*mutex & DESTROYED) == 0) + return EINVAL; + if ((*mutex & LOCKED) != 0) + return EPERM; + + int r = pthread_mutex_unlock(mutex); + if (r != 0) return r; + return pthread_mutex_lock(mutex); } + int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstim) { - return ENOTRECOVERABLE; + (void)abstim; + return pthread_cond_wait(cond, mutex); +} + +int pthread_cond_signal(pthread_cond_t *cond) { + return 0; } -int pthread_cond_signal(pthread_cond_t *cond) { return EINVAL; } -int pthread_cond_broadcast(pthread_cond_t *cond) { return EINVAL; } + +int pthread_cond_broadcast(pthread_cond_t *cond) { + if ((*cond & DESTROYED) == 0) + return EINVAL; + return 0; +} + int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) { if (once_control->init_executed == 0) { @@ -196,4 +224,23 @@ int pthread_key_delete(pthread_key_t key) { int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)) { return ENOMEM; +} + +int pthread_attr_init(pthread_attr_t *attr) { + return EINVAL; +} +int pthread_attr_destroy(pthread_attr_t *attr) { + return EINVAL; +} + +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) { + return EINVAL; +} +int pthread_attr_getstacksize(const pthread_attr_t *restrict attr, + size_t *restrict stacksize) { + return EINVAL; +} + +void pthread_exit(void *retval) { + return; } \ No newline at end of file diff --git a/newlib_shim/time.c b/newlib_shim/time.c index a278e54..c7ab289 100644 --- a/newlib_shim/time.c +++ b/newlib_shim/time.c @@ -6,6 +6,7 @@ #define _POSIX_MONOTONIC_CLOCK #include #include +#include #undef errno extern int errno; @@ -68,3 +69,13 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) { // always pretend to sleep for that amount return 0; } + +time_t time(time_t *t) { + errno = EINVAL; + return -1; +} + +int utime(const char *filename, const struct utimbuf *buf) { + errno = EINVAL; + return -1; +} \ No newline at end of file diff --git a/newlib_shim/unistd.c b/newlib_shim/unistd.c index afcc9e5..50e69f3 100644 --- a/newlib_shim/unistd.c +++ b/newlib_shim/unistd.c @@ -1,8 +1,9 @@ #include #include +#include // Implement functions from unistd that are not already defined in other parts -// of newlibs libc or in something we supply +// of newlibs libc Or in something we supply // unsigned alarm (unsigned __secs); int chdir(const char *__path) { @@ -68,7 +69,6 @@ int execv(const char *__path, char *const __argv[]) { // already given in newlib // int execve (const char *__path, char * const __argv[], char * const // __envp[]); - // int execvp (const char *__file, char * const __argv[]); // int execvpe (const char *__file, char * const __argv[], char * const // __envp[]); @@ -86,11 +86,15 @@ int execv(const char *__path, char *const __argv[]) { // int fexecve (int __fd, char * const __argv[], char * const __envp[]); // long fpathconf (int __fd, int __name); +// int execvpe (const char *__file, char * const __argv[], char * const +// __envp[]); + int fsync(int __fd) { return 0; } int fdatasync(int __fd) { return 0; } - // char * get_current_dir_name (void); -char *getcwd(char *__buf, size_t __size) { return "/"; } +char * getcwd (char *__buf, size_t __size) { + return (__buf && __size > 1) ? strcpy(__buf, "/") : 0; +} // int getdomainname (char *__name, size_t __len); // gid_t getegid (void); // uid_t geteuid (void); @@ -102,7 +106,9 @@ char *getcwd(char *__buf, size_t __size) { return "/"; } // int getlogin_r (char *name, size_t namesize) ; // #endif // char * getpass (const char *__prompt); -// int getpagesize (void); +int getpagesize (void) { + return 4096; // assuming a page size of 4096 bytes +} // pid_t getpgid (pid_t); // pid_t getpgrp (void); // pid_t getpid (void); // already implementedc @@ -113,21 +119,28 @@ char *getcwd(char *__buf, size_t __size) { return "/"; } // char * getwd (char *__buf); // int lchown (const char *__path, uid_t __owner, gid_t __group); // #if __ATFILE_VISIBLE -// int linkat (int __dirfd1, const char *__path1, int __dirfd2, const char -// *__path2, int __flags); +// int linkat (int __dirfd1, const char *__path1, int __dirfd2, const char *__path2, int __flags); +// #endif + +// #if __MISC_VISIBLE || __XSI_VISIBLE +// int nice (int __nice_value); +// #endif -// #endif #if __MISC_VISIBLE || __XSI_VISIBLE -// int nice(int __nice_value); -// #endif // #if __MISC_VISIBLE || __XSI_VISIBLE >= 4 -// int lockf(int __fd, int __cmd, off_t __len); -// #endif -// long pathconf (const char *__path, int __name); -// int pause (void); -// #if __POSIX_VISIBLE >= 199506 -// int pthread_atfork (void (*)(void), void (*)(void), void (*)(void)); -// #endif -// int pipe (int __fildes[2]) { +// int lockf (int __fd, int __cmd, off_t __len); +// #endif + +// long pathconf (const char *__path, int __name); + +int pause (void) { + return 0; +} + +// #if __POSIX_VISIBLE >= 199506 int +// pthread_atfork (void (*)(void), void (*)(void), void (*)(void)); +// #endif int + +// pipe (int __fildes[2]) { // pipe2(__fileds[2], 0); // } // int pipe2 (int __fildes[2], int flags); diff --git a/sdk_install/script-template.sh b/sdk_install/script-template.sh index 6557545..4723191 100644 --- a/sdk_install/script-template.sh +++ b/sdk_install/script-template.sh @@ -18,7 +18,7 @@ while getopts "c:d" opt; do DEFAULT_CLANG=true ;; ?) - echo "Unkown argument to scipt" + echo "Unknown argument to script" ;; esac done @@ -26,8 +26,17 @@ done SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) cd $SCRIPT_DIR +# Detect BSD vs GNU sed +if sed --version >/dev/null 2>&1; then + # GNU sed + SED_INPLACE() { sed -i "$@"; } +else + # BSD sed (macOS) + SED_INPLACE() { sed -i '' "$@"; } +fi + COMPILER_INCLUDES=$($CLANG_NAME -print-file-name=include) -sed -i "s|COMPILER_INCLUDES|$COMPILER_INCLUDES|g" @DANDELION_TARGET@-clang.cfg +SED_INPLACE "s|COMPILER_INCLUDES|$COMPILER_INCLUDES|g" @DANDELION_TARGET@-clang.cfg CLANG_PATH="$(which $CLANG_NAME)" CLANG_DIR="$(dirname $CLANG_PATH)" @@ -40,10 +49,10 @@ fi if [ $DEFAULT_CLANG = true ] && ! [[ -f $CLANG_DIR/clang ]]; then cp "$CLANG_PATH" "$CLANG_DIR/clang" ln -s "$CLANG_DIR/clang" "$CLANG_DIR/clang++" - sed "s||$SCRIPT_DIR|g" @DANDELION_TARGET@-clang.cfg >> "$CLANG_DIR/clang.cfg" + sed "s||$SCRIPT_DIR|g" @DANDELION_TARGET@-clang.cfg >> "$CLANG_DIR/clang.cfg" # enable stdinc, as we assume it has been cleared when we install our clang as system clang - sed -i "s|-nostdinc||g" "$CLANG_DIR/clang.cfg" - sed "s||$SCRIPT_DIR|g" @DANDELION_TARGET@-clang++.cfg >> "$CLANG_DIR/clang++.cfg" + SED_INPLACE "s|-nostdinc||g" "$CLANG_DIR/clang.cfg" + sed "s||$SCRIPT_DIR|g" @DANDELION_TARGET@-clang++.cfg >> "$CLANG_DIR/clang++.cfg" # need to change the config to use the clang.cfg in the same folder, so remove prefix - sed -i "s|@DANDELION_TARGET@-||g" "$CLANG_DIR/clang++.cfg" + SED_INPLACE "s|@DANDELION_TARGET@-||g" "$CLANG_DIR/clang++.cfg" fi \ No newline at end of file diff --git a/system/platform/debug/debug.c b/system/platform/debug/debug.c index e02bdf0..efd5420 100644 --- a/system/platform/debug/debug.c +++ b/system/platform/debug/debug.c @@ -186,7 +186,9 @@ void __dandelion_platform_init(void) { sysdata.input_bufs = heap_ptr; for (size_t input_set = 0; input_set < input_set_index; input_set++) { + // Set the starting offset for this set input_sets[input_set].offset = total_buffers; + write_all(1, "\t", 1); write_all(1, input_sets[input_set].ident, input_sets[input_set].ident_len); write_all(1, "\n", 1);