Commit 63f1eab
Changed files (10)
datatypes
memory
platform
linux
testing
datatypes/error.h
@@ -67,7 +67,7 @@ enum _ErrorReasons {
#define TRY(...) do { \
Status _res = (__VA_ARGS__); \
if( S_NOK(_res) ) { \
- return _res; \
+ return _res; \
} \
} while(0)
memory/memory.h
@@ -50,4 +50,16 @@ Status mem_relinquish( Page *start, u32 page_count ); /* Free virtual memory ran
Status mem_occupy( Page *start, u32 page_count ); /* Set up physical backing */
Status mem_vacate( Page *start, u32 page_count ); /* Allow removal of physical backing */
+#ifdef NOTLIBC_IMPLEMENT
+
+extern void *memset( void* ptr, int value, unsigned long count );
+
+void *memset( void* ptr, int value, unsigned long count ) {
+ mem_set( ptr, count, value );
+ return ptr;
+}
+
+#endif
+
+
#endif
platform/linux/file.h
@@ -105,81 +105,20 @@ Status File_open( const String *name, usize flags, File *out ) {
break;
}
- out->fd = linux_open( &name->data[0], syscall_flags, 0666 );
-
- if( !LINUX_SYSCALL_ERROR( out->fd ) ) {
- return S_SUCCESS;
- } else {
- switch( out->fd ) {
- case -EACCES:
- case -EPERM:
- return S_FAILURE | ERRSRC_PLATFORM | ERR_PERMISSION_DENIED;
- case -EEXIST:
- return S_FAILURE | ERRSRC_PLATFORM | ERR_FILE_ALREADY_EXISTS;
- case -EINVAL:
- return S_FAILURE | ERRSRC_PLATFORM | ERR_INVALID_ARGUMENT;
- case -ENOENT:
- return S_FAILURE | ERRSRC_PLATFORM | ERR_FILE_DOESNT_EXIST;
- case -ENAMETOOLONG:
- return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
- case -ENOSPC:
- return S_FAILURE | ERRSRC_PLATFORM | ERR_NO_DISK_SPACE;
- default:
- return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
- }
- }
+ return linux_open( &name->data[0], syscall_flags, 0666, &out->fd );
}
Status File_close( File *f ) {
- usize res = linux_close( f->fd );
-
- if( !LINUX_SYSCALL_ERROR( res ) ) {
- f->fd = -1;
- return S_SUCCESS;
- } else {
- switch( res ) {
- case -EBADF:
- return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
- default:
- return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
- }
- }
+ return linux_close( &f->fd );
}
Status File_read( const File *f, usize max_amount, usize *out_amount, u8 *out ) {
- usize res = linux_read( f->fd, out, max_amount );
- if( !LINUX_SYSCALL_ERROR(res) ) {
- *out_amount = res;
- return S_SUCCESS;
- } else {
- switch(res) {
- case -EBADF:
- return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
- case -EFAULT:
- return S_FAILURE | ERRSRC_ARG_3 | ERR_OUT_OF_BOUND;
- default:
- return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
- }
- }
+ return linux_read( f->fd, max_amount, out_amount, out);
}
Status File_write( const File *f, usize amount, usize *out_amount, const u8 *buf ) {
- usize res = linux_write( f->fd, buf, amount );
-
- if( !LINUX_SYSCALL_ERROR(res) ) {
- *out_amount = res;
- return S_SUCCESS;
- } else {
- switch(res) {
- case -EBADF:
- return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
- case -EFAULT:
- return S_FAILURE | ERRSRC_ARG_3 | ERR_OUT_OF_BOUND;
- default:
- return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
- }
- }
+ return linux_write( f->fd, amount, out_amount, buf );
}
Status File_delete( const String *name ) {
@@ -203,20 +142,7 @@ Status File_delete( const String *name ) {
}
Status File_seek( const File *f, usize position ) {
- usize res = linux_lseek( f->fd, position, SEEK_SET );
-
- if( !LINUX_SYSCALL_ERROR(res) ) {
- return S_SUCCESS;
- } else {
- switch( res ) {
- case -EBADF:
- return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
- case -EOVERFLOW:
- return S_FAILURE | ERR_OVERFLOW;
- default:
- return S_FAILURE | ERR_GENERIC;
- }
- }
+ return linux_lseek( f->fd, position, SEEK_SET );
}
Status FileView_from_file( File *file, usize claim_amount, usize flags, FileView *out ) {
@@ -231,22 +157,24 @@ Status FileView_from_file( File *file, usize claim_amount, usize flags, FileView
/* Get filesize */
struct stat s = {0};
- isize res = linux_fstat( file->fd, &s );
-
- if( LINUX_SYSCALL_ERROR(res) ) {
- DEBUG(breakpoint());
- return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
- }
+ TRY( linux_fstat( file->fd, &s ) );
out->filesize = s.st_size;
- if( out->filesize != 0 ) { /* Nothing to map in an empty file */
- res = linux_mmap( (usize)out->start, out->filesize, LINUX_PROT_READ | LINUX_PROT_WRITE, MMAP_MAP_FIXED | MMAP_MAP_SHARED, file->fd, 0 );
- if( LINUX_SYSCALL_ERROR(res) ) {
- DEBUG(breakpoint());
- return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
- }
+ void *discard;
+
+ if( out->filesize > 0 ) { /* Nothing to map in an empty file */
+ TRY( linux_mmap(
+ (usize)out->start,
+ out->filesize,
+ LINUX_PROT_READ | LINUX_PROT_WRITE,
+ MMAP_MAP_FIXED | MMAP_MAP_SHARED,
+ file->fd,
+ 0,
+ &discard
+ ));
}
+
/* Finalize output */
out->file = *file;
out->flags = flags;
@@ -281,26 +209,21 @@ Status FileView_extend_file( FileView *fv, usize amount ) {
usize map_start_addr = (u64)((u8*)fv->start + map_start_offset);
+ TRY( linux_fallocate( fv->file.fd, 0, fv->filesize, amount ) );
- usize res = linux_fallocate( fv->file.fd, 0, fv->filesize, amount );
- if( LINUX_SYSCALL_ERROR(res) ) {
- return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
- }
fv->filesize += amount;
- res = linux_mmap(
+ void *discard;
+
+ TRY( linux_mmap(
map_start_addr,
fv->filesize - map_start_offset + amount,
LINUX_PROT_READ | LINUX_PROT_WRITE,
MMAP_MAP_FIXED | MMAP_MAP_SHARED,
fv->file.fd,
- map_start_offset
- );
-
-
- if( LINUX_SYSCALL_ERROR(res) ) {
- return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_MAP_FAILURE;
- }
+ map_start_offset,
+ &discard
+ ));
return S_SUCCESS;
}
@@ -311,10 +234,7 @@ Status FileView_destroy( FileView *fv ) {
fv->file.fd = -1;
}
- usize res = linux_munmap( (usize)fv->start, fv->claimed );
- if( LINUX_SYSCALL_ERROR(res) ) {
- return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_UNMAP_FAILURE;
- }
+ TRY( linux_munmap( (usize)fv->start, fv->claimed ) );
fv->flags = 0;
fv->filesize = 0;
platform/linux/memory.h
@@ -6,12 +6,16 @@
#include "./syscalls.h"
Status mem_claim( u32 page_count, Page **ptr_out) {
- void* res = (void*)linux_mmap( 0, page_count*sizeof(Page), LINUX_PROT_NONE, MMAP_MAP_PRIVATE | MMAP_MAP_ANONYMOUS, -1, 0 );
+ TRY( linux_mmap(
+ 0,
+ page_count*sizeof(Page),
+ LINUX_PROT_NONE,
+ MMAP_MAP_PRIVATE | MMAP_MAP_ANONYMOUS,
+ -1,
+ 0,
+ (void**)ptr_out
+ ));
- if( LINUX_SYSCALL_ERROR(res) )
- return S_FAILURE | ERR_MEM_MAP_FAILURE;
-
- *ptr_out = res;
return S_SUCCESS;
}
@@ -26,29 +30,19 @@ Status mem_relinquish( Page *start, u32 page_count ) {
}
Status mem_occupy( Page *start, u32 page_count ) {
- usize res = linux_mprotect( (usize)start, page_count*sizeof(Page), LINUX_PROT_READ | LINUX_PROT_WRITE );
-
- if( LINUX_SYSCALL_ERROR(res) ) {
- return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_SETPERM_FAILURE;
- }
+ return linux_mprotect(
+ (usize)start,
+ page_count*sizeof(Page),
+ LINUX_PROT_READ | LINUX_PROT_WRITE
+ );
- return S_SUCCESS;
}
Status mem_vacate( Page *start, u32 page_count ) {
usize amount = page_count*sizeof(Page);
- usize res = linux_mprotect( (usize)start, amount, LINUX_PROT_NONE );
-
- if( LINUX_SYSCALL_ERROR(res) ) {
- return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_SETPERM_FAILURE;
- }
-
- res = linux_madvise( (usize)start, amount, MADV_DONTNEED);
-
- if( LINUX_SYSCALL_ERROR(res) ) {
- return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_SETHINT_FAILURE;
- }
+ TRY( linux_mprotect( (usize)start, amount, LINUX_PROT_NONE ) );
+ TRY( linux_madvise( (usize)start, amount, MADV_DONTNEED) );
return S_SUCCESS;
}
platform/linux/syscalls.h
@@ -1,7 +1,9 @@
#ifndef HEADER_PLATFORM_LINUX_SYSCALLS_INCLUDED
#define HEADER_PLATFORM_LINUX_SYSCALLS_INCLUDED
+#include "datatypes/error.h"
#include "platform/common/types.h"
+#include "platform/info/build.h"
static inline isize linux_syscall1(usize num, usize arg1);
static inline isize linux_syscall2(usize num, usize arg1, usize arg2);
@@ -155,13 +157,39 @@ static inline isize linux_syscall6(usize num, usize arg1, usize arg2, usize arg3
#define ERFKILL 132 /* Operation not possible due to RF-kill */
#define EHWPOISON 133 /* Memory page has hardware error */
-
-static inline isize linux_read( u32 fd, u8* buf, usize count ) {
- return linux_syscall3( 0, fd, (usize)buf, count );
+static inline Status linux_read( u32 fd, usize max_amount, usize *out_amount, u8 *out ) {
+ usize res = linux_syscall3( 0, fd, (usize)out, max_amount );
+ if( !LINUX_SYSCALL_ERROR(res) ) {
+ *out_amount = res;
+ return S_SUCCESS;
+ } else {
+ switch(res) {
+ case -EBADF:
+ return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
+ case -EFAULT:
+ return S_FAILURE | ERRSRC_ARG_3 | ERR_OUT_OF_BOUND;
+ default:
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+ }
+ }
}
-static inline isize linux_write( u32 fd, const u8* buf, usize count ) {
- return linux_syscall3( 1, fd, (usize)buf, count );
+static inline Status linux_write( u32 fd, usize amount, usize *out_amount, const u8 *buf ) {
+ usize res = linux_syscall3( 1, fd, (usize)buf, amount );
+
+ if( !LINUX_SYSCALL_ERROR(res) ) {
+ *out_amount = res;
+ return S_SUCCESS;
+ } else {
+ switch(res) {
+ case -EBADF:
+ return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
+ case -EFAULT:
+ return S_FAILURE | ERRSRC_ARG_3 | ERR_OUT_OF_BOUND;
+ default:
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+ }
+ }
}
/* Copied from some header included by linux/fcntl */
@@ -190,20 +218,69 @@ static inline isize linux_write( u32 fd, const u8* buf, usize count ) {
#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
-static inline isize linux_open( const u8* path, s32 flags, s32 mode ) {
- return linux_syscall3( 2, (usize)path, (usize)flags, (usize)mode);
+static inline Status linux_open( const u8* path, s32 flags, s32 mode, s32 *out_fd ) {
+ isize res = linux_syscall3( 2, (usize)path, (usize)flags, (usize)mode);
+
+ if( !LINUX_SYSCALL_ERROR( res ) ) {
+ *out_fd = res;
+ return S_SUCCESS;
+ } else {
+ switch( res ) {
+ case -EACCES:
+ case -EPERM:
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_PERMISSION_DENIED;
+ case -EEXIST:
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_FILE_ALREADY_EXISTS;
+ case -EINVAL:
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_INVALID_ARGUMENT;
+ case -ENOENT:
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_FILE_DOESNT_EXIST;
+ case -ENAMETOOLONG:
+ return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
+ case -ENOSPC:
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_NO_DISK_SPACE;
+ default:
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+ }
+ }
}
-static inline isize linux_close( u32 fd ) {
- return linux_syscall1( 3, fd );
+static inline Status linux_close( s32 *fd ) {
+ usize res = linux_syscall1( 3, *fd );
+
+ if( !LINUX_SYSCALL_ERROR( res ) ) {
+ *fd = -1;
+ return S_SUCCESS;
+ } else {
+ switch( res ) {
+ case -EBADF:
+ return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
+ default:
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+ }
+ }
}
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
-static inline isize linux_lseek( u32 fd, usize offset, usize whence ) {
- return linux_syscall3( 8, fd, offset, whence );
+static inline Status linux_lseek( u32 fd, usize offset, usize whence ) {
+
+ usize res = linux_syscall3( 8, fd, offset, whence );
+
+ if( !LINUX_SYSCALL_ERROR(res) ) {
+ return S_SUCCESS;
+ } else {
+ switch( res ) {
+ case -EBADF:
+ return S_FAILURE | ERRSRC_ARG_1 | ERR_INVALID_ARGUMENT;
+ case -EOVERFLOW:
+ return S_FAILURE | ERR_OVERFLOW;
+ default:
+ return S_FAILURE | ERR_GENERIC;
+ }
+ }
}
#if ARCH == ARCH_X86_64
@@ -242,8 +319,14 @@ static inline isize linux_stat( const char* path, struct stat *statbuf ) {
return linux_syscall2( 4, (usize)path, (usize)statbuf );
}
-static inline isize linux_fstat( s32 fd, struct stat *statbuf ) {
- return linux_syscall2( 5, (usize)fd, (usize)statbuf );
+static inline Status linux_fstat( s32 fd, struct stat *statbuf ) {
+ isize res = linux_syscall2( 5, (usize)fd, (usize)statbuf );
+
+ if( !LINUX_SYSCALL_ERROR(res) ) {
+ return S_SUCCESS;
+ } else {
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+ }
}
static inline void linux_exit( s32 exitcode ) {
@@ -265,18 +348,36 @@ static inline void linux_exit( s32 exitcode ) {
#define MMAP_MAP_FAILED ((void *)-1)
-static inline isize linux_mmap( usize addr, usize len, usize prot, usize flags, usize fd, usize offset ) {
- return linux_syscall6( 9, addr, len, prot, flags, fd, offset );
-}
+static inline Status linux_mmap( usize addr, usize len, usize prot, usize flags, usize fd, usize offset, void **out ) {
+ isize res = linux_syscall6( 9, addr, len, prot, flags, fd, offset );
-static inline isize linux_munmap( usize start, usize len ) {
- return linux_syscall2( 11, start, len );
+ if( !LINUX_SYSCALL_ERROR(res) ) {
+ *out = (void*)res;
+ return S_SUCCESS;
+ } else {
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_MAP_FAILURE;
+ }
}
-static inline isize linux_mprotect( usize start, usize len, usize prot ) {
- return linux_syscall3( 10, start, len, prot );
+static inline Status linux_munmap( usize start, usize len ) {
+ isize res = linux_syscall2( 11, start, len );
+
+ if( !LINUX_SYSCALL_ERROR(res) ) {
+ return S_SUCCESS;
+ } else {
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_UNMAP_FAILURE;
+ }
}
+static inline Status linux_mprotect( usize start, usize len, usize prot ) {
+ isize res = linux_syscall3( 10, start, len, prot );
+
+ if( !LINUX_SYSCALL_ERROR(res) ) {
+ return S_SUCCESS;
+ } else {
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_SETPERM_FAILURE;
+ }
+}
#define MADV_NORMAL 0
#define MADV_RANDOM 1
@@ -305,8 +406,14 @@ static inline isize linux_mprotect( usize start, usize len, usize prot ) {
#define MADV_GUARD_INSTALL 102
#define MADV_GUARD_REMOVE 103
-static inline isize linux_madvise( usize start, usize len, s32 behaviour ) {
- return linux_syscall3( 11, start, len, (usize)(u32)behaviour );
+static inline Status linux_madvise( usize start, usize len, s32 behaviour ) {
+ isize res = linux_syscall3( 11, start, len, (usize)(u32)behaviour );
+
+ if( !LINUX_SYSCALL_ERROR(res) ) {
+ return S_SUCCESS;
+ } else {
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_MEM_SETHINT_FAILURE;
+ }
}
@@ -314,8 +421,14 @@ static inline isize linux_unlink( const u8 *path ) {
return linux_syscall1( 87, (usize)path );
}
-static inline isize linux_fallocate( s32 fd, s32 mode, usize offset, usize len ) {
- return linux_syscall4(285, fd, mode, offset, len);
+static inline Status linux_fallocate( s32 fd, s32 mode, usize offset, usize len ) {
+ isize res = linux_syscall4(285, fd, mode, offset, len);
+
+ if( !LINUX_SYSCALL_ERROR(res) ) {
+ return S_SUCCESS;
+ } else {
+ return S_FAILURE | ERRSRC_PLATFORM | ERR_GENERIC;
+ }
}
#endif
platform/platform.h
@@ -24,4 +24,6 @@
}
#endif
+
+
#endif
testing/tests/000_entry_exit.c
@@ -1,4 +1,4 @@
-#include "platform/platform.h"
+#include "notlibc/core.h"
void entry(void) {
terminate(0);
testing/tests/001_safemath.c
@@ -1,5 +1,4 @@
-#include "platform/platform.h"
-#include "util/mathops.h"
+#include "notlibc/core.h"
#define N 12
testing/tests/002_round.c
@@ -1,5 +1,4 @@
-#include "platform/platform.h"
-#include "util/mathops.h"
+#include "notlibc/core.h"
#define N 13
testing/test.sh
@@ -20,7 +20,7 @@ echo
echo Compiling tests.
echo
-CFLAGS="-nostdlib -I. -DNOTLIBC_IMPLEMENT -DNOTLIBC_SILENCE -fno-builtin -g"
+CFLAGS="-nostdlib -ffreestanding -I. -DNOTLIBC_IMPLEMENT -DNOTLIBC_SILENCE -fno-builtin -g -Wall -Wextra -Wpedantic -Werror"
for SRC in ./testing/tests/*.c; do