Lines Matching defs:obj

90 static int do_search_info(const Obj_Entry *obj, int, struct dl_serinfo *);
135 static int relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
165 static bool obj_resolve_origin(Obj_Entry *obj);
172 static void rtld_fill_dl_phdr_info(const Obj_Entry *obj,
359 Obj_Entry *last_interposer, *obj, *preload_tail;
698 TAILQ_FOREACH(obj, &obj_list, next) {
699 if (obj->marker)
701 if (obj->z_interpose && obj != obj_main) {
702 objlist_put_after(&list_main, last_interposer, obj);
703 last_interposer = obj;
705 objlist_push_tail(&list_main, obj);
707 obj->refcount++;
735 allocate_tls_offset(entry->obj);
819 TAILQ_FOREACH(obj, &obj_list, next) {
820 if (obj->marker)
822 if (ld_loadfltr || obj->z_loadfltr)
823 load_filtees(obj, 0, &lockstate);
826 dbg("enforcing main obj relro");
841 rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def)
846 ptr = (void *)make_function_pointer(def, obj);
856 _rtld_bind(Obj_Entry *obj, Elf_Size reloff)
868 if (obj->pltrel)
869 rel = (const Elf_Rel *) ((caddr_t) obj->pltrel + reloff);
871 rel = (const Elf_Rel *) ((caddr_t) obj->pltrela + reloff);
873 where = (Elf_Addr *) (obj->relocbase + rel->r_offset);
874 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, SYMLOOK_IN_PLT,
884 defobj->strtab + def->st_name, basename(obj->path),
894 target = reloc_jmpslot(where, target, defobj, obj, rel);
950 origin_subst_one(Obj_Entry *obj, char *real, const char *kw,
975 if (subst_count == 0 || (obj != NULL && !obj_resolve_origin(obj)))
977 if (obj != NULL)
978 subst = obj->origin_path;
1015 origin_subst(Obj_Entry *obj, char *real)
1019 if (obj == NULL || !trust)
1027 res1 = origin_subst_one(obj, real, "$ORIGIN", NULL, false);
1051 digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
1055 Needed_Entry **needed_tail = &obj->needed;
1056 Needed_Entry **needed_filtees_tail = &obj->needed_filtees;
1057 Needed_Entry **needed_aux_filtees_tail = &obj->needed_aux_filtees;
1068 obj->bind_now = false;
1069 dynp = obj->dynamic;
1076 obj->rel = (const Elf_Rel *) (obj->relocbase + dynp->d_un.d_ptr);
1080 obj->relsize = dynp->d_un.d_val;
1088 obj->pltrel = (const Elf_Rel *)
1089 (obj->relocbase + dynp->d_un.d_ptr);
1093 obj->pltrelsize = dynp->d_un.d_val;
1097 obj->rela = (const Elf_Rela *) (obj->relocbase + dynp->d_un.d_ptr);
1101 obj->relasize = dynp->d_un.d_val;
1114 obj->symtab = (const Elf_Sym *)
1115 (obj->relocbase + dynp->d_un.d_ptr);
1123 obj->strtab = (const char *) (obj->relocbase + dynp->d_un.d_ptr);
1127 obj->strsize = dynp->d_un.d_val;
1131 obj->verneed = (const Elf_Verneed *) (obj->relocbase +
1136 obj->verneednum = dynp->d_un.d_val;
1140 obj->verdef = (const Elf_Verdef *) (obj->relocbase +
1145 obj->verdefnum = dynp->d_un.d_val;
1149 obj->versyms = (const Elf_Versym *)(obj->relocbase +
1155 hashtab = (const Elf_Hashelt *)(obj->relocbase +
1157 obj->nbuckets = hashtab[0];
1158 obj->nchains = hashtab[1];
1159 obj->buckets = hashtab + 2;
1160 obj->chains = obj->buckets + obj->nbuckets;
1161 obj->valid_hash_sysv = obj->nbuckets > 0 && obj->nchains > 0 &&
1162 obj->buckets != NULL;
1168 hashtab = (const Elf_Hashelt *)(obj->relocbase +
1170 obj->nbuckets_gnu = hashtab[0];
1171 obj->symndx_gnu = hashtab[1];
1174 obj->maskwords_bm_gnu = nmaskwords - 1;
1175 obj->shift2_gnu = hashtab[3];
1176 obj->bloom_gnu = (Elf_Addr *) (hashtab + 4);
1177 obj->buckets_gnu = hashtab + 4 + bloom_size32;
1178 obj->chain_zero_gnu = obj->buckets_gnu + obj->nbuckets_gnu -
1179 obj->symndx_gnu;
1181 obj->valid_hash_gnu = powerof2(nmaskwords) &&
1182 obj->nbuckets_gnu > 0 && obj->buckets_gnu != NULL;
1187 if (!obj->rtld) {
1190 nep->obj = NULL;
1199 if (!obj->rtld) {
1202 nep->obj = NULL;
1211 if (!obj->rtld) {
1214 nep->obj = NULL;
1223 obj->pltgot = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr);
1227 obj->textrel = true;
1231 obj->symbolic = true;
1251 obj->init = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
1255 obj->preinit_array = (Elf_Addr)(obj->relocbase + dynp->d_un.d_ptr);
1259 obj->preinit_array_num = dynp->d_un.d_val / sizeof(Elf_Addr);
1263 obj->init_array = (Elf_Addr)(obj->relocbase + dynp->d_un.d_ptr);
1267 obj->init_array_num = dynp->d_un.d_val / sizeof(Elf_Addr);
1271 obj->fini = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
1275 obj->fini_array = (Elf_Addr)(obj->relocbase + dynp->d_un.d_ptr);
1279 obj->fini_array_num = dynp->d_un.d_val / sizeof(Elf_Addr);
1297 obj->z_origin = true;
1299 obj->symbolic = true;
1301 obj->textrel = true;
1303 obj->bind_now = true;
1305 obj->static_tls = true;
1309 obj->local_gotno = dynp->d_un.d_val;
1313 obj->symtabno = dynp->d_un.d_val;
1317 obj->gotsym = dynp->d_un.d_val;
1327 obj->glink = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
1333 obj->z_noopen = true;
1335 obj->z_origin = true;
1337 obj->z_global = true;
1339 obj->bind_now = true;
1341 obj->z_nodelete = true;
1343 obj->z_loadfltr = true;
1345 obj->z_interpose = true;
1347 obj->z_nodeflib = true;
1349 obj->z_pie = true;
1361 obj->traced = false;
1364 obj->pltrela = (const Elf_Rela *) obj->pltrel;
1365 obj->pltrel = NULL;
1366 obj->pltrelasize = obj->pltrelsize;
1367 obj->pltrelsize = 0;
1371 if (obj->valid_hash_sysv)
1372 obj->dynsymcount = obj->nchains;
1373 else if (obj->valid_hash_gnu) {
1374 obj->dynsymcount = 0;
1375 for (bkt = 0; bkt < obj->nbuckets_gnu; bkt++) {
1376 if (obj->buckets_gnu[bkt] == 0)
1378 hashval = &obj->chain_zero_gnu[obj->buckets_gnu[bkt]];
1380 obj->dynsymcount++;
1383 obj->dynsymcount += obj->symndx_gnu;
1388 obj_resolve_origin(Obj_Entry *obj)
1391 if (obj->origin_path != NULL)
1393 obj->origin_path = xmalloc(PATH_MAX);
1394 return (rtld_dirname_abs(obj->path, obj->origin_path) != -1);
1398 digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath,
1402 if (obj->z_origin && !obj_resolve_origin(obj))
1406 obj->runpath = (char *)obj->strtab + dyn_runpath->d_un.d_val;
1407 obj->runpath = origin_subst(obj, obj->runpath);
1409 obj->rpath = (char *)obj->strtab + dyn_rpath->d_un.d_val;
1410 obj->rpath = origin_subst(obj, obj->rpath);
1413 object_add_name(obj, obj->strtab + dyn_soname->d_un.d_val);
1418 digest_dynamic(Obj_Entry *obj, int early)
1424 digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname, &dyn_runpath);
1425 return (digest_dynamic2(obj, dyn_rpath, dyn_soname, dyn_runpath));
1437 Obj_Entry *obj;
1443 obj = obj_new();
1448 obj->phdr = phdr;
1449 obj->phsize = ph->p_memsz;
1450 obj->relocbase = (caddr_t)phdr - ph->p_vaddr;
1454 obj->stack_flags = PF_X | PF_R | PF_W;
1460 obj->interp = (const char *)(ph->p_vaddr + obj->relocbase);
1465 obj->vaddrbase = trunc_page(ph->p_vaddr);
1466 obj->mapbase = obj->vaddrbase + obj->relocbase;
1467 obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) -
1468 obj->vaddrbase;
1470 obj->mapsize = round_page(ph->p_vaddr + ph->p_memsz) -
1471 obj->vaddrbase;
1477 obj->dynamic = (const Elf_Dyn *)(ph->p_vaddr + obj->relocbase);
1481 obj->tlsindex = 1;
1482 obj->tlssize = ph->p_memsz;
1483 obj->tlsalign = ph->p_align;
1484 obj->tlsinitsize = ph->p_filesz;
1485 obj->tlsinit = (void*)(ph->p_vaddr + obj->relocbase);
1489 obj->stack_flags = ph->p_flags;
1493 obj->relro_page = obj->relocbase + trunc_page(ph->p_vaddr);
1494 obj->relro_size = round_page(ph->p_memsz);
1498 note_start = (Elf_Addr)obj->relocbase + ph->p_vaddr;
1500 digest_notes(obj, note_start, note_end);
1509 obj->entry = entry;
1510 return obj;
1514 digest_notes(Obj_Entry *obj, Elf_Addr note_start, Elf_Addr note_end)
1539 obj->osrel = *(const int32_t *)(p);
1540 dbg("note osrel %d", obj->osrel);
1544 obj->crt_no_init = true;
1554 Obj_Entry *obj;
1556 TAILQ_FOREACH(obj, &obj_list, next) {
1557 if (obj == (Obj_Entry *) handle)
1561 if (obj == NULL || obj->refcount == 0 || obj->dl_refcount == 0) {
1565 return obj;
1573 donelist_check(DoneList *dlp, const Obj_Entry *obj)
1578 if (dlp->objs[i] == obj)
1587 dlp->objs[dlp->num_used++] = obj;
1778 *defobj_out = cache[symnum].obj;
1829 cache[symnum].obj = defobj;
2023 for (needed = elm->obj->needed; needed != NULL; needed = needed->next) {
2024 if (needed->obj == NULL || donelist_check(&donelist, needed->obj))
2026 objlist_push_tail(&needed->obj->dldags, root);
2027 objlist_push_tail(&root->dagmembers, needed->obj);
2042 globallist_curr(const Obj_Entry *obj)
2046 if (obj == NULL)
2048 if (!obj->marker)
2049 return (__DECONST(Obj_Entry *, obj));
2050 obj = TAILQ_PREV(obj, obj_entry_q, next);
2055 globallist_next(const Obj_Entry *obj)
2059 obj = TAILQ_NEXT(obj, next);
2060 if (obj == NULL)
2062 if (!obj->marker)
2063 return (__DECONST(Obj_Entry *, obj));
2069 hold_object(Obj_Entry *obj)
2072 obj->holdcount++;
2076 unhold_object(Obj_Entry *obj)
2079 assert(obj->holdcount > 0);
2080 if (--obj->holdcount == 0 && obj->unholdfree)
2081 release_object(obj);
2088 Obj_Entry *obj;
2101 obj = elm->obj;
2102 if (obj == NULL)
2104 if (obj->z_nodelete && !obj->ref_nodel) {
2105 dbg("obj %s -z nodelete", obj->path);
2106 init_dag(obj);
2107 ref_dag(obj);
2108 obj->ref_nodel = true;
2110 if (obj->z_global && objlist_find(&list_global, obj) == NULL) {
2111 dbg("obj %s -z global", obj->path);
2112 objlist_push_tail(&list_global, obj);
2113 init_dag(obj);
2119 parse_rtld_phdr(Obj_Entry *obj)
2124 obj->stack_flags = PF_X | PF_R | PF_W;
2125 for (ph = obj->phdr; (const char *)ph < (const char *)obj->phdr +
2126 obj->phsize; ph++) {
2129 obj->stack_flags = ph->p_flags;
2132 obj->relro_page = obj->relocbase +
2134 obj->relro_size = round_page(ph->p_memsz);
2137 note_start = (Elf_Addr)obj->relocbase + ph->p_vaddr;
2139 digest_notes(obj, note_start, note_end);
2279 if (needed->obj != NULL)
2280 initlist_add_objects(needed->obj, needed->obj, list);
2284 * Scan all of the DAGs rooted in the range of objects from "obj" to
2293 initlist_add_objects(Obj_Entry *obj, Obj_Entry *tail, Objlist *list)
2297 if (obj->init_scanned || obj->init_done)
2299 obj->init_scanned = true;
2302 nobj = globallist_next(obj);
2303 if (nobj != NULL && obj != tail)
2307 if (obj->needed != NULL)
2308 initlist_add_neededs(obj->needed, list);
2309 if (obj->needed_filtees != NULL)
2310 initlist_add_neededs(obj->needed_filtees, list);
2311 if (obj->needed_aux_filtees != NULL)
2312 initlist_add_neededs(obj->needed_aux_filtees, list);
2315 objlist_push_tail(list, obj);
2318 if ((obj->fini != (Elf_Addr)NULL || obj->fini_array != (Elf_Addr)NULL)
2319 && !obj->on_fini_list) {
2320 objlist_push_head(&list_fini, obj);
2321 obj->on_fini_list = true;
2335 if (needed->obj != NULL) {
2336 dlclose_locked(needed->obj, lockstate);
2337 needed->obj = NULL;
2347 unload_filtees(Obj_Entry *obj, RtldLockState *lockstate)
2350 free_needed_filtees(obj->needed_filtees, lockstate);
2351 obj->needed_filtees = NULL;
2352 free_needed_filtees(obj->needed_aux_filtees, lockstate);
2353 obj->needed_aux_filtees = NULL;
2354 obj->filtees_loaded = false;
2358 load_filtee1(Obj_Entry *obj, Needed_Entry *needed, int flags,
2363 needed->obj = dlopen_object(obj->strtab + needed->name, -1, obj,
2364 flags, ((ld_loadfltr || obj->z_loadfltr) ? RTLD_NOW : RTLD_LAZY) |
2370 load_filtees(Obj_Entry *obj, int flags, RtldLockState *lockstate)
2374 if (!obj->filtees_loaded) {
2375 load_filtee1(obj, obj->needed_filtees, flags, lockstate);
2376 load_filtee1(obj, obj->needed_aux_filtees, flags, lockstate);
2377 obj->filtees_loaded = true;
2382 process_needed(Obj_Entry *obj, Needed_Entry *needed, int flags)
2387 obj1 = needed->obj = load_object(obj->strtab + needed->name, -1, obj,
2403 Obj_Entry *obj;
2405 for (obj = first; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
2406 if (obj->marker)
2408 if (process_needed(obj, obj->needed, flags) == -1)
2418 Obj_Entry *obj;
2431 obj = load_object(p, -1, NULL, 0);
2432 if (obj == NULL)
2434 obj->z_interpose = true;
2462 Obj_Entry *obj;
2469 TAILQ_FOREACH(obj, &obj_list, next) {
2470 if (obj->marker || obj->doomed)
2472 if (object_match_name(obj, name))
2473 return (obj);
2516 TAILQ_FOREACH(obj, &obj_list, next) {
2517 if (obj->marker || obj->doomed)
2519 if (obj->ino == sb.st_ino && obj->dev == sb.st_dev)
2522 if (obj != NULL && name != NULL) {
2523 object_add_name(obj, name);
2526 return obj;
2535 obj = do_load_object(fd, name, path, &sb, flags);
2536 if (obj == NULL)
2540 return obj;
2547 Obj_Entry *obj;
2565 obj = map_object(fd, printable_path(path), sbp);
2566 if (obj == NULL)
2574 object_add_name(obj, name);
2575 obj->path = path;
2576 if (!digest_dynamic(obj, 0))
2578 dbg("%s valid_hash_sysv %d valid_hash_gnu %d dynsymcount %d", obj->path,
2579 obj->valid_hash_sysv, obj->valid_hash_gnu, obj->dynsymcount);
2580 if (obj->z_pie && (flags & RTLD_LO_TRACE) == 0) {
2581 dbg("refusing to load PIE executable \"%s\"", obj->path);
2582 _rtld_error("Cannot load PIE binary %s as DSO", obj->path);
2585 if (obj->z_noopen && (flags & (RTLD_LO_DLOPEN | RTLD_LO_TRACE)) ==
2587 dbg("refusing to load non-loadable \"%s\"", obj->path);
2588 _rtld_error("Cannot dlopen non-loadable %s", obj->path);
2592 obj->dlopened = (flags & RTLD_LO_DLOPEN) != 0;
2593 TAILQ_INSERT_TAIL(&obj_list, obj, next);
2596 linkmap_add(obj); /* for GDB & dlinfo() */
2597 max_stack_flags |= obj->stack_flags;
2599 dbg(" %p .. %p: %s", obj->mapbase,
2600 obj->mapbase + obj->mapsize - 1, obj->path);
2601 if (obj->textrel)
2602 dbg(" WARNING: %s has impure text", obj->path);
2603 LD_UTRACE(UTRACE_LOAD_OBJECT, obj, obj->mapbase, obj->mapsize, 0,
2604 obj->path);
2606 return (obj);
2609 munmap(obj->mapbase, obj->mapsize);
2610 obj_free(obj);
2617 Obj_Entry *obj;
2619 TAILQ_FOREACH(obj, &obj_list, next) {
2620 if (obj->marker)
2622 if (addr < (void *) obj->mapbase)
2624 if (addr < (void *) (obj->mapbase + obj->mapsize))
2625 return obj;
2678 if (root != NULL && (elm->obj->refcount != 1 ||
2679 objlist_find(&root->dagmembers, elm->obj) == NULL))
2684 elm->obj->doomed = true;
2686 hold_object(elm->obj);
2692 fini_addr = (Elf_Addr *)elm->obj->fini_array;
2693 if (fini_addr != NULL && elm->obj->fini_array_num > 0) {
2694 for (index = elm->obj->fini_array_num - 1; index >= 0;
2698 elm->obj->path, (void *)fini_addr[index]);
2699 LD_UTRACE(UTRACE_FINI_CALL, elm->obj,
2700 (void *)fini_addr[index], 0, 0, elm->obj->path);
2701 call_initfini_pointer(elm->obj, fini_addr[index]);
2705 if (elm->obj->fini != (Elf_Addr)NULL) {
2706 dbg("calling fini function for %s at %p", elm->obj->path,
2707 (void *)elm->obj->fini);
2708 LD_UTRACE(UTRACE_FINI_CALL, elm->obj, (void *)elm->obj->fini,
2709 0, 0, elm->obj->path);
2710 call_initfini_pointer(elm->obj, elm->obj->fini);
2713 unhold_object(elm->obj);
2737 Obj_Entry *obj;
2748 TAILQ_FOREACH(obj, &obj_list, next) {
2749 if (obj->marker)
2751 obj->init_scanned = false;
2760 if (elm->obj->init_done) /* Initialized early. */
2767 elm->obj->init_done = true;
2768 hold_object(elm->obj);
2770 if (elm->obj == obj_main && obj_main->crt_no_init) {
2784 if (elm->obj->init != (Elf_Addr)NULL) {
2785 dbg("calling init function for %s at %p", elm->obj->path,
2786 (void *)elm->obj->init);
2787 LD_UTRACE(UTRACE_INIT_CALL, elm->obj, (void *)elm->obj->init,
2788 0, 0, elm->obj->path);
2789 call_init_pointer(elm->obj, elm->obj->init);
2791 init_addr = (Elf_Addr *)elm->obj->init_array;
2793 for (index = 0; index < elm->obj->init_array_num; index++) {
2795 dbg("calling init function for %s at %p", elm->obj->path,
2797 LD_UTRACE(UTRACE_INIT_CALL, elm->obj,
2798 (void *)init_addr[index], 0, 0, elm->obj->path);
2799 call_init_pointer(elm->obj, init_addr[index]);
2804 unhold_object(elm->obj);
2822 objlist_find(Objlist *list, const Obj_Entry *obj)
2827 if (elm->obj == obj)
2839 objlist_push_head(Objlist *list, Obj_Entry *obj)
2844 elm->obj = obj;
2849 objlist_push_tail(Objlist *list, Obj_Entry *obj)
2854 elm->obj = obj;
2859 objlist_put_after(Objlist *list, Obj_Entry *listobj, Obj_Entry *obj)
2864 if (listelm->obj == listobj)
2868 elm->obj = obj;
2876 objlist_remove(Objlist *list, Obj_Entry *obj)
2880 if ((elm = objlist_find(list, obj)) != NULL) {
2900 error = relocate_object(elm->obj, bind_now, rtldobj, flags,
2917 reloc_textrel_prot(Obj_Entry *obj, bool before)
2924 for (l = obj->phsize / sizeof(*ph), ph = obj->phdr; l > 0;
2928 base = obj->relocbase + trunc_page(ph->p_vaddr);
2934 obj->path, before ? "en" : "dis",
2947 relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
2951 if (obj->relocated)
2953 obj->relocated = true;
2954 if (obj != rtldobj)
2955 dbg("relocating \"%s\"", obj->path);
2957 if (obj->symtab == NULL || obj->strtab == NULL ||
2958 !(obj->valid_hash_sysv || obj->valid_hash_gnu))
2959 dbg("object %s has no run-time symbol table", obj->path);
2962 if (obj->textrel && reloc_textrel_prot(obj, true) != 0)
2966 if (reloc_non_plt(obj, rtldobj, flags, lockstate))
2970 if (obj->textrel && reloc_textrel_prot(obj, false) != 0)
2974 init_pltgot(obj);
2977 if (reloc_plt(obj) == -1)
2980 if ((obj->bind_now || bind_now) && reloc_jmpslots(obj, flags,
2984 if (!obj->mainprog && obj_enforce_relro(obj) == -1)
2992 obj->magic = RTLD_MAGIC;
2993 obj->version = RTLD_VERSION;
3008 Obj_Entry *obj;
3011 for (error = 0, obj = first; obj != NULL;
3012 obj = TAILQ_NEXT(obj, next)) {
3013 if (obj->marker)
3015 error = relocate_object(obj, bind_now, rtldobj, flags,
3035 resolve_object_ifunc(Obj_Entry *obj, bool bind_now, int flags,
3039 if (obj->ifuncs_resolved)
3041 obj->ifuncs_resolved = true;
3042 if (!obj->irelative && !((obj->bind_now || bind_now) &&
3043 obj->gnu_ifunc) && !obj->non_plt_gnu_ifunc)
3045 if (obj_disable_relro(obj) == -1 ||
3046 (obj->irelative && reloc_iresolve(obj, lockstate) == -1) ||
3047 ((obj->bind_now || bind_now) && obj->gnu_ifunc &&
3048 reloc_gnu_ifunc(obj, flags, lockstate) == -1) ||
3049 (obj->non_plt_gnu_ifunc && reloc_non_plt(obj, &obj_rtld,
3051 obj_enforce_relro(obj) == -1)
3061 Obj_Entry *obj;
3064 obj = elm->obj;
3065 if (obj->marker)
3067 if (resolve_object_ifunc(obj, bind_now, flags,
3383 dlopen_cleanup(Obj_Entry *obj, RtldLockState *lockstate)
3386 obj->dl_refcount--;
3387 unref_dag(obj);
3388 if (obj->refcount == 0)
3389 unload_object(obj, lockstate);
3397 Obj_Entry *obj;
3414 obj = NULL;
3416 obj = obj_main;
3417 obj->refcount++;
3419 obj = load_object(name, fd, refobj, lo_flags);
3422 if (obj) {
3423 obj->dl_refcount++;
3424 if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL)
3425 objlist_push_tail(&list_global, obj);
3428 assert(globallist_next(old_obj_tail) == obj);
3430 obj->symbolic = true;
3433 obj->static_tls && !allocate_tls_offset(obj)) {
3435 "for static Thread Local Storage", obj->path);
3439 result = load_needed_objects(obj, lo_flags & (RTLD_LO_DLOPEN |
3441 init_dag(obj);
3442 ref_dag(obj);
3444 result = rtld_verify_versions(&obj->dagmembers);
3447 if (result == -1 || relocate_object_dag(obj,
3451 dlopen_cleanup(obj, lockstate);
3452 obj = NULL;
3465 initlist_add_objects(obj, obj, &initlist);
3473 if (obj != NULL)
3474 process_z(obj);
3482 init_dag(obj);
3483 ref_dag(obj);
3488 if (obj != NULL && ((lo_flags & RTLD_LO_NODELETE) != 0 ||
3489 obj->z_nodelete) && !obj->ref_nodel) {
3490 dbg("obj %s nodelete", obj->path);
3491 ref_dag(obj);
3492 obj->z_nodelete = obj->ref_nodel = true;
3496 LD_UTRACE(UTRACE_DLOPEN_STOP, obj, NULL, 0, obj ? obj->dl_refcount : 0,
3498 GDB_STATE(RT_CONSISTENT,obj ? &obj->linkmap : NULL);
3502 if (obj != NULL)
3510 dlopen_cleanup(obj, lockstate);
3523 return obj;
3525 trace_loaded_objects(obj);
3536 const Obj_Entry *obj, *defobj;
3558 if ((obj = obj_from_addr(retaddr)) == NULL) {
3565 res = symlook_obj(&req, obj);
3573 obj = globallist_next(obj);
3574 for (; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
3575 if (obj->marker)
3577 res = symlook_obj(&req, obj);
3602 res = symlook_default(&req, obj);
3609 if ((obj = dlcheck(handle)) == NULL) {
3616 if (obj->mainprog) {
3638 res = symlook_list(&req, &obj->dagmembers, &donelist);
3711 const Obj_Entry *obj;
3715 obj = obj_from_addr(addr);
3716 if (obj == NULL) {
3721 rtld_fill_dl_phdr_info(obj, phdr_info);
3729 const Obj_Entry *obj;
3736 obj = obj_from_addr(addr);
3737 if (obj == NULL) {
3742 info->dli_fname = obj->path;
3743 info->dli_fbase = obj->mapbase;
3751 for (symoffset = 0; symoffset < obj->dynsymcount; symoffset++) {
3752 def = obj->symtab + symoffset;
3766 symbol_addr = obj->relocbase + def->st_value;
3771 info->dli_sname = obj->strtab + def->st_name;
3785 const Obj_Entry *obj;
3795 if ((obj = obj_from_addr(retaddr)) == NULL)
3798 obj = dlcheck(handle);
3800 if (obj == NULL) {
3808 *((struct link_map const **)p) = &obj->linkmap;
3811 error = rtld_dirname(obj->path, p);
3816 error = do_search_info(obj, request, (struct dl_serinfo *)p);
3830 rtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info)
3833 phdr_info->dlpi_addr = (Elf_Addr)obj->relocbase;
3834 phdr_info->dlpi_name = obj->path;
3835 phdr_info->dlpi_phdr = obj->phdr;
3836 phdr_info->dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]);
3837 phdr_info->dlpi_tls_modid = obj->tlsindex;
3838 phdr_info->dlpi_tls_data = obj->tlsinit;
3847 Obj_Entry *obj, marker;
3856 for (obj = globallist_curr(TAILQ_FIRST(&obj_list)); obj != NULL;) {
3857 TAILQ_INSERT_AFTER(&obj_list, obj, &marker, next);
3858 rtld_fill_dl_phdr_info(obj, &phdr_info);
3859 hold_object(obj);
3865 unhold_object(obj);
3866 obj = globallist_next(&marker);
3912 do_search_info(const Obj_Entry *obj, int request, struct dl_serinfo *info)
3923 path_enumerate(obj->rpath, fill_search_info, NULL, &args);
3925 path_enumerate(obj->runpath, fill_search_info, NULL, &args);
3926 path_enumerate(gethints(obj->z_nodeflib), fill_search_info, NULL, &args);
3927 if (!obj->z_nodeflib)
3948 if (path_enumerate(obj->rpath, fill_search_info, NULL, &args) != NULL)
3956 if (path_enumerate(obj->runpath, fill_search_info, NULL, &args) != NULL)
3960 if (path_enumerate(gethints(obj->z_nodeflib), fill_search_info, NULL, &args)
3965 if (!obj->z_nodeflib && path_enumerate(ld_standard_library_path,
4036 linkmap_add(Obj_Entry *obj)
4038 struct link_map *l = &obj->linkmap;
4041 obj->linkmap.l_name = obj->path;
4042 obj->linkmap.l_addr = obj->mapbase;
4043 obj->linkmap.l_ld = obj->dynamic;
4046 obj->linkmap.l_offs = obj->relocbase;
4072 linkmap_delete(Obj_Entry *obj)
4074 struct link_map *l = &obj->linkmap;
4126 release_object(Obj_Entry *obj)
4129 if (obj->holdcount > 0) {
4130 obj->unholdfree = true;
4133 munmap(obj->mapbase, obj->mapsize);
4134 linkmap_delete(obj);
4135 obj_free(obj);
4209 res = symlook_list(&req1, &elm->obj->dagmembers, donelist);
4259 res = symlook_list(&req1, &elm->obj->dagmembers, &donelist);
4298 if (donelist_check(dlp, elm->obj))
4301 if ((res = symlook_obj(&req1, elm->obj)) == 0) {
4337 if (n->obj == NULL ||
4338 (res = symlook_list(&req1, &n->obj->dagmembers, dlp)) != 0)
4365 symlook_obj(SymLook *req, const Obj_Entry *obj)
4375 if (obj->valid_hash_gnu)
4376 mres = symlook_obj1_gnu(req, obj);
4377 else if (obj->valid_hash_sysv)
4378 mres = symlook_obj1_sysv(req, obj);
4383 if (obj->needed_filtees != NULL) {
4385 load_filtees(__DECONST(Obj_Entry *, obj), flags, req->lockstate);
4388 res = symlook_needed(&req1, obj->needed_filtees, &donelist);
4395 if (obj->needed_aux_filtees != NULL) {
4397 load_filtees(__DECONST(Obj_Entry *, obj), flags, req->lockstate);
4400 res = symlook_needed(&req1, obj->needed_aux_filtees, &donelist);
4413 matched_symbol(SymLook *req, const Obj_Entry *obj, Sym_Match_Result *result,
4420 symp = obj->symtab + symnum;
4421 strp = obj->strtab + symp->st_name;
4448 if (obj->versyms != NULL) {
4449 verndx = VER_NDX(obj->versyms[symnum]);
4450 if (verndx > obj->vernum) {
4453 obj->path, obj->strtab + symnum, verndx);
4475 if ((obj->versyms[symnum] & VER_NDX_HIDDEN)
4487 if (obj->versyms == NULL) {
4488 if (object_match_name(obj, req->ventry->name)) {
4490 "for symbol %s", obj_rtld.path, obj->path,
4491 req->ventry->name, obj->strtab + symnum);
4495 verndx = VER_NDX(obj->versyms[symnum]);
4496 if (verndx > obj->vernum) {
4498 obj->path, obj->strtab + symnum, verndx);
4501 if (obj->vertab[verndx].hash != req->ventry->hash ||
4502 strcmp(obj->vertab[verndx].name, req->ventry->name)) {
4514 (obj->versyms[symnum] & VER_NDX_HIDDEN))
4524 * obj->buckets is known not to be NULL at this point; the test for this was
4525 * performed with the obj->valid_hash_sysv assignment.
4528 symlook_obj1_sysv(SymLook *req, const Obj_Entry *obj)
4537 for (symnum = obj->buckets[req->hash % obj->nbuckets];
4538 symnum != STN_UNDEF; symnum = obj->chains[symnum]) {
4539 if (symnum >= obj->nchains)
4542 if (matched_symbol(req, obj, &matchres, symnum)) {
4544 req->defobj_out = obj;
4550 req->defobj_out = obj;
4558 symlook_obj1_gnu(SymLook *req, const Obj_Entry *obj)
4572 bloom_word = obj->bloom_gnu[(req->hash_gnu / __ELF_WORD_SIZE) &
4573 obj->maskwords_bm_gnu];
4577 h2 = ((req->hash_gnu >> obj->shift2_gnu) & (__ELF_WORD_SIZE - 1));
4584 bucket = obj->buckets_gnu[req->hash_gnu % obj->nbuckets_gnu];
4587 hashval = &obj->chain_zero_gnu[bucket];
4590 symnum = hashval - obj->chain_zero_gnu;
4591 if (matched_symbol(req, obj, &matchres, symnum)) {
4593 req->defobj_out = obj;
4600 req->defobj_out = obj;
4607 trace_loaded_objects(Obj_Entry *obj)
4623 for (; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
4628 if (obj->marker)
4630 if (list_containers && obj->needed != NULL)
4631 rtld_printf("%s:\n", obj->path);
4632 for (needed = obj->needed; needed; needed = needed->next) {
4633 if (needed->obj != NULL) {
4634 if (needed->obj->traced && !list_containers)
4636 needed->obj->traced = true;
4637 path = needed->obj->path;
4641 name = (char *)obj->strtab + needed->name;
4691 rtld_printf("%p", needed->obj ? needed->obj->mapbase :
4712 Obj_Entry marker, *obj, *next;
4723 for (obj = TAILQ_FIRST(&obj_list); obj != NULL; obj = next) {
4724 next = TAILQ_NEXT(obj, next);
4725 if (obj->marker || obj->refcount != 0)
4727 LD_UTRACE(UTRACE_UNLOAD_OBJECT, obj, obj->mapbase,
4728 obj->mapsize, 0, obj->path);
4729 dbg("unloading \"%s\"", obj->path);
4735 TAILQ_REMOVE(&obj_list, obj, next);
4738 if (obj->filtees_loaded) {
4742 unload_filtees(obj, lockstate);
4746 unload_filtees(obj, lockstate);
4748 release_object(obj);
4763 objlist_remove(&elm->obj->dldags, root);
4764 if (elm->obj != root)
4765 unlink_object(elm->obj);
4777 elm->obj->refcount++;
4787 elm->obj->refcount--;
4850 Obj_Entry *obj;
4882 for (obj = globallist_curr(objs); obj != NULL;
4883 obj = globallist_next(obj)) {
4884 if (obj->tlsoffset > 0) {
4885 addr = (Elf_Addr)tls + obj->tlsoffset;
4886 if (obj->tlsinitsize > 0)
4887 memcpy((void*) addr, obj->tlsinit, obj->tlsinitsize);
4888 if (obj->tlssize > obj->tlsinitsize)
4889 memset((void*) (addr + obj->tlsinitsize), 0,
4890 obj->tlssize - obj->tlsinitsize);
4891 dtv[obj->tlsindex + 1] = addr;
4932 Obj_Entry *obj;
4982 for (obj = objs; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
4983 if (obj->marker || obj->tlsoffset == 0)
4985 addr = segbase - obj->tlsoffset;
4986 memset((void*) (addr + obj->tlsinitsize),
4987 0, obj->tlssize - obj->tlsinitsize);
4988 if (obj->tlsinit) {
4989 memcpy((void*) addr, obj->tlsinit, obj->tlsinitsize);
4990 obj->static_tls_copied = true;
4992 dtv[obj->tlsindex + 1] = addr;
5038 Obj_Entry* obj;
5041 TAILQ_FOREACH(obj, &obj_list, next) {
5042 if (obj->marker)
5044 if (obj->tlsindex == index)
5047 if (!obj) {
5052 p = malloc_aligned(obj->tlssize, obj->tlsalign);
5053 memcpy(p, obj->tlsinit, obj->tlsinitsize);
5054 memset(p + obj->tlsinitsize, 0, obj->tlssize - obj->tlsinitsize);
5060 allocate_tls_offset(Obj_Entry *obj)
5064 if (obj->tls_done)
5067 if (obj->tlssize == 0) {
5068 obj->tls_done = true;
5073 off = calculate_first_tls_offset(obj->tlssize, obj->tlsalign);
5076 obj->tlssize, obj->tlsalign);
5085 if (calculate_tls_end(off, obj->tlssize) > tls_static_space)
5087 } else if (obj->tlsalign > tls_static_max_align) {
5088 tls_static_max_align = obj->tlsalign;
5091 tls_last_offset = obj->tlsoffset = off;
5092 tls_last_size = obj->tlssize;
5093 obj->tls_done = true;
5099 free_tls_offset(Obj_Entry *obj)
5108 if (calculate_tls_end(obj->tlsoffset, obj->tlssize)
5110 tls_last_offset -= obj->tlssize;
5139 object_add_name(Obj_Entry *obj, const char *name)
5149 STAILQ_INSERT_TAIL(&obj->names, entry, link);
5154 object_match_name(const Obj_Entry *obj, const char *name)
5158 STAILQ_FOREACH(entry, &obj->names, link) {
5166 locate_dependency(const Obj_Entry *obj, const char *name)
5172 if (object_match_name(entry->obj, name))
5173 return entry->obj;
5176 for (needed = obj->needed; needed != NULL; needed = needed->next) {
5177 if (strcmp(obj->strtab + needed->name, name) == 0 ||
5178 (needed->obj != NULL && object_match_name(needed->obj, name))) {
5186 return (needed->obj);
5190 obj->path, name);
5232 rtld_verify_object_versions(Obj_Entry *obj)
5241 if (obj->ver_checked)
5243 obj->ver_checked = true;
5251 vn = obj->verneed;
5255 obj->path, vn->vn_version);
5272 vd = obj->verdef;
5276 obj->path, vd->vd_version);
5295 obj->vernum = maxvernum + 1;
5296 obj->vertab = xcalloc(obj->vernum, sizeof(Ver_Entry));
5298 vd = obj->verdef;
5304 obj->vertab[vernum].hash = vd->vd_hash;
5305 obj->vertab[vernum].name = obj->strtab + vda->vda_name;
5306 obj->vertab[vernum].file = NULL;
5307 obj->vertab[vernum].flags = 0;
5314 vn = obj->verneed;
5316 depobj = locate_dependency(obj, obj->strtab + vn->vn_file);
5321 if (check_object_provided_version(obj, depobj, vna))
5325 obj->vertab[vernum].hash = vna->vna_hash;
5326 obj->vertab[vernum].name = obj->strtab + vna->vna_name;
5327 obj->vertab[vernum].file = obj->strtab + vn->vn_file;
5328 obj->vertab[vernum].flags = (vna->vna_other & VER_NEED_HIDDEN) ?
5353 if (entry->obj->strtab == NULL || entry->obj->vertab != NULL)
5355 if (rtld_verify_object_versions(entry->obj) == -1) {
5367 fetch_ventry(const Obj_Entry *obj, unsigned long symnum)
5371 if (obj->vertab) {
5372 vernum = VER_NDX(obj->versyms[symnum]);
5373 if (vernum >= obj->vernum) {
5375 obj->path, obj->strtab + symnum, vernum);
5376 } else if (obj->vertab[vernum].hash != 0) {
5377 return &obj->vertab[vernum];
5393 Obj_Entry *obj;
5398 obj = dlcheck(arg);
5399 if (obj == NULL)
5400 obj = obj_from_addr(arg);
5401 if (obj == NULL) {
5406 res = obj->dlopened ? 1 : 0;
5412 obj_remap_relro(Obj_Entry *obj, int prot)
5415 if (obj->relro_size > 0 && mprotect(obj->relro_page, obj->relro_size,
5418 obj->path, prot, rtld_strerror(errno));
5425 obj_disable_relro(Obj_Entry *obj)
5428 return (obj_remap_relro(obj, PROT_READ | PROT_WRITE));
5432 obj_enforce_relro(Obj_Entry *obj)
5435 return (obj_remap_relro(obj, PROT_READ));
5457 Obj_Entry *obj;
5465 obj = elm->obj;
5466 if (obj->marker || !obj->tls_done || obj->static_tls_copied)
5468 distrib(obj->tlsoffset, obj->tlsinit, obj->tlsinitsize,
5469 obj->tlssize);
5470 obj->static_tls_copied = true;