diff --git a/AK/Assertions.h b/AK/Assertions.h index 9e95bcc6c2..3c1e778a6f 100644 --- a/AK/Assertions.h +++ b/AK/Assertions.h @@ -1,8 +1,12 @@ #pragma once #ifdef SERENITY +#ifdef KERNEL #include #else +#include +#endif +#else #include #define ASSERT(x) assert(x) #define ASSERT_NOT_REACHED() assert(false) diff --git a/AK/StdLib.h b/AK/StdLib.h index 607682d784..efe871f014 100644 --- a/AK/StdLib.h +++ b/AK/StdLib.h @@ -1,8 +1,13 @@ #pragma once #ifdef SERENITY +#ifdef KERNEL #include #else +#include +#include +#endif +#else #include #include #include diff --git a/AK/kmalloc.h b/AK/kmalloc.h index 0ade91659a..02b66c2aab 100644 --- a/AK/kmalloc.h +++ b/AK/kmalloc.h @@ -3,10 +3,52 @@ #include "Compiler.h" #ifdef SERENITY -#ifdef USERLAND -#include -#else +#ifdef KERNEL #include +#else +#include + +extern "C" { + +void* kcalloc(size_t nmemb, size_t size); +void* kmalloc(size_t size) MALLOC_ATTR; +void kfree(void* ptr); +void* krealloc(void* ptr, size_t size); + +} + +inline void* operator new(size_t size) +{ + return kmalloc(size); +} + +inline void* operator new[](size_t size) +{ + return kmalloc(size); +} + +inline void operator delete(void* ptr) +{ + return kfree(ptr); +} + +inline void operator delete[](void* ptr) +{ + return kfree(ptr); +} + +inline void operator delete(void* ptr, size_t) +{ + return kfree(ptr); +} + +inline void operator delete[](void* ptr, size_t) +{ + return kfree(ptr); +} + +inline void* operator new(size_t, void* p) { return p; } +inline void* operator new[](size_t, void* p) { return p; } #endif #else #include diff --git a/Kernel/Makefile b/Kernel/Makefile index b93376664a..c7dfcd6ce2 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -59,7 +59,7 @@ FLAVOR_FLAGS = -mregparm=3 -march=i386 -m32 -fno-exceptions -fno-rtti -fmerge-al OPTIMIZATION_FLAGS = -Os -fno-asynchronous-unwind-tables INCLUDE_FLAGS = -I.. -I. -DEFINES = -DSERENITY -DSANITIZE_PTRS +DEFINES = -DSERENITY -DKERNEL -DSANITIZE_PTRS CXXFLAGS = $(WARNING_FLAGS) $(OPTIMIZATION_FLAGS) $(KERNEL_FLAGS) $(FLAVOR_FLAGS) $(ARCH_FLAGS) $(STANDARD_FLAGS) $(INCLUDE_FLAGS) $(DEFINES) #CXX = /usr/local/gcc-4.8.1-for-linux64/bin/x86_64-pc-linux-g++ diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index 10326fe03d..bbec8f0fe5 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -142,6 +142,7 @@ Task::Region* Task::allocateRegion(size_t size, String&& name) bool Task::deallocateRegion(Region& region) { + InterruptDisabler disabler; for (size_t i = 0; i < m_regions.size(); ++i) { if (m_regions[i].ptr() == ®ion) { // FIXME: This seems racy. diff --git a/LibC/Makefile b/LibC/Makefile index d0ab3ef533..c376122965 100644 --- a/LibC/Makefile +++ b/LibC/Makefile @@ -1,4 +1,11 @@ -OBJS = \ +AK_OBJS = \ + ../AK/StringImpl.o \ + ../AK/String.o \ + ../AK/StringBuilder.o \ + ../AK/FileSystemPath.o \ + ../AK/kmalloc.o + +LIBC_OBJS = \ stdio.o \ unistd.o \ string.o \ @@ -8,8 +15,11 @@ OBJS = \ stdlib.o \ time.o \ utsname.o \ + assert.o \ entry.o +OBJS = $(AK_OBJS) $(LIBC_OBJS) + LIBRARY = LibC.a ARCH_FLAGS = STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib @@ -19,7 +29,7 @@ FLAVOR_FLAGS = -fomit-frame-pointer -mregparm=3 -march=i386 -m32 -fno-exceptions OPTIMIZATION_FLAGS = -Os -fno-asynchronous-unwind-tables INCLUDE_FLAGS = -I.. -I. -DEFINES = -DSERENITY -DSANITIZE_PTRS +DEFINES = -DSERENITY -DUSERLAND -DSANITIZE_PTRS CXXFLAGS = $(WARNING_FLAGS) $(OPTIMIZATION_FLAGS) $(LIBC_FLAGS) $(FLAVOR_FLAGS) $(ARCH_FLAGS) $(STANDARD_FLAGS) $(INCLUDE_FLAGS) $(DEFINES) CXX = g++-8 diff --git a/LibC/assert.cpp b/LibC/assert.cpp new file mode 100644 index 0000000000..4aa774c3fd --- /dev/null +++ b/LibC/assert.cpp @@ -0,0 +1,14 @@ +#include "assert.h" +#include "stdlib.h" +#include "stdio.h" + +extern "C" { + +extern void __assertion_failed(const char* msg, const char* file, unsigned line, const char* func) +{ + printf("ASSERTION FAILED: %s\n%s:%u in %s\n", msg, file, line, func); + abort(); +} + +} + diff --git a/LibC/assert.h b/LibC/assert.h new file mode 100644 index 0000000000..1f5610dd2e --- /dev/null +++ b/LibC/assert.h @@ -0,0 +1,14 @@ +#pragma once + +extern "C" { + +void __assertion_failed(const char* msg, const char* file, unsigned line, const char* func); + +#define assert(expr) (static_cast(expr) ? (void)0 : __assertion_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__)) +#define CRASH() do { asm volatile("ud2"); } while(0) +#define ASSERT assert +#define RELEASE_ASSERT assert +#define ASSERT_NOT_REACHED() assert(false) + +} + diff --git a/LibC/entry.cpp b/LibC/entry.cpp index 5d5eb27078..c3657b704b 100644 --- a/LibC/entry.cpp +++ b/LibC/entry.cpp @@ -1,4 +1,5 @@ #include +#include extern "C" int main(int, char**); @@ -8,6 +9,8 @@ extern "C" int _start() { errno = 0; + StringImpl::initializeGlobals(); + int argc; char** argv; int rc = Syscall::invoke(Syscall::GetArguments, (dword)&argc, (dword)&argv); diff --git a/LibC/stdlib.cpp b/LibC/stdlib.cpp index 7d0f1b5e8f..5feceaec5f 100644 --- a/LibC/stdlib.cpp +++ b/LibC/stdlib.cpp @@ -1,5 +1,7 @@ #include "stdlib.h" #include "mman.h" +#include +#include extern "C" { @@ -20,5 +22,28 @@ void free(void* ptr) munmap(ptr, 4096); } +void* calloc(size_t nmemb, size_t) +{ + ASSERT_NOT_REACHED(); + return nullptr; +} + +void* realloc(void *ptr, size_t) +{ + ASSERT_NOT_REACHED(); + return nullptr; +} + +void exit(int status) +{ + Syscall::invoke(Syscall::PosixExit, (dword)status); +} + +void abort() +{ + // FIXME: Implement proper abort(). + exit(253); +} + } diff --git a/LibC/stdlib.h b/LibC/stdlib.h index 55cd47c9f7..4ebff011da 100644 --- a/LibC/stdlib.h +++ b/LibC/stdlib.h @@ -6,6 +6,11 @@ extern "C" { void* malloc(size_t); void free(void*); +void* calloc(size_t nmemb, size_t); +void* realloc(void *ptr, size_t); + +void exit(int status); +void abort(); } diff --git a/LibC/string.cpp b/LibC/string.cpp index a72bbb7cda..a48e1c2a4f 100644 --- a/LibC/string.cpp +++ b/LibC/string.cpp @@ -21,6 +21,17 @@ int strcmp(const char* s1, const char* s2) return *(const unsigned char*)s1 < *(const unsigned char*)s2 ? -1 : 1; } +int memcmp(const void* v1, const void* v2, size_t n) +{ + auto* s1 = (const byte*)v1; + auto* s2 = (const byte*)v2; + while (n-- > 0) { + if (*s1++ != *s2++) + return s1[-1] < s2[-1] ? -1 : 1; + } + return 0; +} + void memcpy(void* dest, const void* src, size_t n) { auto* bdest = (unsigned char*)dest; diff --git a/LibC/string.h b/LibC/string.h index 32444fd90d..6ef56e075b 100644 --- a/LibC/string.h +++ b/LibC/string.h @@ -6,6 +6,7 @@ extern "C" { size_t strlen(const char*); int strcmp(const char*, const char*); +int memcmp(const void*, const void*, size_t); void memcpy(void*, const void*, size_t); const char* strerror(int errnum); diff --git a/Userland/sh.cpp b/Userland/sh.cpp index faed58e715..b172f6fa9c 100644 --- a/Userland/sh.cpp +++ b/Userland/sh.cpp @@ -4,21 +4,25 @@ #include #include #include +#include -char* g_cwd = nullptr; -char g_hostname[32]; +struct GlobalState { + String cwd; + char hostname[32]; +}; +static GlobalState* g; static void prompt() { if (getuid() == 0) printf("# "); else - printf("\033[32;1m%s\033[0m:\033[34;1m%s\033[0m$> ", g_hostname, g_cwd); + printf("\033[32;1m%s\033[0m:\033[34;1m%s\033[0m$> ", g->hostname, g->cwd.characters()); } static int sh_pwd(int, const char**) { - printf("%s\n", g_cwd); + printf("%s\n", g->cwd.characters()); return 0; } @@ -30,26 +34,34 @@ static int sh_cd(int argc, const char** argv) } char pathbuf[128]; - if (argv[1][1] == '/') - memcpy(pathbuf, argv[1], strlen(argv[1])); + if (argv[1][0] == '/') + memcpy(pathbuf, argv[1], strlen(argv[1]) + 1); else - sprintf(pathbuf, "%s/%s", g_cwd, argv[1]); + sprintf(pathbuf, "%s/%s", g->cwd.characters(), argv[1]); + + FileSystemPath canonicalPath(pathbuf); + if (!canonicalPath.isValid()) { + printf("FileSystemPath failed to canonicalize '%s'\n", pathbuf); + return 1; + } + const char* path = canonicalPath.string().characters(); + struct stat st; - int rc = lstat(pathbuf, &st); + int rc = lstat(path, &st); if (rc < 0) { - printf("lstat(%s) failed: %s\n", pathbuf, strerror(errno)); + printf("lstat(%s) failed: %s\n", path, strerror(errno)); return 1; } if (!S_ISDIR(st.st_mode)) { - printf("Not a directory: %s\n", pathbuf); + printf("Not a directory: %s\n", path); return 1; } - rc = chdir(pathbuf); + rc = chdir(path); if (rc < 0) { - printf("chdir(%s) failed: %s\n", pathbuf, strerror(errno)); + printf("chdir(%s) failed: %s\n", path, strerror(errno)); return 1; } - memcpy(g_cwd, pathbuf, strlen(pathbuf)); + g->cwd = canonicalPath.string(); return 0; } @@ -115,7 +127,8 @@ static int runcmd(char* cmd) int main(int, char**) { - int rc = gethostname(g_hostname, sizeof(g_hostname)); + g = new GlobalState; + int rc = gethostname(g->hostname, sizeof(g->hostname)); if (rc < 0) perror("gethostname"); @@ -128,9 +141,7 @@ int main(int, char**) printf("failed to open /dev/keyboard :(\n"); return 1; } - g_cwd = (char*)malloc(1024); - g_cwd[0] = '/'; - g_cwd[1] = '\0'; + g->cwd = "/"; prompt(); for (;;) { char keybuf[16]; diff --git a/Userland/tst.cpp b/Userland/tst.cpp index 31a1439e64..0799e161bb 100644 --- a/Userland/tst.cpp +++ b/Userland/tst.cpp @@ -1,4 +1,4 @@ -#include +#include int main(int argc, char** argv) {