Lines Matching defs:obj
101 static int do_search_info(const Obj_Entry *obj, int, struct dl_serinfo *);
148 static int relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
179 static bool obj_resolve_origin(Obj_Entry *obj);
186 static void rtld_fill_dl_phdr_info(const Obj_Entry *obj,
270 Elf_Addr _rtld_bind(Obj_Entry *obj, Elf_Size reloff);
498 Obj_Entry *last_interposer, *obj, *preload_tail;
875 TAILQ_FOREACH(obj, &obj_list, next) {
876 if (obj->marker)
878 if (obj->z_interpose && obj != obj_main) {
879 objlist_put_after(&list_main, last_interposer, obj);
880 last_interposer = obj;
882 objlist_push_tail(&list_main, obj);
884 obj->refcount++;
915 allocate_tls_offset(entry->obj);
994 TAILQ_FOREACH(obj, &obj_list, next) {
995 if (obj->marker)
997 if (ld_loadfltr || obj->z_loadfltr)
998 load_filtees(obj, 0, &lockstate);
1001 dbg("enforcing main obj relro");
1017 rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def)
1022 ptr = (void *)make_function_pointer(def, obj);
1028 _rtld_bind(Obj_Entry *obj, Elf_Size reloff)
1040 if (obj->pltrel)
1041 rel = (const Elf_Rel *)((const char *)obj->pltrel + reloff);
1043 rel = (const Elf_Rel *)((const char *)obj->pltrela + reloff);
1045 where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
1046 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, SYMLOOK_IN_PLT,
1056 obj->path == NULL ? NULL : basename(obj->path), (void *)target,
1066 target = reloc_jmpslot(where, target, defobj, obj, rel);
1135 origin_subst_one(Obj_Entry *obj, char *real, const char *kw, const char *subst,
1160 if (subst_count == 0 || (obj != NULL && !obj_resolve_origin(obj)))
1162 if (obj != NULL)
1163 subst = obj->origin_path;
1217 origin_subst(Obj_Entry *obj, const char *real)
1222 if (obj == NULL || !trust)
1234 res = origin_subst_one(tokens[i].pass_obj ? obj : NULL, res,
1258 digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
1262 Needed_Entry **needed_tail = &obj->needed;
1263 Needed_Entry **needed_filtees_tail = &obj->needed_filtees;
1264 Needed_Entry **needed_aux_filtees_tail = &obj->needed_aux_filtees;
1275 obj->bind_now = false;
1276 dynp = obj->dynamic;
1282 obj->rel = (const Elf_Rel *)(obj->relocbase +
1287 obj->relsize = dynp->d_un.d_val;
1295 obj->pltrel = (const Elf_Rel *)(obj->relocbase +
1300 obj->pltrelsize = dynp->d_un.d_val;
1304 obj->rela = (const Elf_Rela *)(obj->relocbase +
1309 obj->relasize = dynp->d_un.d_val;
1317 obj->relr = (const Elf_Relr *)(obj->relocbase +
1322 obj->relrsize = dynp->d_un.d_val;
1336 obj->symtab = (const Elf_Sym *)(obj->relocbase +
1345 obj->strtab = (const char *)(obj->relocbase +
1350 obj->strsize = dynp->d_un.d_val;
1354 obj->verneed = (const Elf_Verneed *)(obj->relocbase +
1359 obj->verneednum = dynp->d_un.d_val;
1363 obj->verdef = (const Elf_Verdef *)(obj->relocbase +
1368 obj->verdefnum = dynp->d_un.d_val;
1372 obj->versyms = (const Elf_Versym *)(obj->relocbase +
1377 hashtab = (const Elf_Hashelt *)(obj->relocbase +
1379 obj->nbuckets = hashtab[0];
1380 obj->nchains = hashtab[1];
1381 obj->buckets = hashtab + 2;
1382 obj->chains = obj->buckets + obj->nbuckets;
1383 obj->valid_hash_sysv = obj->nbuckets > 0 &&
1384 obj->nchains > 0 && obj->buckets != NULL;
1388 hashtab = (const Elf_Hashelt *)(obj->relocbase +
1390 obj->nbuckets_gnu = hashtab[0];
1391 obj->symndx_gnu = hashtab[1];
1394 obj->maskwords_bm_gnu = nmaskwords - 1;
1395 obj->shift2_gnu = hashtab[3];
1396 obj->bloom_gnu = (const Elf_Addr *)(hashtab + 4);
1397 obj->buckets_gnu = hashtab + 4 + bloom_size32;
1398 obj->chain_zero_gnu = obj->buckets_gnu +
1399 obj->nbuckets_gnu - obj->symndx_gnu;
1402 obj->valid_hash_gnu = powerof2(nmaskwords) &&
1403 obj->nbuckets_gnu > 0 && obj->buckets_gnu != NULL;
1407 if (!obj->rtld) {
1410 nep->obj = NULL;
1419 if (!obj->rtld) {
1422 nep->obj = NULL;
1428 if (obj->linkmap.l_refname == NULL)
1429 obj->linkmap.l_refname =
1435 if (!obj->rtld) {
1438 nep->obj = NULL;
1447 obj->pltgot = (Elf_Addr *)(obj->relocbase +
1452 obj->textrel = true;
1456 obj->symbolic = true;
1477 obj->init = (Elf_Addr)(obj->relocbase +
1482 obj->preinit_array = (Elf_Addr)(obj->relocbase +
1487 obj->preinit_array_num = dynp->d_un.d_val /
1492 obj->init_array = (Elf_Addr)(obj->relocbase +
1497 obj->init_array_num = dynp->d_un.d_val /
1502 obj->fini = (Elf_Addr)(obj->relocbase +
1507 obj->fini_array = (Elf_Addr)(obj->relocbase +
1512 obj->fini_array_num = dynp->d_un.d_val /
1525 obj->z_origin = true;
1527 obj->symbolic = true;
1529 obj->textrel = true;
1531 obj->bind_now = true;
1533 obj->static_tls = true;
1538 obj->z_noopen = true;
1540 obj->z_origin = true;
1542 obj->z_global = true;
1544 obj->bind_now = true;
1546 obj->z_nodelete = true;
1548 obj->z_loadfltr = true;
1550 obj->z_interpose = true;
1552 obj->z_nodeflib = true;
1554 obj->z_pie = true;
1558 if (arch_digest_dynamic(obj, dynp))
1569 obj->traced = false;
1572 obj->pltrela = (const Elf_Rela *)obj->pltrel;
1573 obj->pltrel = NULL;
1574 obj->pltrelasize = obj->pltrelsize;
1575 obj->pltrelsize = 0;
1579 if (obj->valid_hash_sysv)
1580 obj->dynsymcount = obj->nchains;
1581 else if (obj->valid_hash_gnu) {
1582 obj->dynsymcount = 0;
1583 for (bkt = 0; bkt < obj->nbuckets_gnu; bkt++) {
1584 if (obj->buckets_gnu[bkt] == 0)
1586 hashval = &obj->chain_zero_gnu[obj->buckets_gnu[bkt]];
1588 obj->dynsymcount++;
1591 obj->dynsymcount += obj->symndx_gnu;
1594 if (obj->linkmap.l_refname != NULL)
1595 obj->linkmap.l_refname = obj->strtab +
1596 (unsigned long)obj->linkmap.l_refname;
1600 obj_resolve_origin(Obj_Entry *obj)
1602 if (obj->origin_path != NULL)
1604 obj->origin_path = xmalloc(PATH_MAX);
1605 return (rtld_dirname_abs(obj->path, obj->origin_path) != -1);
1609 digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath,
1612 if (obj->z_origin && !obj_resolve_origin(obj))
1616 obj->runpath = (const char *)obj->strtab +
1618 obj->runpath = origin_subst(obj, obj->runpath);
1620 obj->rpath = (const char *)obj->strtab + dyn_rpath->d_un.d_val;
1621 obj->rpath = origin_subst(obj, obj->rpath);
1624 object_add_name(obj, obj->strtab + dyn_soname->d_un.d_val);
1629 digest_dynamic(Obj_Entry *obj, int early)
1635 digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname, &dyn_runpath);
1636 return (digest_dynamic2(obj, dyn_rpath, dyn_soname, dyn_runpath));
1648 Obj_Entry *obj;
1654 obj = obj_new();
1659 obj->phdr = phdr;
1660 obj->phsize = ph->p_memsz;
1661 obj->relocbase = __DECONST(char *, phdr) - ph->p_vaddr;
1665 obj->stack_flags = PF_X | PF_R | PF_W;
1670 obj->interp = (const char *)(ph->p_vaddr +
1671 obj->relocbase);
1676 obj->vaddrbase = rtld_trunc_page(ph->p_vaddr);
1677 obj->mapbase = obj->vaddrbase + obj->relocbase;
1679 obj->mapsize = rtld_round_page(
1681 obj->vaddrbase;
1687 obj->dynamic = (const Elf_Dyn *)(ph->p_vaddr +
1688 obj->relocbase);
1692 obj->tlsindex = 1;
1693 obj->tlssize = ph->p_memsz;
1694 obj->tlsalign = ph->p_align;
1695 obj->tlsinitsize = ph->p_filesz;
1696 obj->tlsinit = (void *)(ph->p_vaddr + obj->relocbase);
1697 obj->tlspoffset = ph->p_offset;
1701 obj->stack_flags = ph->p_flags;
1705 note_start = (Elf_Addr)obj->relocbase + ph->p_vaddr;
1707 digest_notes(obj, note_start, note_end);
1716 obj->entry = entry;
1717 return (obj);
1721 digest_notes(Obj_Entry *obj, Elf_Addr note_start, Elf_Addr note_end)
1731 if (arch_digest_note(obj, note))
1750 obj->osrel = *(const int32_t *)(p);
1751 dbg("note osrel %d", obj->osrel);
1757 obj->fctl0 = *(const uint32_t *)(p);
1758 dbg("note fctl0 %#x", obj->fctl0);
1762 obj->crt_no_init = true;
1772 Obj_Entry *obj;
1774 TAILQ_FOREACH(obj, &obj_list, next) {
1775 if (obj == (Obj_Entry *)handle)
1779 if (obj == NULL || obj->refcount == 0 || obj->dl_refcount == 0) {
1783 return (obj);
1791 donelist_check(DoneList *dlp, const Obj_Entry *obj)
1796 if (dlp->objs[i] == obj)
1805 dlp->objs[dlp->num_used++] = obj;
1995 *defobj_out = cache[symnum].obj;
2047 cache[symnum].obj = defobj;
2296 for (needed = elm->obj->needed; needed != NULL;
2298 if (needed->obj == NULL ||
2299 donelist_check(&donelist, needed->obj))
2301 objlist_push_tail(&needed->obj->dldags, root);
2302 objlist_push_tail(&root->dagmembers, needed->obj);
2316 globallist_curr(const Obj_Entry *obj)
2319 if (obj == NULL)
2321 if (!obj->marker)
2322 return (__DECONST(Obj_Entry *, obj));
2323 obj = TAILQ_PREV(obj, obj_entry_q, next);
2328 globallist_next(const Obj_Entry *obj)
2331 obj = TAILQ_NEXT(obj, next);
2332 if (obj == NULL)
2334 if (!obj->marker)
2335 return (__DECONST(Obj_Entry *, obj));
2341 hold_object(Obj_Entry *obj)
2343 obj->holdcount++;
2347 unhold_object(Obj_Entry *obj)
2349 assert(obj->holdcount > 0);
2350 if (--obj->holdcount == 0 && obj->unholdfree)
2351 release_object(obj);
2358 Obj_Entry *obj;
2371 obj = elm->obj;
2372 if (obj == NULL)
2374 if (obj->z_nodelete && !obj->ref_nodel) {
2375 dbg("obj %s -z nodelete", obj->path);
2376 init_dag(obj);
2377 ref_dag(obj);
2378 obj->ref_nodel = true;
2380 if (obj->z_global && objlist_find(&list_global, obj) == NULL) {
2381 dbg("obj %s -z global", obj->path);
2382 objlist_push_tail(&list_global, obj);
2383 init_dag(obj);
2389 parse_rtld_phdr(Obj_Entry *obj)
2394 obj->stack_flags = PF_X | PF_R | PF_W;
2395 for (ph = obj->phdr;
2396 (const char *)ph < (const char *)obj->phdr + obj->phsize; ph++) {
2399 obj->stack_flags = ph->p_flags;
2402 note_start = (Elf_Addr)obj->relocbase + ph->p_vaddr;
2404 digest_notes(obj, note_start, note_end);
2539 if (needed->obj != NULL)
2540 initlist_add_objects(needed->obj, needed->obj, list);
2544 * Scan all of the DAGs rooted in the range of objects from "obj" to
2553 initlist_add_objects(Obj_Entry *obj, Obj_Entry *tail, Objlist *list)
2557 if (obj->init_scanned || obj->init_done)
2559 obj->init_scanned = true;
2562 nobj = globallist_next(obj);
2563 if (nobj != NULL && obj != tail)
2567 if (obj->needed != NULL)
2568 initlist_add_neededs(obj->needed, list);
2569 if (obj->needed_filtees != NULL)
2570 initlist_add_neededs(obj->needed_filtees, list);
2571 if (obj->needed_aux_filtees != NULL)
2572 initlist_add_neededs(obj->needed_aux_filtees, list);
2575 objlist_push_tail(list, obj);
2578 if ((obj->fini != (Elf_Addr)NULL ||
2579 obj->fini_array != (Elf_Addr)NULL) &&
2580 !obj->on_fini_list) {
2581 objlist_push_head(&list_fini, obj);
2582 obj->on_fini_list = true;
2592 if (needed->obj != NULL) {
2593 dlclose_locked(needed->obj, lockstate);
2594 needed->obj = NULL;
2604 unload_filtees(Obj_Entry *obj, RtldLockState *lockstate)
2606 free_needed_filtees(obj->needed_filtees, lockstate);
2607 obj->needed_filtees = NULL;
2608 free_needed_filtees(obj->needed_aux_filtees, lockstate);
2609 obj->needed_aux_filtees = NULL;
2610 obj->filtees_loaded = false;
2614 load_filtee1(Obj_Entry *obj, Needed_Entry *needed, int flags,
2618 needed->obj = dlopen_object(obj->strtab + needed->name, -1, obj,
2620 ((ld_loadfltr || obj->z_loadfltr) ? RTLD_NOW : RTLD_LAZY) |
2627 load_filtees(Obj_Entry *obj, int flags, RtldLockState *lockstate)
2629 if (obj->filtees_loaded || obj->filtees_loading)
2632 obj->filtees_loading = true;
2633 load_filtee1(obj, obj->needed_filtees, flags, lockstate);
2634 load_filtee1(obj, obj->needed_aux_filtees, flags, lockstate);
2635 obj->filtees_loaded = true;
2636 obj->filtees_loading = false;
2640 process_needed(Obj_Entry *obj, Needed_Entry *needed, int flags)
2645 obj1 = needed->obj = load_object(obj->strtab + needed->name, -1,
2646 obj, flags & ~RTLD_LO_NOLOAD);
2662 Obj_Entry *obj;
2664 for (obj = first; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
2665 if (obj->marker)
2667 if (process_needed(obj, obj->needed, flags) == -1)
2676 Obj_Entry *obj;
2705 obj = load_object(name, fd, NULL, 0);
2706 if (obj == NULL) {
2710 obj->z_interpose = true;
2739 Obj_Entry *obj;
2746 TAILQ_FOREACH(obj, &obj_list, next) {
2747 if (obj->marker || obj->doomed)
2749 if (object_match_name(obj, name))
2750 return (obj);
2793 TAILQ_FOREACH(obj, &obj_list, next) {
2794 if (obj->marker || obj->doomed)
2796 if (obj->ino == sb.st_ino && obj->dev == sb.st_dev)
2799 if (obj != NULL) {
2801 object_add_name(obj, name);
2804 return (obj);
2813 obj = do_load_object(fd, name, path, &sb, flags);
2814 if (obj == NULL)
2818 return (obj);
2825 Obj_Entry *obj;
2841 obj = map_object(fd, printable_path(path), sbp);
2842 if (obj == NULL)
2850 object_add_name(obj, name);
2851 obj->path = path;
2852 if (!digest_dynamic(obj, 0))
2854 dbg("%s valid_hash_sysv %d valid_hash_gnu %d dynsymcount %d", obj->path,
2855 obj->valid_hash_sysv, obj->valid_hash_gnu, obj->dynsymcount);
2856 if (obj->z_pie && (flags & RTLD_LO_TRACE) == 0) {
2857 dbg("refusing to load PIE executable \"%s\"", obj->path);
2858 _rtld_error("Cannot load PIE binary %s as DSO", obj->path);
2861 if (obj->z_noopen &&
2863 dbg("refusing to load non-loadable \"%s\"", obj->path);
2864 _rtld_error("Cannot dlopen non-loadable %s", obj->path);
2868 obj->dlopened = (flags & RTLD_LO_DLOPEN) != 0;
2869 TAILQ_INSERT_TAIL(&obj_list, obj, next);
2872 linkmap_add(obj); /* for GDB & dlinfo() */
2873 max_stack_flags |= obj->stack_flags;
2875 dbg(" %p .. %p: %s", obj->mapbase, obj->mapbase + obj->mapsize - 1,
2876 obj->path);
2877 if (obj->textrel)
2878 dbg(" WARNING: %s has impure text", obj->path);
2879 LD_UTRACE(UTRACE_LOAD_OBJECT, obj, obj->mapbase, obj->mapsize, 0,
2880 obj->path);
2882 return (obj);
2885 munmap(obj->mapbase, obj->mapsize);
2886 obj_free(obj);
2893 Obj_Entry *obj;
2901 obj = obj_new();
2903 obj->phdr = phdr;
2904 obj->phsize = ehdr->e_phnum * sizeof(*phdr);
2915 obj->stack_flags = phdr->p_flags;
2928 obj->mapbase = __DECONST(caddr_t, addr);
2929 obj->mapsize = segn->p_vaddr + segn->p_memsz - (Elf_Addr)addr;
2930 obj->vaddrbase = 0;
2931 obj->relocbase = obj->mapbase;
2933 object_add_name(obj, kname);
2934 obj->path = xstrdup(kname);
2935 obj->dynamic = (const Elf_Dyn *)(obj->relocbase + phdyn->p_vaddr);
2937 if (!digest_dynamic(obj, 0)) {
2938 obj_free(obj);
2949 obj->path, obj->mapbase, obj->phdr, seg0,
2950 obj->relocbase + seg0->p_vaddr, obj->dynamic);
2952 TAILQ_INSERT_TAIL(&obj_list, obj, next);
2955 linkmap_add(obj); /* for GDB & dlinfo() */
2956 max_stack_flags |= obj->stack_flags;
2958 LD_UTRACE(UTRACE_LOAD_OBJECT, obj, obj->mapbase, 0, 0, obj->path);
2965 Obj_Entry *obj;
2967 TAILQ_FOREACH(obj, &obj_list, next) {
2968 if (obj->marker)
2970 if (addr < (void *)obj->mapbase)
2972 if (addr < (void *)(obj->mapbase + obj->mapsize))
2973 return obj;
3027 (elm->obj->refcount != 1 ||
3028 objlist_find(&root->dagmembers, elm->obj) ==
3035 elm->obj->doomed = true;
3037 hold_object(elm->obj);
3044 fini_addr = (Elf_Addr *)elm->obj->fini_array;
3045 if (fini_addr != NULL && elm->obj->fini_array_num > 0) {
3046 for (index = elm->obj->fini_array_num - 1;
3051 elm->obj->path,
3054 elm->obj,
3056 0, elm->obj->path);
3057 call_initfini_pointer(elm->obj,
3062 if (elm->obj->fini != (Elf_Addr)NULL) {
3064 elm->obj->path, (void *)elm->obj->fini);
3065 LD_UTRACE(UTRACE_FINI_CALL, elm->obj,
3066 (void *)elm->obj->fini, 0, 0,
3067 elm->obj->path);
3068 call_initfini_pointer(elm->obj, elm->obj->fini);
3071 unhold_object(elm->obj);
3096 Obj_Entry *obj;
3107 TAILQ_FOREACH(obj, &obj_list, next) {
3108 if (obj->marker)
3110 obj->init_scanned = false;
3119 if (elm->obj->init_done) /* Initialized early. */
3126 elm->obj->init_done = true;
3127 hold_object(elm->obj);
3129 if (elm->obj == obj_main && obj_main->crt_no_init) {
3143 if (elm->obj->init != (Elf_Addr)NULL) {
3145 elm->obj->path, (void *)elm->obj->init);
3146 LD_UTRACE(UTRACE_INIT_CALL, elm->obj,
3147 (void *)elm->obj->init, 0, 0, elm->obj->path);
3148 call_init_pointer(elm->obj, elm->obj->init);
3150 init_addr = (Elf_Addr *)elm->obj->init_array;
3152 for (index = 0; index < elm->obj->init_array_num;
3157 elm->obj->path,
3159 LD_UTRACE(UTRACE_INIT_CALL, elm->obj,
3161 elm->obj->path);
3162 call_init_pointer(elm->obj,
3168 unhold_object(elm->obj);
3186 objlist_find(Objlist *list, const Obj_Entry *obj)
3191 if (elm->obj == obj)
3203 objlist_push_head(Objlist *list, Obj_Entry *obj)
3208 elm->obj = obj;
3213 objlist_push_tail(Objlist *list, Obj_Entry *obj)
3218 elm->obj = obj;
3223 objlist_put_after(Objlist *list, Obj_Entry *listobj, Obj_Entry *obj)
3228 if (listelm->obj == listobj)
3232 elm->obj = obj;
3240 objlist_remove(Objlist *list, Obj_Entry *obj)
3244 if ((elm = objlist_find(list, obj)) != NULL) {
3264 error = relocate_object(elm->obj, bind_now, rtldobj, flags,
3281 reloc_textrel_prot(Obj_Entry *obj, bool before)
3288 for (l = obj->phsize / sizeof(*ph), ph = obj->phdr; l > 0; l--, ph++) {
3291 base = obj->relocbase + rtld_trunc_page(ph->p_vaddr);
3298 obj->path, before ? "en" : "dis",
3308 reloc_relr(Obj_Entry *obj)
3313 relrlim = (const Elf_Relr *)((const char *)obj->relr + obj->relrsize);
3314 for (relr = obj->relr; relr < relrlim; relr++) {
3318 where = (Elf_Addr *)(obj->relocbase + entry);
3319 *where++ += (Elf_Addr)obj->relocbase;
3323 where[i] += (Elf_Addr)obj->relocbase;
3334 relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj, int flags,
3337 if (obj->relocated)
3339 obj->relocated = true;
3340 if (obj != rtldobj)
3341 dbg("relocating \"%s\"", obj->path);
3343 if (obj->symtab == NULL || obj->strtab == NULL ||
3344 !(obj->valid_hash_sysv || obj->valid_hash_gnu))
3345 dbg("object %s has no run-time symbol table", obj->path);
3348 if (obj->textrel && reloc_textrel_prot(obj, true) != 0)
3352 if (reloc_non_plt(obj, rtldobj, flags, lockstate))
3354 reloc_relr(obj);
3357 if (obj->textrel && reloc_textrel_prot(obj, false) != 0)
3361 init_pltgot(obj);
3364 if (reloc_plt(obj, flags, lockstate) == -1)
3367 if ((obj->bind_now || bind_now) &&
3368 reloc_jmpslots(obj, flags, lockstate) == -1)
3371 if (obj != rtldobj && !obj->mainprog && obj_enforce_relro(obj) == -1)
3379 obj->magic = RTLD_MAGIC;
3380 obj->version = RTLD_VERSION;
3395 Obj_Entry *obj;
3398 for (error = 0, obj = first; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
3399 if (obj->marker)
3401 error = relocate_object(obj, bind_now, rtldobj, flags,
3421 resolve_object_ifunc(Obj_Entry *obj, bool bind_now, int flags,
3424 if (obj->ifuncs_resolved)
3426 obj->ifuncs_resolved = true;
3427 if (!obj->irelative && !obj->irelative_nonplt &&
3428 !((obj->bind_now || bind_now) && obj->gnu_ifunc) &&
3429 !obj->non_plt_gnu_ifunc)
3431 if (obj_disable_relro(obj) == -1 ||
3432 (obj->irelative && reloc_iresolve(obj, lockstate) == -1) ||
3433 (obj->irelative_nonplt &&
3434 reloc_iresolve_nonplt(obj, lockstate) == -1) ||
3435 ((obj->bind_now || bind_now) && obj->gnu_ifunc &&
3436 reloc_gnu_ifunc(obj, flags, lockstate) == -1) ||
3437 (obj->non_plt_gnu_ifunc &&
3438 reloc_non_plt(obj, &obj_rtld, flags | SYMLOOK_IFUNC,
3440 obj_enforce_relro(obj) == -1)
3450 Obj_Entry *obj;
3453 obj = elm->obj;
3454 if (obj->marker)
3456 if (resolve_object_ifunc(obj, bind_now, flags, lockstate) == -1)
3769 dlopen_cleanup(Obj_Entry *obj, RtldLockState *lockstate)
3771 obj->dl_refcount--;
3772 unref_dag(obj);
3773 if (obj->refcount == 0)
3774 unload_object(obj, lockstate);
3781 Obj_Entry *obj;
3798 obj = NULL;
3800 obj = obj_main;
3801 obj->refcount++;
3803 obj = load_object(name, fd, refobj, lo_flags);
3806 if (obj) {
3807 obj->dl_refcount++;
3809 objlist_find(&list_global, obj) == NULL)
3810 objlist_push_tail(&list_global, obj);
3812 if (!obj->init_done) {
3816 obj->deepbind = true;
3820 obj->static_tls && !allocate_tls_offset(obj)) {
3823 obj->path);
3827 result = load_needed_objects(obj,
3831 init_dag(obj);
3832 ref_dag(obj);
3834 result = rtld_verify_versions(&obj->dagmembers);
3838 relocate_object_dag(obj,
3842 dlopen_cleanup(obj, lockstate);
3843 obj = NULL;
3856 initlist_add_objects(obj, obj, &initlist);
3865 if (obj != NULL)
3866 process_z(obj);
3874 init_dag(obj);
3875 ref_dag(obj);
3880 if (obj != NULL &&
3881 ((lo_flags & RTLD_LO_NODELETE) != 0 || obj->z_nodelete) &&
3882 !obj->ref_nodel) {
3883 dbg("obj %s nodelete", obj->path);
3884 ref_dag(obj);
3885 obj->z_nodelete = obj->ref_nodel = true;
3889 LD_UTRACE(UTRACE_DLOPEN_STOP, obj, NULL, 0, obj ? obj->dl_refcount : 0,
3891 GDB_STATE(RT_CONSISTENT, obj ? &obj->linkmap : NULL);
3895 if (obj != NULL)
3904 dlopen_cleanup(obj, lockstate);
3917 return (obj);
3919 trace_loaded_objects(obj, false);
3930 const Obj_Entry *obj, *defobj;
3951 if ((obj = obj_from_addr(retaddr)) == NULL) {
3958 res = symlook_obj(&req, obj);
3966 obj = globallist_next(obj);
3967 for (; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
3968 if (obj->marker)
3970 res = symlook_obj(&req, obj);
4004 res = symlook_default(&req, obj);
4011 if ((obj = dlcheck(handle)) == NULL) {
4018 if (obj->mainprog) {
4042 res = symlook_list(&req, &obj->dagmembers, &donelist);
4115 const Obj_Entry *obj;
4119 obj = obj_from_addr(addr);
4120 if (obj == NULL) {
4125 rtld_fill_dl_phdr_info(obj, phdr_info);
4133 const Obj_Entry *obj;
4140 obj = obj_from_addr(addr);
4141 if (obj == NULL) {
4146 info->dli_fname = obj->path;
4147 info->dli_fbase = obj->mapbase;
4155 for (symoffset = 0; symoffset < obj->dynsymcount; symoffset++) {
4156 def = obj->symtab + symoffset;
4170 symbol_addr = obj->relocbase + def->st_value;
4175 info->dli_sname = obj->strtab + def->st_name;
4189 const Obj_Entry *obj;
4199 if ((obj = obj_from_addr(retaddr)) == NULL)
4202 obj = dlcheck(handle);
4204 if (obj == NULL) {
4212 *((struct link_map const **)p) = &obj->linkmap;
4215 error = rtld_dirname(obj->path, p);
4220 error = do_search_info(obj, request, (struct dl_serinfo *)p);
4234 rtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info)
4238 phdr_info->dlpi_addr = (Elf_Addr)obj->relocbase;
4239 phdr_info->dlpi_name = obj->path;
4240 phdr_info->dlpi_phdr = obj->phdr;
4241 phdr_info->dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]);
4242 phdr_info->dlpi_tls_modid = obj->tlsindex;
4245 obj->tlsindex, 0, true) + TLS_DTV_OFFSET;
4258 Obj_Entry *obj;
4261 for (obj = globallist_curr(TAILQ_FIRST(&obj_list)); obj != NULL;
4262 obj = globallist_next(obj)) {
4263 rtld_fill_dl_phdr_info(obj, &phdr_info);
4277 Obj_Entry *obj, marker;
4286 for (obj = globallist_curr(TAILQ_FIRST(&obj_list)); obj != NULL;) {
4287 TAILQ_INSERT_AFTER(&obj_list, obj, &marker, next);
4288 rtld_fill_dl_phdr_info(obj, &phdr_info);
4289 hold_object(obj);
4295 unhold_object(obj);
4296 obj = globallist_next(&marker);
4343 do_search_info(const Obj_Entry *obj, int request, struct dl_serinfo *info)
4354 path_enumerate(obj->rpath, fill_search_info, NULL, &args);
4356 path_enumerate(obj->runpath, fill_search_info, NULL, &args);
4357 path_enumerate(gethints(obj->z_nodeflib), fill_search_info, NULL,
4359 if (!obj->z_nodeflib)
4382 if (path_enumerate(obj->rpath, fill_search_info, NULL, &args) != NULL)
4391 if (path_enumerate(obj->runpath, fill_search_info, NULL, &args) != NULL)
4395 if (path_enumerate(gethints(obj->z_nodeflib), fill_search_info, NULL,
4400 if (!obj->z_nodeflib &&
4471 linkmap_add(Obj_Entry *obj)
4475 l = &obj->linkmap;
4476 l->l_name = obj->path;
4477 l->l_base = obj->mapbase;
4478 l->l_ld = obj->dynamic;
4479 l->l_addr = obj->relocbase;
4504 linkmap_delete(Obj_Entry *obj)
4508 l = &obj->linkmap;
4558 release_object(Obj_Entry *obj)
4560 if (obj->holdcount > 0) {
4561 obj->unholdfree = true;
4564 munmap(obj->mapbase, obj->mapsize);
4565 linkmap_delete(obj);
4566 obj_free(obj);
4641 res = symlook_list(&req1, &elm->obj->dagmembers, donelist);
4692 res = symlook_list(&req1, &elm->obj->dagmembers, &donelist);
4734 if (donelist_check(dlp, elm->obj))
4737 if ((res = symlook_obj(&req1, elm->obj)) == 0) {
4775 if (n->obj == NULL || (res = symlook_list(&req1,
4776 &n->obj->dagmembers, dlp)) != 0)
4796 symlook_obj_load_filtees(SymLook *req, SymLook *req1, const Obj_Entry *obj,
4803 load_filtees(__DECONST(Obj_Entry *, obj), flags, req->lockstate);
4819 symlook_obj(SymLook *req, const Obj_Entry *obj)
4828 if (obj->valid_hash_gnu)
4829 mres = symlook_obj1_gnu(req, obj);
4830 else if (obj->valid_hash_sysv)
4831 mres = symlook_obj1_sysv(req, obj);
4836 if (obj->needed_filtees != NULL) {
4837 res = symlook_obj_load_filtees(req, &req1, obj,
4838 obj->needed_filtees);
4845 if (obj->needed_aux_filtees != NULL) {
4846 res = symlook_obj_load_filtees(req, &req1, obj,
4847 obj->needed_aux_filtees);
4860 matched_symbol(SymLook *req, const Obj_Entry *obj, Sym_Match_Result *result,
4867 symp = obj->symtab + symnum;
4868 strp = obj->strtab + symp->st_name;
4893 if (obj->versyms != NULL) {
4894 verndx = VER_NDX(obj->versyms[symnum]);
4895 if (verndx > obj->vernum) {
4898 obj->path, obj->strtab + symnum, verndx);
4919 if ((obj->versyms[symnum] & VER_NDX_HIDDEN) ==
4931 if (obj->versyms == NULL) {
4932 if (object_match_name(obj, req->ventry->name)) {
4935 obj_rtld.path, obj->path, req->ventry->name,
4936 obj->strtab + symnum);
4940 verndx = VER_NDX(obj->versyms[symnum]);
4941 if (verndx > obj->vernum) {
4943 obj->path, obj->strtab + symnum, verndx);
4946 if (obj->vertab[verndx].hash != req->ventry->hash ||
4947 strcmp(obj->vertab[verndx].name, req->ventry->name)) {
4959 (obj->versyms[symnum] & VER_NDX_HIDDEN))
4969 * obj->buckets is known not to be NULL at this point; the test for this was
4970 * performed with the obj->valid_hash_sysv assignment.
4973 symlook_obj1_sysv(SymLook *req, const Obj_Entry *obj)
4982 for (symnum = obj->buckets[req->hash % obj->nbuckets];
4983 symnum != STN_UNDEF; symnum = obj->chains[symnum]) {
4984 if (symnum >= obj->nchains)
4987 if (matched_symbol(req, obj, &matchres, symnum)) {
4989 req->defobj_out = obj;
4995 req->defobj_out = obj;
5003 symlook_obj1_gnu(SymLook *req, const Obj_Entry *obj)
5017 bloom_word = obj->bloom_gnu[(req->hash_gnu / __ELF_WORD_SIZE) &
5018 obj->maskwords_bm_gnu];
5022 h2 = ((req->hash_gnu >> obj->shift2_gnu) & (__ELF_WORD_SIZE - 1));
5029 bucket = obj->buckets_gnu[req->hash_gnu % obj->nbuckets_gnu];
5032 hashval = &obj->chain_zero_gnu[bucket];
5035 symnum = hashval - obj->chain_zero_gnu;
5036 if (matched_symbol(req, obj, &matchres, symnum)) {
5038 req->defobj_out = obj;
5045 req->defobj_out = obj;
5068 trace_print_obj(Obj_Entry *obj, const char *name, const char *path,
5119 obj != NULL ? obj->mapbase : NULL);
5129 trace_loaded_objects(Obj_Entry *obj, bool show_preload)
5138 for (; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
5141 if (obj->marker)
5143 if (list_containers && obj->needed != NULL)
5144 rtld_printf("%s:\n", obj->path);
5145 for (needed = obj->needed; needed; needed = needed->next) {
5146 if (needed->obj != NULL) {
5147 if (needed->obj->traced && !list_containers)
5149 needed->obj->traced = true;
5150 path = needed->obj->path;
5154 name = obj->strtab + needed->name;
5155 trace_print_obj(needed->obj, name, path, main_local,
5165 TAILQ_FOREACH(obj, &obj_list, next) {
5166 if (obj->marker || obj == obj_main || obj->traced)
5174 Name_Entry *fname = STAILQ_FIRST(&obj->names);
5176 trace_print_obj(obj, name, obj->path, main_local, NULL,
5191 Obj_Entry marker, *obj, *next;
5202 for (obj = TAILQ_FIRST(&obj_list); obj != NULL; obj = next) {
5203 next = TAILQ_NEXT(obj, next);
5204 if (obj->marker || obj->refcount != 0)
5206 LD_UTRACE(UTRACE_UNLOAD_OBJECT, obj, obj->mapbase, obj->mapsize,
5207 0, obj->path);
5208 dbg("unloading \"%s\"", obj->path);
5214 TAILQ_REMOVE(&obj_list, obj, next);
5217 if (obj->filtees_loaded) {
5221 unload_filtees(obj, lockstate);
5225 unload_filtees(obj, lockstate);
5227 release_object(obj);
5242 objlist_remove(&elm->obj->dldags, root);
5243 if (elm->obj != root)
5244 unlink_object(elm->obj);
5256 elm->obj->refcount++;
5266 elm->obj->refcount--;
5357 Obj_Entry *obj;
5404 for (obj = globallist_curr(objs); obj != NULL;
5405 obj = globallist_next(obj)) {
5406 if (obj->tlsoffset == 0)
5408 tls_init_offset = obj->tlspoffset & (obj->tlsalign - 1);
5409 addr = (Elf_Addr)tcb + obj->tlsoffset;
5412 if (obj->tlsinitsize > 0) {
5414 obj->tlsinit, obj->tlsinitsize);
5416 if (obj->tlssize > obj->tlsinitsize) {
5418 obj->tlsinitsize),
5420 obj->tlssize - obj->tlsinitsize -
5423 dtv[obj->tlsindex + 1] = addr;
5469 Obj_Entry *obj;
5520 for (obj = objs; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
5521 if (obj->marker || obj->tlsoffset == 0)
5523 addr = segbase - obj->tlsoffset;
5524 memset((void *)(addr + obj->tlsinitsize), 0,
5525 obj->tlssize - obj->tlsinitsize);
5526 if (obj->tlsinit) {
5527 memcpy((void *)addr, obj->tlsinit,
5528 obj->tlsinitsize);
5529 obj->static_tls_copied = true;
5531 dtv[obj->tlsindex + 1] = addr;
5578 Obj_Entry *obj;
5581 TAILQ_FOREACH(obj, &obj_list, next) {
5582 if (obj->marker)
5584 if (obj->tlsindex == index)
5587 if (obj == NULL) {
5592 if (obj->tls_static) {
5594 p = (char *)_tcb_get() + obj->tlsoffset + TLS_TCB_SIZE;
5596 p = (char *)_tcb_get() - obj->tlsoffset;
5601 obj->tls_dynamic = true;
5603 p = xmalloc_aligned(obj->tlssize, obj->tlsalign, obj->tlspoffset);
5604 memcpy(p, obj->tlsinit, obj->tlsinitsize);
5605 memset(p + obj->tlsinitsize, 0, obj->tlssize - obj->tlsinitsize);
5610 allocate_tls_offset(Obj_Entry *obj)
5614 if (obj->tls_dynamic)
5617 if (obj->tls_static)
5620 if (obj->tlssize == 0) {
5621 obj->tls_static = true;
5626 off = calculate_first_tls_offset(obj->tlssize, obj->tlsalign,
5627 obj->tlspoffset);
5630 obj->tlssize, obj->tlsalign, obj->tlspoffset);
5632 obj->tlsoffset = off;
5634 off += obj->tlssize;
5646 } else if (obj->tlsalign > tls_static_max_align) {
5647 tls_static_max_align = obj->tlsalign;
5651 tls_last_size = obj->tlssize;
5652 obj->tls_static = true;
5658 free_tls_offset(Obj_Entry *obj)
5666 size_t off = obj->tlsoffset;
5669 off += obj->tlssize;
5672 tls_last_offset -= obj->tlssize;
5701 object_add_name(Obj_Entry *obj, const char *name)
5711 STAILQ_INSERT_TAIL(&obj->names, entry, link);
5716 object_match_name(const Obj_Entry *obj, const char *name)
5720 STAILQ_FOREACH(entry, &obj->names, link) {
5728 locate_dependency(const Obj_Entry *obj, const char *name)
5734 if (object_match_name(entry->obj, name))
5735 return (entry->obj);
5738 for (needed = obj->needed; needed != NULL; needed = needed->next) {
5739 if (strcmp(obj->strtab + needed->name, name) == 0 ||
5740 (needed->obj != NULL && object_match_name(needed->obj,
5749 return (needed->obj);
5753 obj->path, name);
5798 rtld_verify_object_versions(Obj_Entry *obj)
5807 if (obj->ver_checked)
5809 obj->ver_checked = true;
5817 vn = obj->verneed;
5822 obj->path, vn->vn_version);
5840 vd = obj->verdef;
5845 obj->path, vd->vd_version);
5864 obj->vernum = maxvernum + 1;
5865 obj->vertab = xcalloc(obj->vernum, sizeof(Ver_Entry));
5867 vd = obj->verdef;
5874 obj->vertab[vernum].hash = vd->vd_hash;
5875 obj->vertab[vernum].name = obj->strtab + vda->vda_name;
5876 obj->vertab[vernum].file = NULL;
5877 obj->vertab[vernum].flags = 0;
5884 vn = obj->verneed;
5886 depobj = locate_dependency(obj, obj->strtab + vn->vn_file);
5891 if (check_object_provided_version(obj, depobj, vna))
5895 obj->vertab[vernum].hash = vna->vna_hash;
5896 obj->vertab[vernum].name = obj->strtab + vna->vna_name;
5897 obj->vertab[vernum].file = obj->strtab + vn->vn_file;
5898 obj->vertab[vernum].flags = (vna->vna_other &
5924 if (entry->obj->strtab == NULL || entry->obj->vertab != NULL)
5926 if (rtld_verify_object_versions(entry->obj) == -1) {
5938 fetch_ventry(const Obj_Entry *obj, unsigned long symnum)
5942 if (obj->vertab) {
5943 vernum = VER_NDX(obj->versyms[symnum]);
5944 if (vernum >= obj->vernum) {
5946 obj->path, obj->strtab + symnum, vernum);
5947 } else if (obj->vertab[vernum].hash != 0) {
5948 return (&obj->vertab[vernum]);
5963 Obj_Entry *obj;
5968 obj = dlcheck(arg);
5969 if (obj == NULL)
5970 obj = obj_from_addr(arg);
5971 if (obj == NULL) {
5976 res = obj->dlopened ? 1 : 0;
5982 obj_remap_relro(Obj_Entry *obj, int prot)
5988 for (ph = obj->phdr; (const char *)ph < (const char *)obj->phdr +
5989 obj->phsize; ph++) {
5992 relro_page = obj->relocbase + rtld_trunc_page(ph->p_vaddr);
5998 obj->path, prot, rtld_strerror(errno));
6007 obj_disable_relro(Obj_Entry *obj)
6009 return (obj_remap_relro(obj, PROT_READ | PROT_WRITE));
6013 obj_enforce_relro(Obj_Entry *obj)
6015 return (obj_remap_relro(obj, PROT_READ));
6038 Obj_Entry *obj;
6047 obj = elm->obj;
6048 if (obj->marker || !obj->tls_static || obj->static_tls_copied)
6051 distrib(obj->tlsoffset, obj->tlsinit, obj->tlsinitsize,
6052 obj->tlssize);
6054 obj->static_tls_copied = true;