Deleted Added
full compact
rtld.c (232777) rtld.c (232831)
1/*-
2 * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
3 * Copyright 2003 Alexander Kabaev <kan@FreeBSD.ORG>.
4 * Copyright 2009, 2010, 2011 Konstantin Belousov <kib@FreeBSD.ORG>.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 10 unchanged lines hidden (view full) ---

19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
1/*-
2 * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
3 * Copyright 2003 Alexander Kabaev <kan@FreeBSD.ORG>.
4 * Copyright 2009, 2010, 2011 Konstantin Belousov <kib@FreeBSD.ORG>.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 10 unchanged lines hidden (view full) ---

19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * $FreeBSD: head/libexec/rtld-elf/rtld.c 232777 2012-03-10 08:49:44Z kib $
27 * $FreeBSD: head/libexec/rtld-elf/rtld.c 232831 2012-03-11 20:03:09Z kib $
28 */
29
30/*
31 * Dynamic linker for ELF.
32 *
33 * John Polstra <jdp@polstra.com>.
34 */
35

--- 20 unchanged lines hidden (view full) ---

56#include <string.h>
57#include <unistd.h>
58
59#include "debug.h"
60#include "rtld.h"
61#include "libmap.h"
62#include "rtld_tls.h"
63#include "rtld_printf.h"
28 */
29
30/*
31 * Dynamic linker for ELF.
32 *
33 * John Polstra <jdp@polstra.com>.
34 */
35

--- 20 unchanged lines hidden (view full) ---

56#include <string.h>
57#include <unistd.h>
58
59#include "debug.h"
60#include "rtld.h"
61#include "libmap.h"
62#include "rtld_tls.h"
63#include "rtld_printf.h"
64#include "notes.h"
64
65#ifndef COMPAT_32BIT
66#define PATH_RTLD "/libexec/ld-elf.so.1"
67#else
68#define PATH_RTLD "/libexec/ld-elf32.so.1"
69#endif
70
71/* Types. */

--- 62 unchanged lines hidden (view full) ---

134static void trace_loaded_objects(Obj_Entry *);
135static void unlink_object(Obj_Entry *);
136static void unload_object(Obj_Entry *);
137static void unref_dag(Obj_Entry *);
138static void ref_dag(Obj_Entry *);
139static int origin_subst_one(char **, const char *, const char *,
140 const char *, char *);
141static char *origin_subst(const char *, const char *);
65
66#ifndef COMPAT_32BIT
67#define PATH_RTLD "/libexec/ld-elf.so.1"
68#else
69#define PATH_RTLD "/libexec/ld-elf32.so.1"
70#endif
71
72/* Types. */

--- 62 unchanged lines hidden (view full) ---

135static void trace_loaded_objects(Obj_Entry *);
136static void unlink_object(Obj_Entry *);
137static void unload_object(Obj_Entry *);
138static void unref_dag(Obj_Entry *);
139static void ref_dag(Obj_Entry *);
140static int origin_subst_one(char **, const char *, const char *,
141 const char *, char *);
142static char *origin_subst(const char *, const char *);
143static void preinit_main(void);
142static int rtld_verify_versions(const Objlist *);
143static int rtld_verify_object_versions(Obj_Entry *);
144static void object_add_name(Obj_Entry *, const char *);
145static int object_match_name(const Obj_Entry *, const char *);
146static void ld_utrace_log(int, void *, void *, size_t, int, const char *);
147static void rtld_fill_dl_phdr_info(const Obj_Entry *obj,
148 struct dl_phdr_info *phdr_info);
149

--- 50 unchanged lines hidden (view full) ---

200/*
201 * Global declarations normally provided by crt1. The dynamic linker is
202 * not built with crt1, so we have to provide them ourselves.
203 */
204char *__progname;
205char **environ;
206
207/*
144static int rtld_verify_versions(const Objlist *);
145static int rtld_verify_object_versions(Obj_Entry *);
146static void object_add_name(Obj_Entry *, const char *);
147static int object_match_name(const Obj_Entry *, const char *);
148static void ld_utrace_log(int, void *, void *, size_t, int, const char *);
149static void rtld_fill_dl_phdr_info(const Obj_Entry *obj,
150 struct dl_phdr_info *phdr_info);
151

--- 50 unchanged lines hidden (view full) ---

202/*
203 * Global declarations normally provided by crt1. The dynamic linker is
204 * not built with crt1, so we have to provide them ourselves.
205 */
206char *__progname;
207char **environ;
208
209/*
210 * Used to pass argc, argv to init functions.
211 */
212int main_argc;
213char **main_argv;
214
215/*
208 * Globals to control TLS allocation.
209 */
210size_t tls_last_offset; /* Static TLS offset of last module */
211size_t tls_last_size; /* Static TLS size of last module */
212size_t tls_static_space; /* Static TLS space allocated */
213int tls_dtv_generation = 1; /* Used to detect when dtv size changes */
214int tls_max_index = 1; /* Largest module index allocated */
215

