/** * \brief DL interface bindings * \author Sebastian Sumpf * \date 2014-10-24 * * Wrap Genode's shared library interface onto libc semantics. */ #include #include #include #include extern "C" { #include } using namespace Genode; enum { MAX_ERR = 128 }; static char err_str[MAX_ERR]; char *dlerror(void) { return err_str; } static Shared_object *to_object(void *handle) { return static_cast(handle); } void *dlopen(const char *name, int mode) { int supported = RTLD_LAZY | RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE; /* error on unsupported mode values */ if (mode & ~supported) { snprintf(err_str, MAX_ERR, "Unsupported mode 0x%x\n", mode & ~supported); PERR("dlopen: %s", err_str); return nullptr; } Shared_object *obj = 0; unsigned flags = mode & RTLD_NOW ? Shared_object::NOW : Shared_object::LAZY; flags |= mode & RTLD_NODELETE ? Shared_object::KEEP : 0; try { obj = new (env()->heap()) Shared_object(name, flags); } catch (...) { snprintf(err_str, MAX_ERR, "Unable to open file %s\n", name); } return (void *)obj; } void *dlsym(void *handle, const char *name) { if (handle == nullptr || handle == RTLD_NEXT || handle == RTLD_DEFAULT || handle == RTLD_SELF) { snprintf(err_str, MAX_ERR, "Unsupported handle %p\n", handle); return nullptr; } try { return to_object(handle)->lookup(name); } catch (...) { snprintf(err_str, MAX_ERR, "Symbol '%s' not found\n", name); } return nullptr; } int dladdr(const void *addr, Dl_info *dlip) { try { Address_info info((addr_t)addr); dlip->dli_fname = info.path; dlip->dli_fbase = (void *)info.base; dlip->dli_sname = info.name; dlip->dli_saddr = (void *)info.addr; } catch (...) { snprintf(err_str, MAX_ERR, "Symbol %p at not found", addr); return 0; } return 1; } int dlclose(void *handle) { destroy(env()->heap(), to_object(handle)); return 0; } int dlinfo(void *handle, int request, void *p) { PERR("%s not implemented", __func__); return 0; } dlfunc_t dlfunc(void *handle, const char *name) { PERR("%s not implemented", __func__); return 0; } void *dlvsym(void *handle, const char *name, const char *version) { PERR("%s not implemented", __func__); return nullptr; }