static gpointer _g_module_symbol (gpointer handle, const gchar *symbol_name) { image_id id; status_t status; image_info info; int32 type, name_len; void *p; gchar *msg, name[256]; gint n, l; id = (image_id) handle; status = get_image_info (id, &info); if (status != B_OK) { msg = g_strdup_printf ("failed to get_image_info(): %s", strerror (status)); g_module_set_error (msg); g_free (msg); return NULL; } l = strlen (symbol_name); name_len = 256; type = B_SYMBOL_TYPE_ANY; n = 0; status = get_nth_image_symbol (id, n, name, &name_len, &type, &p); while (status == B_OK) { if (p && strncmp (name, symbol_name, l) == 0) return p; if (strcmp (name, "_end") == 0) { msg = g_strdup_printf ("unmatched symbol name `%s'", symbol_name); g_module_set_error (msg); g_free (msg); return NULL; } name_len = 256; type = B_SYMBOL_TYPE_ANY; n++; status = get_nth_image_symbol (id, n, name, &name_len, &type, &p); } msg = g_strdup_printf ("failed to get_image_symbol(%s): %s", symbol_name, strerror (status)); g_module_set_error (msg); g_free (msg); return NULL; }
int dladdr(void *addr, Dl_info *info) { // TODO: This can be implemented more efficiently in the runtime loader. // get_library_symbol() already has the code doing that. char curSymName[NAME_MAX]; static char symName[NAME_MAX]; static char imageName[MAXPATHLEN]; void *symLocation; int32 cookie; int32 symType, symNameLength; uint32 symIndex; image_info imageInfo; if (info == NULL) return 0; imageName[0] = '\0'; symName[0] = '\0'; info->dli_fname = imageName; info->dli_saddr = NULL; info->dli_sname = symName; cookie = 0; while (get_next_image_info(0, &cookie, &imageInfo) == B_OK) { // check if the image holds the symbol if ((addr_t)addr >= (addr_t)imageInfo.text && (addr_t)addr < (addr_t)imageInfo.text + imageInfo.text_size) { strlcpy(imageName, imageInfo.name, MAXPATHLEN); info->dli_fbase = imageInfo.text; symIndex = 0; symNameLength = NAME_MAX; while (get_nth_image_symbol(imageInfo.id, symIndex, curSymName, &symNameLength, &symType, &symLocation) == B_OK) { // check if symbol is the nearest until now if (symLocation <= addr && symLocation >= info->dli_saddr) { strlcpy(symName, curSymName, NAME_MAX); info->dli_saddr = symLocation; // stop here if exact match if (info->dli_saddr == addr) return 1; } symIndex++; symNameLength = NAME_MAX; } break; } } if (info->dli_saddr != NULL) return 1; return 0; }
main(int argc, char **argv) { char *path, *symname; image_id img; int32 n = 0; volatile int32 symnamelen, symtype; void *symloc; if (argc != 2) { printf("more args, bozo\n"); exit(1); } path = (void *) malloc((size_t) 2048); symname = (void *) malloc((size_t) 2048); if (!getcwd(path, 2048)) { printf("aiee!\n"); exit(1); } if (!strcat(path, "/")) {printf("naah.\n"); exit (1); } /*printf("%s\n",path);*/ if ('/' != argv[1][0]) { if (!strcat(path, argv[1])) { printf("feh1\n"); exit(1); } } else { if (!strcpy(path, argv[1])) { printf("gah!\n"); exit(1); } } /*printf("%s\n",path);*/ img = load_add_on(path); if (B_ERROR == img) {printf("Couldn't load_add_on() %s.\n", path); exit(2); } symnamelen=2047; while (B_BAD_INDEX != get_nth_image_symbol(img, n++, symname, &symnamelen, &symtype, &symloc)) { printf("%s |%s |GLOB %Lx | \n", symname, ((B_SYMBOL_TYPE_ANY == symtype) || (B_SYMBOL_TYPE_TEXT == symtype)) ? "FUNC" : "VAR ", symloc); symnamelen=2047; } printf("number of symbols: %d\n", n); if (B_ERROR == unload_add_on(img)) {printf("err while closing.\n"); exit(3); } free(path); return(0); }
status_t CamRoster::LoadExternalAddons() { PRINT((CH "()" CT)); // FIXME return B_ERROR; int32 index; int32 sclass; status_t err; CamDeviceAddon *addon; status_t (*get_webcam_addon_func)(WebCamMediaAddOn* webcam, CamDeviceAddon **addon); for (index = 0; get_nth_image_symbol(fAddon->ImageID(), index, NULL, NULL, &sclass, (void **)&get_webcam_addon_func) == B_OK; index++) { PRINT((CH ": got sym" CT)); // if (sclass != B_SYMBOL_TYPE_TEXT) // continue; err = (*get_webcam_addon_func)(fAddon, &addon); PRINT((CH ": Loaded addon '%s' with error 0x%08lx" CT, (err>0)?NULL:addon->BrandName(), err)); } return B_OK; }