--- 114 unchanged lines hidden (view full) ---

330
331 /* Initialize and relocate ourselves. */
332 assert(aux_info[AT_BASE] != NULL);
333 init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr, aux_info);
334
335 __progname = obj_rtld.path;
336 argv0 = argv[0] != NULL ? argv[0] : "(null)";
337 environ = env;
216 * Globals to control TLS allocation.
217 */
218size_t tls_last_offset; /* Static TLS offset of last module */
219size_t tls_last_size; /* Static TLS size of last module */
220size_t tls_static_space; /* Static TLS space allocated */
221int tls_dtv_generation = 1; /* Used to detect when dtv size changes */
222int tls_max_index = 1; /* Largest module index allocated */
223

--- 114 unchanged lines hidden (view full) ---

338
339 /* Initialize and relocate ourselves. */
340 assert(aux_info[AT_BASE] != NULL);
341 init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr, aux_info);
342
343 __progname = obj_rtld.path;
344 argv0 = argv[0] != NULL ? argv[0] : "(null)";
345 environ = env;
346 main_argc = argc;
347 main_argv = argv;
338
339 trust = !issetugid();
340
341 ld_bind_now = getenv(LD_ "BIND_NOW");
342 /*
343 * If the process is tainted, then we un-set the dangerous environment
344 * variables. The process will be marked as tainted until setuid(2)
345 * is called. If any child process calls setuid(2) we do not want any

--- 107 unchanged lines hidden (view full) ---

453 linkmap_add(obj_main);
454 linkmap_add(&obj_rtld);
455
456 /* Link the main program into the list of objects. */
457 *obj_tail = obj_main;
458 obj_tail = &obj_main->next;
459 obj_count++;
460 obj_loads++;
348
349 trust = !issetugid();
350
351 ld_bind_now = getenv(LD_ "BIND_NOW");
352 /*
353 * If the process is tainted, then we un-set the dangerous environment
354 * variables. The process will be marked as tainted until setuid(2)
355 * is called. If any child process calls setuid(2) we do not want any

--- 107 unchanged lines hidden (view full) ---

463 linkmap_add(obj_main);
464 linkmap_add(&obj_rtld);
465
466 /* Link the main program into the list of objects. */
467 *obj_tail = obj_main;
468 obj_tail = &obj_main->next;
469 obj_count++;
470 obj_loads++;
461 /* Make sure we don't call the main program's init and fini functions. */
462 obj_main->init = obj_main->fini = (Elf_Addr)NULL;
463
464 /* Initialize a fake symbol for resolving undefined weak references. */
465 sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
466 sym_zero.st_shndx = SHN_UNDEF;
467 sym_zero.st_value = -(uintptr_t)obj_main->relocbase;
468
469 if (!libmap_disable)
470 libmap_disable = (bool)lm_init(libmap_override);

--- 75 unchanged lines hidden (view full) ---

546
547 map_stacks_exec(NULL);
548
549 dbg("resolving ifuncs");
550 if (resolve_objects_ifunc(obj_main,
551 ld_bind_now != NULL && *ld_bind_now != '\0', NULL) == -1)
552 die();
553
471
472 /* Initialize a fake symbol for resolving undefined weak references. */
473 sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
474 sym_zero.st_shndx = SHN_UNDEF;
475 sym_zero.st_value = -(uintptr_t)obj_main->relocbase;
476
477 if (!libmap_disable)
478 libmap_disable = (bool)lm_init(libmap_override);

--- 75 unchanged lines hidden (view full) ---

