image_id preload_image(char const* path) { if (path == NULL) return B_BAD_VALUE; KTRACE("rld: preload_image(\"%s\")", path); image_t *image = NULL; status_t status = load_image(path, B_LIBRARY_IMAGE, NULL, NULL, &image); if (status < B_OK) { KTRACE("rld: preload_image(\"%s\") failed to load container: %s", path, strerror(status)); return status; } if (image->find_undefined_symbol == NULL) image->find_undefined_symbol = find_undefined_symbol_global; status = load_dependencies(image); if (status < B_OK) goto err; set_image_flags_recursively(image, RTLD_GLOBAL); status = relocate_dependencies(image); if (status < B_OK) goto err; status = add_preloaded_image(image); if (status < B_OK) goto err; inject_runtime_loader_api(image); remap_images(); init_dependencies(image, true); // if the image contains an add-on, register it runtime_loader_add_on* addOnStruct; if (find_symbol(image, SymbolLookupInfo("__gRuntimeLoaderAddOn", B_SYMBOL_TYPE_DATA), (void**)&addOnStruct) == B_OK) { add_add_on(image, addOnStruct); } KTRACE("rld: preload_image(\"%s\") done: id: %" B_PRId32, path, image->id); return image->id; err: KTRACE("rld: preload_image(\"%s\") failed: %s", path, strerror(status)); dequeue_loaded_image(image); delete_image(image); return status; }
DLL_EXPORT int ECDHEMakeKey(char *x, char *y, char *z, char *k) { ecc_key ecc_dhe; init_dependencies(); int res = ecc_make_key_ex(NULL, find_prng("sprng"), &ecc_dhe, &ecc256); if (!res) { mp_toradix(ecc_dhe.pubkey.x, x, 16); mp_toradix(ecc_dhe.pubkey.y, y, 16); mp_toradix(ecc_dhe.pubkey.z, z, 16); mp_toradix(ecc_dhe.k, k, 16); ecc_free(&ecc_dhe); } }
image_id load_library(char const *path, uint32 flags, bool addOn, void** _handle) { image_t *image = NULL; image_type type = (addOn ? B_ADD_ON_IMAGE : B_LIBRARY_IMAGE); status_t status; if (path == NULL && addOn) return B_BAD_VALUE; KTRACE("rld: load_library(\"%s\", %#" B_PRIx32 ", %d)", path, flags, addOn); rld_lock(); // for now, just do stupid simple global locking // have we already loaded this library? // Checking it at this stage saves loading its dependencies again if (!addOn) { // a NULL path is fine -- it means the global scope shall be opened if (path == NULL) { *_handle = RLD_GLOBAL_SCOPE; rld_unlock(); return 0; } image = find_loaded_image_by_name(path, APP_OR_LIBRARY_TYPE); if (image != NULL && (flags & RTLD_GLOBAL) != 0) set_image_flags_recursively(image, RTLD_GLOBAL); if (image) { atomic_add(&image->ref_count, 1); rld_unlock(); KTRACE("rld: load_library(\"%s\"): already loaded: %" B_PRId32, path, image->id); *_handle = image; return image->id; } } status = load_image(path, type, NULL, NULL, &image); if (status < B_OK) { rld_unlock(); KTRACE("rld: load_library(\"%s\") failed to load container: %s", path, strerror(status)); return status; } if (image->find_undefined_symbol == NULL) { if (addOn) image->find_undefined_symbol = find_undefined_symbol_add_on; else image->find_undefined_symbol = find_undefined_symbol_global; } status = load_dependencies(image); if (status < B_OK) goto err; // If specified, set the RTLD_GLOBAL flag recursively on this image and all // dependencies. If not specified, we temporarily set // RFLAG_USE_FOR_RESOLVING so that the dependencies will correctly be used // for undefined symbol resolution. if ((flags & RTLD_GLOBAL) != 0) set_image_flags_recursively(image, RTLD_GLOBAL); else set_image_flags_recursively(image, RFLAG_USE_FOR_RESOLVING); status = relocate_dependencies(image); if (status < B_OK) goto err; if ((flags & RTLD_GLOBAL) == 0) clear_image_flags_recursively(image, RFLAG_USE_FOR_RESOLVING); remap_images(); init_dependencies(image, true); rld_unlock(); KTRACE("rld: load_library(\"%s\") done: id: %" B_PRId32, path, image->id); *_handle = image; return image->id; err: KTRACE("rld: load_library(\"%s\") failed: %s", path, strerror(status)); dequeue_loaded_image(image); delete_image(image); rld_unlock(); return status; }
image_id load_program(char const *path, void **_entry) { status_t status; image_t *image; KTRACE("rld: load_program(\"%s\")", path); rld_lock(); // for now, just do stupid simple global locking preload_images(); TRACE(("rld: load %s\n", path)); status = load_image(path, B_APP_IMAGE, NULL, NULL, &gProgramImage); if (status < B_OK) goto err; if (gProgramImage->find_undefined_symbol == NULL) gProgramImage->find_undefined_symbol = find_undefined_symbol_global; status = load_dependencies(gProgramImage); if (status < B_OK) goto err; // Set RTLD_GLOBAL on all libraries including the program. // This results in the desired symbol resolution for dlopen()ed libraries. set_image_flags_recursively(gProgramImage, RTLD_GLOBAL); status = relocate_dependencies(gProgramImage); if (status < B_OK) goto err; inject_runtime_loader_api(gProgramImage); remap_images(); init_dependencies(gProgramImage, true); // Since the images are initialized now, we no longer should use our // getenv(), but use the one from libroot.so find_symbol_breadth_first(gProgramImage, SymbolLookupInfo("getenv", B_SYMBOL_TYPE_TEXT), &image, (void**)&gGetEnv); if (gProgramImage->entry_point == 0) { status = B_NOT_AN_EXECUTABLE; goto err; } *_entry = (void *)(gProgramImage->entry_point); rld_unlock(); gProgramLoaded = true; KTRACE("rld: load_program(\"%s\") done: entry: %p, id: %" B_PRId32 , path, *_entry, gProgramImage->id); return gProgramImage->id; err: KTRACE("rld: load_program(\"%s\") failed: %s", path, strerror(status)); delete_image(gProgramImage); if (report_errors()) { // send error message gErrorMessage.AddInt32("error", status); gErrorMessage.SetDeliveryInfo(gProgramArgs->error_token, -1, 0, find_thread(NULL)); _kern_write_port_etc(gProgramArgs->error_port, 'KMSG', gErrorMessage.Buffer(), gErrorMessage.ContentSize(), 0, 0); } _kern_loading_app_failed(status); rld_unlock(); return status; }