static kern_return_t init_context(KXLDContext *context, u_int ndependencies) { kern_return_t rval = KERN_FAILURE; /* Create an array of objects large enough to hold an object * for every dependency, an interface for each dependency, and a kext. */ rval = kxld_array_init(&context->objects, kxld_object_sizeof(), 2 * ndependencies + 1); require_noerr(rval, finish); rval = kxld_array_init(&context->dependencies, kxld_kext_sizeof(), ndependencies); require_noerr(rval, finish); rval = kxld_dict_init(&context->defined_symbols_by_name, kxld_dict_string_hash, kxld_dict_string_cmp, 0); require_noerr(rval, finish); rval = kxld_dict_init(&context->defined_cxx_symbols_by_value, kxld_dict_kxldaddr_hash, kxld_dict_kxldaddr_cmp, 0); require_noerr(rval, finish); rval = kxld_dict_init(&context->obsolete_symbols_by_name, kxld_dict_string_hash, kxld_dict_string_cmp, 0); require_noerr(rval, finish); rval = kxld_dict_init(&context->vtables_by_name, kxld_dict_string_hash, kxld_dict_string_cmp, 0); require_noerr(rval, finish); rval = KERN_SUCCESS; finish: return rval; }
static kern_return_t create_vtable_index(KXLDKext *kext) { kern_return_t rval = KERN_FAILURE; KXLDVTable *vtable = NULL; u_int i = 0; if (kext->vtable_index_created) { rval = KERN_SUCCESS; goto finish; } /* Map vtable names to the vtable structures */ rval = kxld_dict_init(&kext->vtable_index, kxld_dict_string_hash, kxld_dict_string_cmp, kext->vtables.nitems); require_noerr(rval, finish); for (i = 0; i < kext->vtables.nitems; ++i) { vtable = kxld_array_get_item(&kext->vtables, i); rval = kxld_dict_insert(&kext->vtable_index, vtable->name, vtable); require_noerr(rval, finish); } kext->vtable_index_created = TRUE; rval = KERN_SUCCESS; finish: return rval; }
kern_return_t kxld_create_context(KXLDContext **_context, KXLDAllocateCallback allocate_callback, KXLDLoggingCallback logging_callback, KXLDFlags flags, cpu_type_t cputype, cpu_subtype_t cpusubtype, vm_size_t pagesize __KXLD_KERNEL_UNUSED) { kern_return_t rval = KERN_FAILURE; KXLDContext * context = NULL; KXLDArray * section_order = NULL; #if !KERNEL cpu_type_t * cputype_p = NULL; #endif check(_context); if (isOldInterface) { check(allocate_callback); } check(logging_callback); *_context = NULL; context = kxld_alloc(sizeof(*context)); require_action(context, finish, rval=KERN_RESOURCE_SHORTAGE); bzero(context, sizeof(*context)); context->flags = flags; context->allocate_callback = allocate_callback; context->cputype = cputype; context->cpusubtype = cpusubtype; #if !KERNEL if (pagesize) { kxld_set_cross_link_page_size(pagesize); } #endif /* !KERNEL */ kxld_set_logging_callback(logging_callback); context->kext = kxld_alloc(kxld_kext_sizeof()); require_action(context->kext, finish, rval=KERN_RESOURCE_SHORTAGE); bzero(context->kext, kxld_kext_sizeof()); /* Check if we already have an order array for this arch */ #if KXLD_USER_OR_OBJECT #if KERNEL context->section_order = s_section_order; #else /* In userspace, create the dictionary if it doesn't already exist */ if (!s_order_dict) { s_order_dict = kxld_alloc(sizeof(*s_order_dict)); require_action(s_order_dict, finish, rval=KERN_RESOURCE_SHORTAGE); bzero(s_order_dict, sizeof(*s_order_dict)); rval = kxld_dict_init(s_order_dict, kxld_dict_uint32_hash, kxld_dict_uint32_cmp, 0); require_noerr(rval, finish); } context->section_order = kxld_dict_find(s_order_dict, &cputype); #endif /* KERNEL */ /* Create an order array for this arch if needed */ if (!context->section_order) { section_order = kxld_alloc(sizeof(*section_order)); require_action(section_order, finish, rval=KERN_RESOURCE_SHORTAGE); bzero(section_order, sizeof(*section_order)); #if KERNEL s_section_order = section_order; #else /* In userspace, add the new array to the order dictionary */ cputype_p = kxld_alloc(sizeof(*cputype_p)); require_action(cputype_p, finish, rval=KERN_RESOURCE_SHORTAGE); *cputype_p = cputype; rval = kxld_dict_insert(s_order_dict, cputype_p, section_order); require_noerr(rval, finish); cputype_p = NULL; #endif /* KERNEL */ context->section_order = section_order; section_order = NULL; } #endif /* KXLD_USER_OR_OBJECT */ rval = KERN_SUCCESS; *_context = context; context = NULL; finish: if (context) kxld_destroy_context(context); if (section_order) kxld_free(section_order, sizeof(*section_order)); #if !KERNEL if (cputype_p) kxld_free(cputype_p, sizeof(*cputype_p)); #endif return rval; }