aboutsummaryrefslogtreecommitdiff
path: root/src/lib/libc
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2016-07-16 18:07:24 +0200
committerAlex Auvolat <alex@adnab.me>2016-07-16 18:07:24 +0200
commitbb2dd23f315bafa7b0b64845c2fe25d7a0893b10 (patch)
tree51657cd1ad8b6f1d5941604e75c251a246809034 /src/lib/libc
parent3d6a857b9186ef6304ea6cf04627c2b787169f29 (diff)
downloadkogata-bb2dd23f315bafa7b0b64845c2fe25d7a0893b10.tar.gz
kogata-bb2dd23f315bafa7b0b64845c2fe25d7a0893b10.zip
Got Lua running \o/
Diffstat (limited to 'src/lib/libc')
-rw-r--r--src/lib/libc/malloc.c13
-rw-r--r--src/lib/libc/readline.c1
-rw-r--r--src/lib/libc/setjmp.s75
-rw-r--r--src/lib/libc/start.c3
-rw-r--r--src/lib/libc/stdio.c191
-rw-r--r--src/lib/libc/stdlib.c2
6 files changed, 176 insertions, 109 deletions
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;
}