diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/include/setjmp.h | 5 | ||||
-rw-r--r-- | src/lib/include/stdio.h | 26 | ||||
-rw-r--r-- | src/lib/libc/malloc.c | 13 | ||||
-rw-r--r-- | src/lib/libc/readline.c | 1 | ||||
-rw-r--r-- | src/lib/libc/setjmp.s | 75 | ||||
-rw-r--r-- | src/lib/libc/start.c | 3 | ||||
-rw-r--r-- | src/lib/libc/stdio.c | 191 | ||||
-rw-r--r-- | src/lib/libc/stdlib.c | 2 |
8 files changed, 192 insertions, 124 deletions
diff --git a/src/lib/include/setjmp.h b/src/lib/include/setjmp.h index 46c3b5d..904ae4a 100644 --- a/src/lib/include/setjmp.h +++ b/src/lib/include/setjmp.h @@ -2,10 +2,7 @@ #include <stdint.h> -struct _jmp_buf { - uint32_t stuff[10]; // 40 bytes -}; -typedef struct _jmp_buf jmp_buf; +typedef uint32_t jmp_buf[10]; int setjmp(jmp_buf env); diff --git a/src/lib/include/stdio.h b/src/lib/include/stdio.h index c6b636d..a67553c 100644 --- a/src/lib/include/stdio.h +++ b/src/lib/include/stdio.h @@ -2,6 +2,8 @@ #include <stdarg.h> +#include <proto/fs.h> + #include <kogata/printf.h> #include <kogata/syscall.h> @@ -11,7 +13,10 @@ void setup_libc_stdio(); //TODO below struct file_t { - // TODO + fd_t fd; + stat_t st; + int mode; + int flags; }; typedef struct file_t FILE; @@ -47,15 +52,15 @@ int fclose(FILE* f); extern FILE *stdin, *stdout, *stderr; -#define BUFSIZ 0 +#define BUFSIZ 1024 void setbuf(FILE *stream, char *buf); void setbuffer(FILE *stream, char *buf, size_t size); void setlinebuf(FILE *stream); int setvbuf(FILE *stream, char *buf, int mode, size_t size); -#define _IOFBF 0 -#define _IOLBF 1 -#define _IONBF 2 +#define _IOFBF 1 +#define _IOLBF 2 +#define _IONBF 4 typedef size_t fpos_t; //TODO @@ -65,9 +70,9 @@ void rewind(FILE *stream); int fgetpos(FILE *stream, fpos_t *pos); int fsetpos(FILE *stream, const fpos_t *pos); -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 +#define SEEK_SET 1 +#define SEEK_CUR 2 +#define SEEK_END 4 #define L_tmpnam 128 FILE *tmpfile(void); @@ -76,11 +81,10 @@ char *tmpnam(char *s); int rename(const char *old, const char *new); int remove(const char *pathname); - int printf(const char *format, ...); int fprintf(FILE *stream, const char *format, ...); -int dprintf(int fd, const char *format, ...); -int sprintf(char *str, const char *format, ...); +int vfprintf(FILE *stream, const char *format, va_list ap); + /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libc/malloc.c b/src/lib/libc/malloc.c index 473404b..fd37f76 100644 --- a/src/lib/libc/malloc.c +++ b/src/lib/libc/malloc.c @@ -54,7 +54,10 @@ void malloc_setup() { void* malloc(size_t size) { if (size == 0) return 0; - return slab_alloc(mem_allocator, size); + //dbg_printf("malloc 0x%p -> ", size); + void* ret = slab_alloc(mem_allocator, size); + //dbg_printf("0x%p\n", ret); + return ret; } void* calloc(size_t nmemb, size_t sz) { @@ -64,10 +67,16 @@ void* calloc(size_t nmemb, size_t sz) { } void* realloc(void* ptr, size_t sz) { - return slab_realloc(mem_allocator, ptr, sz); + //dbg_printf("realloc 0x%p 0x%p -> ", ptr, sz); + void* ret = slab_realloc(mem_allocator, ptr, sz); + //dbg_printf("0x%p\n", ret); + return ret; } void free(void* ptr) { + if (ptr == 0) return; + + //dbg_printf("free 0x%p\n", ptr); slab_free(mem_allocator, ptr); } diff --git a/src/lib/libc/readline.c b/src/lib/libc/readline.c index 20c2007..c93bfe2 100644 --- a/src/lib/libc/readline.c +++ b/src/lib/libc/readline.c @@ -21,6 +21,7 @@ char *readline(const char* prompt) { // readline_history *h = &stdio_history; puts(prompt); + fflush(stdout); char* buf = malloc(READLINE_MAX_LEN); if (buf == NULL) return NULL; diff --git a/src/lib/libc/setjmp.s b/src/lib/libc/setjmp.s index 164cc5b..a9b5f48 100644 --- a/src/lib/libc/setjmp.s +++ b/src/lib/libc/setjmp.s @@ -1,24 +1,18 @@ [GLOBAL setjmp] setjmp: - ; Store general purpose registers - ; (in new stack frame) - mov [esp+4], eax - mov [esp+8], ebx - mov [esp+12], ecx - mov [esp+16], edx - mov [esp+20], edi - mov [esp+24], esi - mov [esp+28], ebp - mov [esp+32], esp - - ; Store flags - pushf - pop eax - mov [esp+36], eax + ; get return address + mov edx, [esp] + ; get address of jmpbuf structure + mov ecx, [esp+4] - ; Store return address - mov eax, [esp] - mov [esp+40], eax + ; Store general purpose registers + mov [ecx], ebx + mov [ecx+4], edx + mov [ecx+8], ebp + mov [ecx+12], esp + mov [ecx+16], esi + mov [ecx+20], edi + mov [ecx+24], eax ; return 0 xor eax, eax @@ -27,27 +21,26 @@ setjmp: [GLOBAL longjmp] longjmp: - ; on previous stack, resume return address - mov eax, [esp+32] - mov ebx, [esp+40] - mov [eax], ebx - - ; resume flags - mov eax, [esp+36] - push eax - popf - - ; load return value in eax - mov eax, [esp+44] - ; resume geneal purpose registers, except eax/esp - mov ebx, [esp+8] - mov ecx, [esp+12] - mov edx, [esp+16] - mov edi, [esp+20] - mov esi, [esp+24] - mov ebp, [esp+28] - - ; resume previous esp - mov esp, [esp+32] - ; return as if we were the setjmp call + ; get address of jmpbuf structure + mov ecx, [esp+4] + ; get retun value + mov eax, [esp+8] + + ; load general purpose registers + ; (edx contains the return address) + mov ebx, [ecx] + mov edx, [ecx+4] + mov ebp, [ecx+8] + mov esp, [ecx+12] + mov esi, [ecx+16] + mov edi, [ecx+20] + + ; make sure return value is nonzero + test eax, eax + jnz _doret + inc eax +_doret: + ; store back return address + mov [esp], edx ret + diff --git a/src/lib/libc/start.c b/src/lib/libc/start.c index 185d90f..49bf6a3 100644 --- a/src/lib/libc/start.c +++ b/src/lib/libc/start.c @@ -12,8 +12,9 @@ void __libc_start() { setup_libc_stdio(); // TODO : more setup ? yes, for args, for env... + char *argv[] = {"bin"}; - int ret = main(0, 0); + int ret = main(1, argv); sc_exit(ret); } diff --git a/src/lib/libc/stdio.c b/src/lib/libc/stdio.c index 8d4577e..c849683 100644 --- a/src/lib/libc/stdio.c +++ b/src/lib/libc/stdio.c @@ -10,15 +10,31 @@ FILE *stdin = 0; FILE *stdout = 0; FILE *stderr = 0; -void setup_libc_stdio() { - fd_t tty_io = STD_FD_TTY_STDIO; - // fd_t tty_in = STD_FD_STDIN; - // fd_t tty_out = STD_FD_STDOUT; - // fd_t tty_err = STD_FD_STDERR; +FILE libc_tty_stdio, libc_stdin, libc_stdout, libc_stderr; - // TODO - if (true) { - sc_fctl(tty_io, FC_SET_BLOCKING, 0); +void setup_libc_stdio() { + if (sc_stat_open(STD_FD_TTY_STDIO, &libc_tty_stdio.st)) { + libc_tty_stdio.fd = STD_FD_TTY_STDIO; + sc_fctl(libc_tty_stdio.fd, FC_SET_BLOCKING, 0); + // TODO: initialize libc_tty_stdio as a TTY + stdin = &libc_tty_stdio; + stdout = &libc_tty_stdio; + stderr = &libc_tty_stdio; + } + if (sc_stat_open(STD_FD_STDIN, &libc_stdin.st)) { + libc_stdin.fd = STD_FD_STDIN; + // TODO: initialize + stdin = &libc_stdin; + } + if (sc_stat_open(STD_FD_STDOUT, &libc_stdout.st)) { + libc_stdout.fd = STD_FD_STDOUT; + // TODO: initialize + stdout = &libc_stdout; + } + if (sc_stat_open(STD_FD_STDERR, &libc_stderr.st)) { + libc_stderr.fd = STD_FD_STDERR; + // TODO: initialize + stderr = &libc_stderr; } } @@ -37,13 +53,12 @@ int puts(const char* s) { int printf(const char* fmt, ...) { va_list ap; - char buffer[256]; va_start(ap, fmt); - vsnprintf(buffer, 256, fmt, ap); + int ret = vfprintf(stdout, fmt, ap); va_end(ap); - return puts(buffer); + return ret; } // ================== @@ -51,14 +66,59 @@ int printf(const char* fmt, ...) { // ================== -int fgetc(FILE *stream) { +FILE *fopen(const char *path, const char *mode) { // TODO return 0; } -char *fgets(char *s, int size, FILE *stream) { +FILE *freopen(const char *path, const char *mode, FILE *stream) { // TODO return 0; } +int fclose(FILE* f) { + // TODO + return 0; +} + + +// --------------- +// INPUT FUNCTIONS +// --------------- + +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { + if (stream == NULL || stream->fd == 0) return 0; + + // TODO buffering + // TODO position + return sc_read(stream->fd, 0, size * nmemb, ptr); +} + +int fgetc(FILE *stream) { + // TODO buffering && ungetc + char x; + if (fread(&x, 1, 1, stream)) { + return x; + } else { + return EOF; + } +} +char *fgets(char *s, int size, FILE *stream) { + int l = 0; + while (l < size - 1) { + int c = fgetc(stream); + if (c == EOF) { + break; + } else if (c == '\b') { + if (l > 0) l--; + // TODO if terminal write back space or something + } else { + s[l] = c; + l++; + if (c == '\n') break; + } + } + s[l] = 0; + return s; +} int getc(FILE *stream) { // TODO return 0; @@ -68,77 +128,90 @@ int ungetc(int c, FILE *stream) { return 0; } +// ---------------- +// OUTPUT FUNCTIONS +// ---------------- + +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { + if (stream == NULL || stream->fd == 0) return 0; + + // TODO buffering + // TODO position + return sc_write(stream->fd, 0, size * nmemb, ptr); +} + int fputc(int c, FILE *stream) { - // TODO - return 0; + unsigned char x = c; + return fwrite(&x, 1, 1, stream); } int fputs(const char *s, FILE *stream) { - // TODO - return 0; + return fwrite(s, strlen(s), 1, stream); } int putc(int c, FILE *stream) { - // TODO - return 0; + return fputc(c, stream); } -FILE *fopen(const char *path, const char *mode) { - // TODO - return 0; +int fprintf(FILE *stream, const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + int ret = vfprintf(stream, fmt, ap); + va_end(ap); + + return ret; } -FILE *freopen(const char *path, const char *mode, FILE *stream) { - // TODO - return 0; +int vfprintf(FILE *stream, const char *format, va_list ap) { + char buf[1024]; + vsnprintf(buf, 1024, format, ap); + + return fputs(buf, stream); } -void clearerr(FILE *stream) { - // TODO +// buffering + +void setbuf(FILE *stream, char *buf) { + setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ); } -int feof(FILE *stream) { +void setbuffer(FILE *stream, char *buf, size_t size) { // TODO - return 0; } -int ferror(FILE *stream) { +void setlinebuf(FILE *stream) { + setvbuf(stream, NULL, _IOLBF, 0); +} +int setvbuf(FILE *stream, char *buf, int mode, size_t size) { // TODO return 0; } -int fileno(FILE *stream) { + +int fflush(FILE* f) { // TODO return 0; } +// --------------------- +// COMPLICATED FUNCTIONS +// --------------------- -size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { +void clearerr(FILE *stream) { // TODO - return 0; } -size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { +int feof(FILE *stream) { // TODO return 0; } - -int fflush(FILE* f) { +int ferror(FILE *stream) { // TODO return 0; } -int fclose(FILE* f) { +int fileno(FILE *stream) { // TODO return 0; } -void setbuf(FILE *stream, char *buf) { - // TODO -} -void setbuffer(FILE *stream, char *buf, size_t size) { - // TODO -} -void setlinebuf(FILE *stream) { - // TODO -} -int setvbuf(FILE *stream, char *buf, int mode, size_t size) { - // TODO - return 0; -} +// ------------------ +// POSITION FUNCTIONS +// ------------------ int fseek(FILE *stream, long offset, int whence) { @@ -161,6 +234,10 @@ int fsetpos(FILE *stream, const fpos_t *pos) { return 0; } +// --------------------- +// PATH & FILE FUNCTIONS +// --------------------- + FILE *tmpfile(void) { // TODO return 0; @@ -181,18 +258,4 @@ int remove(const char *pathname) { -int fprintf(FILE *stream, const char *format, ...) { - // TODO - return 0; -} -int dprintf(int fd, const char *format, ...) { - // TODO - return 0; -} -int sprintf(char *str, const char *format, ...) { - // TODO - return 0; -} - - /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libc/stdlib.c b/src/lib/libc/stdlib.c index 540d53c..7d08cd1 100644 --- a/src/lib/libc/stdlib.c +++ b/src/lib/libc/stdlib.c @@ -57,7 +57,7 @@ double strtod(const char *nptr, char **endptr) { for (int i = 0; i < exp; i++) val /= 10; } } - if (endptr != NULL) *endptr = (char*)(p-1); + if (endptr != NULL) *endptr = (char*)p; return val * sign; } |