554
555 map_stacks_exec(NULL);
556
557 dbg("resolving ifuncs");
558 if (resolve_objects_ifunc(obj_main,
559 ld_bind_now != NULL && *ld_bind_now != '\0', NULL) == -1)
560 die();
561
562 if (!obj_main->crt_no_init) {
563 /*
564 * Make sure we don't call the main program's init and fini
565 * functions for binaries linked with old crt1 which calls
566 * _init itself.
567 */
568 obj_main->init = obj_main->fini = (Elf_Addr)NULL;
569 obj_main->preinit_array = obj_main->init_array =
570 obj_main->fini_array = (Elf_Addr)NULL;
571 }
572
554 wlock_acquire(rtld_bind_lock, &lockstate);
573 wlock_acquire(rtld_bind_lock, &lockstate);
574 if (obj_main->crt_no_init)
575 preinit_main();
555 objlist_call_init(&initlist, &lockstate);
556 objlist_clear(&initlist);
557 dbg("loading filtees");
558 for (obj = obj_list->next; obj != NULL; obj = obj->next) {
559 if (ld_loadfltr || obj->z_loadfltr)
560 load_filtees(obj, 0, &lockstate);
561 }
562 lock_release(rtld_bind_lock, &lockstate);

--- 368 unchanged lines hidden (view full) ---

931 case DT_SONAME:
932 *dyn_soname = dynp;
933 break;
934
935 case DT_INIT:
936 obj->init = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
937 break;
938
576 objlist_call_init(&initlist, &lockstate);
577 objlist_clear(&initlist);
578 dbg("loading filtees");
579 for (obj = obj_list->next; obj != NULL; obj = obj->next) {
580 if (ld_loadfltr || obj->z_loadfltr)
581 load_filtees(obj, 0, &lockstate);
582 }
583 lock_release(rtld_bind_lock, &lockstate);

--- 368 unchanged lines hidden (view full) ---

952 case DT_SONAME:
953 *dyn_soname = dynp;
954 break;
955
956 case DT_INIT:
957 obj->init = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
958 break;
959
960 case DT_PREINIT_ARRAY:
961 obj->preinit_array = (Elf_Addr)(obj->relocbase + dynp->d_un.d_ptr);
962 break;
963
964 case DT_PREINIT_ARRAYSZ:
965 obj->preinit_array_num = dynp->d_un.d_val / sizeof(Elf_Addr);
966 break;
967
968 case DT_INIT_ARRAY:
969 obj->init_array = (Elf_Addr)(obj->relocbase + dynp->d_un.d_ptr);
970 break;
971
972 case DT_INIT_ARRAYSZ:
973 obj->init_array_num = dynp->d_un.d_val / sizeof(Elf_Addr);
974 break;
975
939 case DT_FINI:
940 obj->fini = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
941 break;
942
976 case DT_FINI:
977 obj->fini = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
978 break;
979
980 case DT_FINI_ARRAY:
981 obj->fini_array = (Elf_Addr)(obj->relocbase + dynp->d_un.d_ptr);
982 break;
983
984 case DT_FINI_ARRAYSZ:
985 obj->fini_array_num = dynp->d_un.d_val / sizeof(Elf_Addr);
986 break;
987
943 /*
944 * Don't process DT_DEBUG on MIPS as the dynamic section
945 * is mapped read-only. DT_MIPS_RLD_MAP is used instead.
946 */
947
948#ifndef __mips__
949 case DT_DEBUG:
950 /* XXX - not implemented yet */

--- 109 unchanged lines hidden (view full) ---

