Skip to content

Commit

Permalink
wip dyld
Browse files Browse the repository at this point in the history
  • Loading branch information
yamt committed Jul 16, 2023
1 parent 58dcb2a commit 79cb6b1
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 15 deletions.
101 changes: 88 additions & 13 deletions lib/dyld.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#define _DARWIN_C_SOURCE /* snprintf */

#include <errno.h>
#include <limits.h>
#include <stdio.h>
Expand All @@ -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)
{
Expand Down Expand Up @@ -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;
}
19 changes: 17 additions & 2 deletions lib/dyld.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
#include <stdint.h>

#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;
Expand All @@ -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);

0 comments on commit 79cb6b1

Please sign in to comment.