Skip to content

Commit

Permalink
fix: use Hermit's sys malloc and fix uninitialised global data
Browse files Browse the repository at this point in the history
  • Loading branch information
johnyob committed Aug 3, 2024
1 parent 57d1f40 commit 986404a
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 2 deletions.
2 changes: 1 addition & 1 deletion newlib/configure.host
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ case "${host}" in
syscall_dir=syscalls
;;
*-*-hermit*)
newlib_cflags="${newlib_cflags} -DREENTRANT_SYSCALLS_PROVIDED -D__DYNAMIC_REENT__ -DSIGNAL_PROVIDED -DHAVE_NANOSLEEP"
newlib_cflags="${newlib_cflags} -DREENTRANT_SYSCALLS_PROVIDED -D__DYNAMIC_REENT__ -DSIGNAL_PROVIDED -DHAVE_NANOSLEEP -DMALLOC_PROVIDED"
+ ;;
# RTEMS supplies its own versions of some routines:
# malloc() (reentrant version)
Expand Down
2 changes: 1 addition & 1 deletion newlib/libc/include/sys/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
#endif
#endif

#if defined(__mips__) && !defined(__rtems__)
#if (defined(__mips__) || defined(__hermit__)) && !defined(__rtems__)
#define __ATTRIBUTE_IMPURE_PTR__ __attribute__((__section__(".sdata")))
#endif

Expand Down
57 changes: 57 additions & 0 deletions newlib/libc/sys/hermit/crt0.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,74 @@
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <reent.h>
#include "syscall.h"

extern int main(int argc, char** argv);
extern void __libc_init_array(void);
extern void __libc_fini_array (void);
extern int _init_signal(void);
extern char** environ;
extern void __sinit (struct _reent *);
extern struct _glue __sglue;
extern __FILE __sf[3];

typedef struct layout {
size_t size;
} layout_t;

#define HERMIT_MALLOC_ALIGN ((size_t)8)

void* malloc(size_t s) {
return _malloc_r(_REENT, s);
}

void* _malloc_r(struct _reent* _r, size_t size) {
uint8_t *ptr = sys_malloc(size + sizeof(layout_t), HERMIT_MALLOC_ALIGN);
if (!ptr)
return NULL;

((layout_t*)ptr)->size = size;
return (void*)(ptr + sizeof(layout_t));
}

void* calloc(size_t nmemb, size_t size) {
return _calloc_r(_REENT, nmemb, size);
}

void* _calloc_r(struct _reent* r, size_t nmemb, size_t size) {
return NULL;
}

void* realloc(void* ptr, size_t size) {
return _realloc_r(_REENT, ptr, size);
}

void* _realloc_r(struct _reent* r, void* ptr, size_t size) {
return NULL;
}

void free(void* ptr) {
_free_r(_REENT, ptr);
}

void _free_r(struct _reent* r, void* ptr) {
if (ptr) {
uint8_t* p = (uint8_t*)ptr - sizeof(layout_t);
sys_free(p, ((layout_t*)p)->size + sizeof(layout_t), HERMIT_MALLOC_ALIGN);
}
}

void runtime_entry(int argc, char** argv, char** env)
{
int ret;

// For some reason, the newlib symbol for _impure_ptr is NULL.
_impure_ptr = &_impure_data;
_REENT_INIT_PTR(_impure_ptr);
__sglue = (struct _glue){ NULL, 3, &__sf[0] };


/* call init function */
__libc_init_array();

Expand Down
5 changes: 5 additions & 0 deletions newlib/libc/sys/hermit/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ int sys_kill(tid_t dest, int signum);
int sys_signal(signal_handler_t handler);
unsigned int sys_rand();

uint8_t *sys_malloc(size_t size, size_t align);
uint8_t *sys_alloc(size_t size, size_t align);
uint8_t *sys_realloc(uint8_t *ptr, size_t size, size_t align, size_t new_size);
void sys_free(uint8_t *ptr, size_t size, size_t align);

struct ucontext;
typedef struct ucontext ucontext_t;

Expand Down

0 comments on commit 986404a

Please sign in to comment.