1060 * returns an Obj_Entry structure.
1061 */
1062static Obj_Entry *
1063digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path)
1064{
1065 Obj_Entry *obj;
1066 const Elf_Phdr *phlimit = phdr + phnum;
1067 const Elf_Phdr *ph;
988 /*
989 * Don't process DT_DEBUG on MIPS as the dynamic section
990 * is mapped read-only. DT_MIPS_RLD_MAP is used instead.
991 */
992
993#ifndef __mips__
994 case DT_DEBUG:
995 /* XXX - not implemented yet */

--- 109 unchanged lines hidden (view full) ---

1105 * returns an Obj_Entry structure.
1106 */
1107static Obj_Entry *
1108digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path)
1109{
1110 Obj_Entry *obj;
1111 const Elf_Phdr *phlimit = phdr + phnum;
1112 const Elf_Phdr *ph;
1113 Elf_Addr note_start, note_end;
1068 int nsegs = 0;
1069
1070 obj = obj_new();
1071 for (ph = phdr; ph < phlimit; ph++) {
1072 if (ph->p_type != PT_PHDR)
1073 continue;
1074
1075 obj->phdr = phdr;

--- 39 unchanged lines hidden (view full) ---

1115 case PT_GNU_STACK:
1116 obj->stack_flags = ph->p_flags;
1117 break;
1118
1119 case PT_GNU_RELRO:
1120 obj->relro_page = obj->relocbase + trunc_page(ph->p_vaddr);
1121 obj->relro_size = round_page(ph->p_memsz);
1122 break;
1114 int nsegs = 0;
1115
1116 obj = obj_new();
1117 for (ph = phdr; ph < phlimit; ph++) {
1118 if (ph->p_type != PT_PHDR)
1119 continue;
1120
1121 obj->phdr = phdr;

--- 39 unchanged lines hidden (view full) ---

1161 case PT_GNU_STACK:
1162 obj->stack_flags = ph->p_flags;
1163 break;
1164
1165 case PT_GNU_RELRO:
1166 obj->relro_page = obj->relocbase + trunc_page(ph->p_vaddr);
1167 obj->relro_size = round_page(ph->p_memsz);
1168 break;
1169
1170 case PT_NOTE:
1171 note_start = (Elf_Addr)obj->relocbase + ph->p_vaddr;
1172 note_end = note_start + ph->p_filesz;
1173 digest_notes(obj, note_start, note_end);
1174 break;
1123 }
1124 }
1125 if (nsegs < 1) {
1126 _rtld_error("%s: too few PT_LOAD segments", path);
1127 return NULL;
1128 }
1129
1130 obj->entry = entry;
1131 return obj;
1132}
1133
1175 }
1176 }
1177 if (nsegs < 1) {
1178 _rtld_error("%s: too few PT_LOAD segments", path);
1179 return NULL;
1180 }
1181
1182 obj->entry = entry;
1183 return obj;
1184}
1185
1186void
1187digest_notes(Obj_Entry *obj, Elf_Addr note_start, Elf_Addr note_end)
1188{
1189 const Elf_Note *note;
1190 const char *note_name;
1191 uintptr_t p;
1192
1193 for (note = (const Elf_Note *)note_start; (Elf_Addr)note < note_end;
1194 note = (const Elf_Note *)((const char *)(note + 1) +
1195 roundup2(note->n_namesz, sizeof(Elf32_Addr)) +
1196 roundup2(note->n_descsz, sizeof(Elf32_Addr)))) {
1197 if (note->n_namesz != sizeof(NOTE_FREEBSD_VENDOR) ||
1198 note->n_descsz != sizeof(int32_t))
1199 continue;
1200 if (note->n_type != ABI_NOTETYPE &&
1201 note->n_type != CRT_NOINIT_NOTETYPE)
1202 continue;
1203 note_name = (const char *)(note + 1);
1204 if (strncmp(NOTE_FREEBSD_VENDOR, note_name,
1205 sizeof(NOTE_FREEBSD_VENDOR)) != 0)
1206 continue;
1207 switch (note->n_type) {
1208 case ABI_NOTETYPE:
1209 /* FreeBSD osrel note */
1210 p = (uintptr_t)(note + 1);
1211 p += roundup2(note->n_namesz, sizeof(Elf32_Addr));
1212 obj->osrel = *(const int32_t *)(p);
1213 dbg("note osrel %d", obj->osrel);
1214 break;
1215 case CRT_NOINIT_NOTETYPE:
1216 /* FreeBSD 'crt does not call init' note */
1217 obj->crt_no_init = true;
1218 dbg("note crt_no_init");
1219 break;
1220 }
1221 }
1222}
1223
1134static Obj_Entry *
1135dlcheck(void *handle)
1136{
1137 Obj_Entry *obj;
1138
1139 for (obj = obj_list; obj != NULL; obj = obj->next)
1140 if (obj == (Obj_Entry *) handle)
1141 break;

--- 357 unchanged lines hidden (view full) ---

1499 if (&obj->next != tail)
1500 initlist_add_objects(obj->next, tail, list);
1501
1502 /* Recursively process the needed objects. */
1503 if (obj->needed != NULL)
1504 initlist_add_neededs(obj->needed, list);
1505
1506 /* Add the object to the init list. */
1224static Obj_Entry *
1225dlcheck(void *handle)
1226{
1227 Obj_Entry *obj;
1228
1229 for (obj = obj_list; obj != NULL; obj = obj->next)
1230 if (obj == (Obj_Entry *) handle)
1231 break;

--- 357 unchanged lines hidden (view full) ---

1589 if (&obj->next != tail)
1590 initlist_add_objects(obj->next, tail, list);
1591
1592 /* Recursively process the needed objects. */
1593 if (obj->needed != NULL)
1594 initlist_add_neededs(obj->needed, list);
1595
1596 /* Add the object to the init list. */
1507 if (obj->init != (Elf_Addr)NULL)
1597 if (obj->preinit_array != (Elf_Addr)NULL || obj->init != (Elf_Addr)NULL ||
1598 obj->init_array != (Elf_Addr)NULL)
1508 objlist_push_tail(list, obj);
1509
1510 /* Add the object to the global fini list in the reverse order. */
1599 objlist_push_tail(list, obj);
1600
1601 /* Add the object to the global fini list in the reverse order. */
1511 if (obj->fini != (Elf_Addr)NULL && !obj->on_fini_list) {
1602 if ((obj->fini != (Elf_Addr)NULL || obj->fini_array != (Elf_Addr)NULL)
1603 && !obj->on_fini_list) {
1512 objlist_push_head(&list_fini, obj);
1513 obj->on_fini_list = true;
1514 }
1515}
1516
1517#ifndef FPTR_TARGET
1518#define FPTR_TARGET(f) ((Elf_Addr) (f))
1519#endif

--- 271 unchanged lines hidden (view full) ---

1791 if (addr < (void *) obj->mapbase)
1792 continue;
1793 if (addr < (void *) (obj->mapbase + obj->mapsize))
1794 return obj;
1795 }
1796 return NULL;
1797}
1798
1604 objlist_push_head(&list_fini, obj);
1605 obj->on_fini_list = true;
1606 }
1607}
1608
1609#ifndef FPTR_TARGET
1610#define FPTR_TARGET(f) ((Elf_Addr) (f))
1611#endif

