From 79cb6b1d139c35000f7fdc52105b3d0757ddc554 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 13 Jul 2023 01:04:57 +0900 Subject: [PATCH] wip dyld --- lib/dyld.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++------- lib/dyld.h | 19 ++++++++-- 2 files changed, 105 insertions(+), 15 deletions(-) diff --git a/lib/dyld.c b/lib/dyld.c index df9a171f..6874e7bb 100644 --- a/lib/dyld.c +++ b/lib/dyld.c @@ -1,3 +1,5 @@ +#define _DARWIN_C_SOURCE /* snprintf */ + #include #include #include @@ -6,39 +8,45 @@ #include "dyld.h" #include "dylink_type.h" #include "fileio.h" +#include "list.h" #include "load_context.h" #include "module.h" #include "type.h" #include "util.h" #include "xlog.h" +int dyld_load_object_from_file(struct dyld *d, const char *name); + void dyld_init(struct dyld *d) { memset(d, 0, sizeof(*d)); + LIST_HEAD_INIT(&d->objs); } int -dyld_load_needed_objects(struct dyld *d, struct dyld_object *obj) +dyld_load_needed_objects(struct dyld *d) { - struct dylink_needs *needs = &obj->module->dylink->needs; - uint32_t i; int ret = 0; - for (i = 0; i < needs->count; i++) { - const struct name *name = &needs->names[i]; - char filename[PATH_MAX]; - snprintf(filename, sizeof(filename), "%.*s", CSTR(name)); - ret = dyld_load_object_from_file(d, filename); - if (ret != 0) { - goto fail; + struct dyld_object *obj; + LIST_FOREACH(obj, &d->objs, q) { + const struct dylink_needs *needs = &obj->module->dylink->needs; + uint32_t i; + for (i = 0; i < needs->count; i++) { + const struct name *name = &needs->names[i]; + char filename[PATH_MAX]; + snprintf(filename, sizeof(filename), "%.*s", + CSTR(name)); + ret = dyld_load_object_from_file(d, filename); + if (ret != 0) { + goto fail; + } } } fail: return ret; } -int dyld_load_object_from_file(struct dyld *d, const char *name); - int dyld_load_object_from_file(struct dyld *d, const char *name) { @@ -66,7 +74,74 @@ dyld_load_object_from_file(struct dyld *d, const char *name) ret = EINVAL; goto fail; } - ret = dyld_load_needed_objects(d, obj); + LIST_INSERT_TAIL(&d->objs, obj, q); +fail: + return ret; +} + +static uint32_t +align_up(uint32_t v, uint32_t palign) +{ + uint32_t align = 1 << palign; + uint32_t mask = align - 1; + return (v + mask) & ~mask; +} + +int +dyld_allocate_memory(struct dyld *d) +{ + uint32_t stack_size = 16 * 1024; /* XXX TODO guess from main obj */ + + d->memory_base += stack_size; + + struct dyld_object *obj; + LIST_FOREACH(obj, &d->objs, q) { + const struct dylink_mem_info *minfo = + &obj->module->dylink->mem_info; + d->memory_base = + align_up(d->memory_base, minfo->memoryalignment); + obj->memory_base = d->memory_base; + d->memory_base += minfo->memorysize; + } + return 0; +} + +int +dyld_allocate_table(struct dyld *d) +{ + d->table_base += 1; /* do not use the first one */ + + struct dyld_object *obj; + LIST_FOREACH(obj, &d->objs, q) { + const struct dylink_mem_info *minfo = + &obj->module->dylink->mem_info; + d->table_base = align_up(d->table_base, minfo->tablealignment); + obj->table_base = d->table_base; + d->table_base += minfo->tablesize; + } + return 0; +} + +int +dyld_load_main_object_from_file(struct dyld *d, const char *name) +{ + int ret; + ret = dyld_load_object_from_file(d, name); + if (ret != 0) { + goto fail; + } + ret = dyld_load_needed_objects(d); + if (ret != 0) { + goto fail; + } + ret = dyld_allocate_memory(d); + if (ret != 0) { + goto fail; + } + ret = dyld_allocate_table(d); + if (ret != 0) { + goto fail; + } fail: return ret; } diff --git a/lib/dyld.h b/lib/dyld.h index b6de0f60..25f1444f 100644 --- a/lib/dyld.h +++ b/lib/dyld.h @@ -1,5 +1,14 @@ #include +#include "list.h" +#include "type.h" + +struct dyld_sym { + const struct name *name; + enum importtype type; + uint32_t idx; +}; + struct dyld_plt { struct finst *finst; struct tableinst *tableinst; @@ -15,18 +24,24 @@ struct dyld_object { struct module *module; struct instance *instance; - struct dyld_object *next; + LIST_ENTRY(struct dyld_object) q; }; struct dyld { uint32_t memory_base; uint32_t table_base; + + struct memtype mt; struct meminst *meminst; + + struct tabletype tt; struct tableinst *tableinst; - struct dyld_object *objs; + + LIST_HEAD(struct dyld_object) objs; }; #if 0 int dyld_resolve_symbol(struct dyld_object *refobj, enum importtype type, const struct name *name, void **resultp); #endif +int dyld_load_main_object_from_file(struct dyld *d, const char *name);