Skip to content

Commit

Permalink
dyld_dlfcn_resolve_symbol: search symbols in the correct object
Browse files Browse the repository at this point in the history
  • Loading branch information
yamt committed Jul 29, 2023
1 parent f92b841 commit 1172fc6
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 37 deletions.
85 changes: 49 additions & 36 deletions libdyld/dyld.c
Original file line number Diff line number Diff line change
Expand Up @@ -856,52 +856,65 @@ symtype_str(enum symtype symtype)
}

int
dyld_resolve_symbol(struct dyld_object *refobj, enum symtype symtype,
const struct name *sym, uint32_t *resultp)
dyld_resolve_symbol_in_obj(struct dyld_object *refobj, struct dyld_object *obj,
enum symtype symtype, const struct name *sym,
uint32_t *resultp)
{
struct dyld *d = refobj->dyld;
struct dyld_object *obj;
enum externtype etype;
if (symtype == SYM_TYPE_FUNC) {
etype = EXTERNTYPE_FUNC;
} else {
etype = EXTERNTYPE_GLOBAL;
}
LIST_FOREACH(obj, &d->objs, q) {
const struct module *m = obj->module;
/* XXX dumb linear search */
uint32_t i;
for (i = 0; i < m->nexports; i++) {
const struct export *ex = &m->exports[i];
const struct exportdesc *ed = &ex->desc;
if (etype != ed->type ||
compare_name(sym, &ex->name)) {
const struct module *m = obj->module;
/* XXX dumb linear search */
uint32_t i;
for (i = 0; i < m->nexports; i++) {
const struct export *ex = &m->exports[i];
const struct exportdesc *ed = &ex->desc;
if (etype != ed->type || compare_name(sym, &ex->name)) {
continue;
}
const struct instance *inst = obj->instance;
uint32_t addr;
if (symtype == SYM_TYPE_FUNC) {
const struct funcinst *fi =
VEC_ELEM(inst->funcs, ed->idx);
addr = dyld_register_funcinst(d, obj, fi);
} else {
struct globalinst *gi =
VEC_ELEM(inst->globals, ed->idx);
if (!is_global_type_i32_const(gi->type)) {
continue;
}
const struct instance *inst = obj->instance;
uint32_t addr;
if (symtype == SYM_TYPE_FUNC) {
const struct funcinst *fi =
VEC_ELEM(inst->funcs, ed->idx);
addr = dyld_register_funcinst(d, obj, fi);
} else {
struct globalinst *gi =
VEC_ELEM(inst->globals, ed->idx);
if (!is_global_type_i32_const(gi->type)) {
continue;
}
/*
* TODO: consult WASM_DYLINK_EXPORT_INFO
* subsection to check TLS.
* for TLS, use __tls_base, not __memory_base.
*/
addr = global_get_i32(gi) + obj->memory_base;
}
xlog_trace("dyld: resolved %s %.*s %.*s -> %.*s idx "
"%" PRIu32 " addr %08" PRIx32,
symtype_str(symtype), CSTR(refobj->name),
CSTR(sym), CSTR(obj->name), ed->idx, addr);
*resultp = addr;
/*
* TODO: consult WASM_DYLINK_EXPORT_INFO
* subsection to check TLS.
* for TLS, use __tls_base, not __memory_base.
*/
addr = global_get_i32(gi) + obj->memory_base;
}
xlog_trace("dyld: resolved %s %.*s %.*s -> %.*s idx "
"%" PRIu32 " addr %08" PRIx32,
symtype_str(symtype), CSTR(refobj->name), CSTR(sym),
CSTR(obj->name), ed->idx, addr);
*resultp = addr;
return 0;
}
return ENOENT;
}

int
dyld_resolve_symbol(struct dyld_object *refobj, enum symtype symtype,
const struct name *sym, uint32_t *resultp)
{
struct dyld *d = refobj->dyld;
struct dyld_object *obj;
LIST_FOREACH(obj, &d->objs, q) {
int ret = dyld_resolve_symbol_in_obj(refobj, obj, symtype, sym,
resultp);
if (ret == 0) {
return 0;
}
}
Expand Down
10 changes: 9 additions & 1 deletion libdyld/dyld_dlfcn.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,16 @@ dyld_dlfcn_resolve_symbol(struct exec_context *ctx, struct host_instance *hi,
struct name name;
name.data = vp;
name.nbytes = namelen;

/*
* Note: this implementation only searches the symbols in
* the object itself.
* Typical dlsym implementions look at symbols in dependency
* libraries as well.
*/
uint32_t addr;
ret = dyld_resolve_symbol(dobj->obj, type, &name, &addr);
ret = dyld_resolve_symbol_in_obj(LIST_FIRST(&d->objs), dobj->obj, type,
&name, &addr);
if (ret != 0) {
xlog_trace("dyld: dyld:resolve_symbol dyld_resolve_symbol "
"failed for %.*s with %d",
Expand Down
3 changes: 3 additions & 0 deletions libdyld/dyld_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ int dyld_execute_all_init_funcs(struct dyld *d, struct dyld_object *start);

int dyld_resolve_symbol(struct dyld_object *refobj, enum symtype symtype,
const struct name *sym, uint32_t *resultp);
int dyld_resolve_symbol_in_obj(struct dyld_object *refobj,
struct dyld_object *obj, enum symtype symtype,
const struct name *sym, uint32_t *resultp);
int dyld_search_and_load_object_from_file(struct dyld *d,
const struct name *name,
struct dyld_object **objp);

0 comments on commit 1172fc6

Please sign in to comment.