--- 271 unchanged lines hidden (view full) ---

1883 if (addr < (void *) obj->mapbase)
1884 continue;
1885 if (addr < (void *) (obj->mapbase + obj->mapsize))
1886 return obj;
1887 }
1888 return NULL;
1889}
1890
1891static void
1892preinit_main(void)
1893{
1894 Elf_Addr *preinit_addr;
1895 int index;
1896
1897 preinit_addr = (Elf_Addr *)obj_main->preinit_array;
1898 if (preinit_addr == (Elf_Addr)NULL)
1899 return;
1900
1901 for (index = 0; index < obj_main->preinit_array_num; index++) {
1902 if (preinit_addr[index] != 0 && preinit_addr[index] != 1) {
1903 dbg("calling preinit function for %s at %p", obj_main->path,
1904 (void *)preinit_addr[index]);
1905 LD_UTRACE(UTRACE_INIT_CALL, obj_main, (void *)preinit_addr[index],
1906 0, 0, obj_main->path);
1907 call_init_pointer(obj_main, preinit_addr[index]);
1908 }
1909 }
1910}
1911
1799/*
1800 * Call the finalization functions for each of the objects in "list"
1801 * belonging to the DAG of "root" and referenced once. If NULL "root"
1802 * is specified, every finalization function will be called regardless
1803 * of the reference count and the list elements won't be freed. All of
1804 * the objects are expected to have non-NULL fini functions.
1805 */
1806static void
1807objlist_call_fini(Objlist *list, Obj_Entry *root, RtldLockState *lockstate)
1808{
1809 Objlist_Entry *elm;
1810 char *saved_msg;
1912/*
1913 * Call the finalization functions for each of the objects in "list"
1914 * belonging to the DAG of "root" and referenced once. If NULL "root"
1915 * is specified, every finalization function will be called regardless
1916 * of the reference count and the list elements won't be freed. All of
1917 * the objects are expected to have non-NULL fini functions.
1918 */
1919static void
1920objlist_call_fini(Objlist *list, Obj_Entry *root, RtldLockState *lockstate)
1921{
1922 Objlist_Entry *elm;
1923 char *saved_msg;
1924 Elf_Addr *fini_addr;
1925 int index;
1811
1812 assert(root == NULL || root->refcount == 1);
1813
1814 /*
1815 * Preserve the current error message since a fini function might
1816 * call into the dynamic linker and overwrite it.
1817 */
1818 saved_msg = errmsg_save();
1819 do {
1820 STAILQ_FOREACH(elm, list, link) {
1821 if (root != NULL && (elm->obj->refcount != 1 ||
1822 objlist_find(&root->dagmembers, elm->obj) == NULL))
1823 continue;
1926
1927 assert(root == NULL || root->refcount == 1);
1928
1929 /*
1930 * Preserve the current error message since a fini function might
1931 * call into the dynamic linker and overwrite it.
1932 */
1933 saved_msg = errmsg_save();
1934 do {
1935 STAILQ_FOREACH(elm, list, link) {
1936 if (root != NULL && (elm->obj->refcount != 1 ||
1937 objlist_find(&root->dagmembers, elm->obj) == NULL))
1938 continue;
1824 dbg("calling fini function for %s at %p", elm->obj->path,
1825 (void *)elm->obj->fini);
1826 LD_UTRACE(UTRACE_FINI_CALL, elm->obj, (void *)elm->obj->fini, 0, 0,
1827 elm->obj->path);
1828 /* Remove object from fini list to prevent recursive invocation. */
1829 STAILQ_REMOVE(list, elm, Struct_Objlist_Entry, link);
1830 /*
1831 * XXX: If a dlopen() call references an object while the
1832 * fini function is in progress, we might end up trying to
1833 * unload the referenced object in dlclose() or the object
1834 * won't be unloaded although its fini function has been
1835 * called.
1836 */
1837 lock_release(rtld_bind_lock, lockstate);
1939 /* Remove object from fini list to prevent recursive invocation. */
1940 STAILQ_REMOVE(list, elm, Struct_Objlist_Entry, link);
1941 /*
1942 * XXX: If a dlopen() call references an object while the
1943 * fini function is in progress, we might end up trying to
1944 * unload the referenced object in dlclose() or the object
1945 * won't be unloaded although its fini function has been
1946 * called.
1947 */
1948 lock_release(rtld_bind_lock, lockstate);
1838 call_initfini_pointer(elm->obj, elm->obj->fini);
1949
1950 /*
1951 * It is legal to have both DT_FINI and DT_FINI_ARRAY defined.
1952 * When this happens, DT_FINI_ARRAY is processed first.
1953 */
1954 fini_addr = (Elf_Addr *)elm->obj->fini_array;
1955 if (fini_addr != NULL && elm->obj->fini_array_num > 0) {
1956 for (index = elm->obj->fini_array_num - 1; index >= 0;
1957 index--) {
1958 if (fini_addr[index] != 0 && fini_addr[index] != 1) {
1959 dbg("calling fini function for %s at %p",
1960 elm->obj->path, (void *)fini_addr[index]);
1961 LD_UTRACE(UTRACE_FINI_CALL, elm->obj,
1962 (void *)fini_addr[index], 0, 0, elm->obj->path);
1963 call_initfini_pointer(elm->obj, fini_addr[index]);
1964 }
1965 }
1966 }
1967 if (elm->obj->fini != (Elf_Addr)NULL) {
1968 dbg("calling fini function for %s at %p", elm->obj->path,
1969 (void *)elm->obj->fini);
1970 LD_UTRACE(UTRACE_FINI_CALL, elm->obj, (void *)elm->obj->fini,
1971 0, 0, elm->obj->path);
1972 call_initfini_pointer(elm->obj, elm->obj->fini);
1973 }
1839 wlock_acquire(rtld_bind_lock, lockstate);
1840 /* No need to free anything if process is going down. */
1841 if (root != NULL)
1842 free(elm);
1843 /*
1844 * We must restart the list traversal after every fini call
1845 * because a dlclose() call from the fini function or from
1846 * another thread might have modified the reference counts.

--- 10 unchanged lines hidden (view full) ---

1857 * functions.
1858 */
1859static void
1860objlist_call_init(Objlist *list, RtldLockState *lockstate)
1861{
1862 Objlist_Entry *elm;
1863 Obj_Entry *obj;
1864 char *saved_msg;
1974 wlock_acquire(rtld_bind_lock, lockstate);
1975 /* No need to free anything if process is going down. */
1976 if (root != NULL)
1977 free(elm);
1978 /*
1979 * We must restart the list traversal after every fini call
1980 * because a dlclose() call from the fini function or from
1981 * another thread might have modified the reference counts.

--- 10 unchanged lines hidden (view full) ---

1992 * functions.
1993 */
1994static void
1995objlist_call_init(Objlist *list, RtldLockState *lockstate)
1996{
1997 Objlist_Entry *elm;
1998 Obj_Entry *obj;
1999 char *saved_msg;
2000 Elf_Addr *init_addr;
2001 int index;
1865
1866 /*
1867 * Clean init_scanned flag so that objects can be rechecked and
1868 * possibly initialized earlier if any of vectors called below
1869 * cause the change by using dlopen.
1870 */
1871 for (obj = obj_list; obj != NULL; obj = obj->next)
1872 obj->init_scanned = false;
1873
1874 /*
1875 * Preserve the current error message since an init function might
1876 * call into the dynamic linker and overwrite it.
1877 */
1878 saved_msg = errmsg_save();
1879 STAILQ_FOREACH(elm, list, link) {
1880 if (elm->obj->init_done) /* Initialized early. */
1881 continue;
2002
2003 /*
2004 * Clean init_scanned flag so that objects can be rechecked and
2005 * possibly initialized earlier if any of vectors called below
2006 * cause the change by using dlopen.
2007 */
2008 for (obj = obj_list; obj != NULL; obj = obj->next)
2009 obj->init_scanned = false;
2010
2011 /*
2012 * Preserve the current error message since an init function might
2013 * call into the dynamic linker and overwrite it.
2014 */
2015 saved_msg = errmsg_save();
2016 STAILQ_FOREACH(elm, list, link) {
2017 if (elm->obj->init_done) /* Initialized early. */
2018 continue;
1882 dbg("calling init function for %s at %p", elm->obj->path,
1883 (void *)elm->obj->init);
1884 LD_UTRACE(UTRACE_INIT_CALL, elm->obj, (void *)elm->obj->init, 0, 0,
1885 elm->obj->path);
1886 /*
1887 * Race: other thread might try to use this object before current
1888 * one completes the initilization. Not much can be done here
1889 * without better locking.
1890 */
1891 elm->obj->init_done = true;
1892 lock_release(rtld_bind_lock, lockstate);
2019 /*
2020 * Race: other thread might try to use this object before current
2021 * one completes the initilization. Not much can be done here
2022 * without better locking.
2023 */
2024 elm->obj->init_done = true;
2025 lock_release(rtld_bind_lock, lockstate);
1893 call_initfini_pointer(elm->obj, elm->obj->init);
2026
2027 /*
2028 * It is legal to have both DT_INIT and DT_INIT_ARRAY defined.
2029 * When this happens, DT_INIT is processed first.
2030 */
2031 if (elm->obj->init != (Elf_Addr)NULL) {
2032 dbg("calling init function for %s at %p", elm->obj->path,
2033 (void *)elm->obj->init);
2034 LD_UTRACE(UTRACE_INIT_CALL, elm->obj, (void *)elm->obj->init,
2035 0, 0, elm->obj->path);
2036 call_initfini_pointer(elm->obj, elm->obj->init);
2037 }
2038 init_addr = (Elf_Addr *)elm->obj->init_array;
2039 if (init_addr != (Elf_Addr)NULL) {
2040 for (index = 0; index < elm->obj->init_array_num; index++) {
2041 if (init_addr[index] != 0 && init_addr[index] != 1) {
2042 dbg("calling init function for %s at %p", elm->obj->path,
2043 (void *)init_addr[index]);
2044 LD_UTRACE(UTRACE_INIT_CALL, elm->obj,
2045 (void *)init_addr[index], 0, 0, elm->obj->path);
2046 call_init_pointer(elm->obj, init_addr[index]);
2047 }
2048 }
2049 }
1894 wlock_acquire(rtld_bind_lock, lockstate);
1895 }
1896 errmsg_restore(saved_msg);
1897}
1898
1899static void
1900objlist_clear(Objlist *list)
1901{

--- 2258 unchanged lines hidden ---
2050 wlock_acquire(rtld_bind_lock, lockstate);
2051 }
2052 errmsg_restore(saved_msg);
2053}
2054
2055static void
2056objlist_clear(Objlist *list)
2057{

--- 2258 unchanged lines hidden ---