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

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

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

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

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

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

105static void initlist_add_neededs(Needed_Entry *, Objlist *);
106static void initlist_add_objects(Obj_Entry *, Obj_Entry **, Objlist *);
107static void linkmap_add(Obj_Entry *);
108static void linkmap_delete(Obj_Entry *);
109static int load_needed_objects(Obj_Entry *, int);
110static int load_preload_objects(void);
111static Obj_Entry *load_object(const char *, const Obj_Entry *, int);
112static Obj_Entry *obj_from_addr(const void *);
27 */
28
29/*
30 * Dynamic linker for ELF.
31 *
32 * John Polstra <jdp@polstra.com>.
33 */
34

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

105static void initlist_add_neededs(Needed_Entry *, Objlist *);
106static void initlist_add_objects(Obj_Entry *, Obj_Entry **, Objlist *);
107static void linkmap_add(Obj_Entry *);
108static void linkmap_delete(Obj_Entry *);
109static int load_needed_objects(Obj_Entry *, int);
110static int load_preload_objects(void);
111static Obj_Entry *load_object(const char *, const Obj_Entry *, int);
112static Obj_Entry *obj_from_addr(const void *);
113static void objlist_call_fini(Objlist *, bool, int *);
113static void objlist_call_fini(Objlist *, Obj_Entry *, int *);
114static void objlist_call_init(Objlist *, int *);
115static void objlist_clear(Objlist *);
116static Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *);
117static void objlist_init(Objlist *);
118static void objlist_push_head(Objlist *, Obj_Entry *);
119static void objlist_push_tail(Objlist *, Obj_Entry *);
120static void objlist_remove(Objlist *, Obj_Entry *);
121static void *path_enumerate(const char *, path_enum_proc, void *);

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

1604 if (addr < (void *) (obj->mapbase + obj->mapsize))
1605 return obj;
1606 }
1607 return NULL;
1608}
1609
1610/*
1611 * Call the finalization functions for each of the objects in "list"
114static void objlist_call_init(Objlist *, int *);
115static void objlist_clear(Objlist *);
116static Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *);
117static void objlist_init(Objlist *);
118static void objlist_push_head(Objlist *, Obj_Entry *);
119static void objlist_push_tail(Objlist *, Obj_Entry *);
120static void objlist_remove(Objlist *, Obj_Entry *);
121static void *path_enumerate(const char *, path_enum_proc, void *);

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

1604 if (addr < (void *) (obj->mapbase + obj->mapsize))
1605 return obj;
1606 }
1607 return NULL;
1608}
1609
1610/*
1611 * Call the finalization functions for each of the objects in "list"
1612 * which are unreferenced. All of the objects are expected to have
1613 * non-NULL fini functions.
1612 * belonging to the DAG of "root" and referenced once. If NULL "root"
1613 * is specified, every finalization function will be called regardless
1614 * of the reference count and the list elements won't be freed. All of
1615 * the objects are expected to have non-NULL fini functions.
1614 */
1615static void
1616 */
1617static void
1616objlist_call_fini(Objlist *list, bool force, int *lockstate)
1618objlist_call_fini(Objlist *list, Obj_Entry *root, int *lockstate)
1617{
1619{
1618 Objlist_Entry *elm, *elm_tmp;
1620 Objlist_Entry *elm;
1619 char *saved_msg;
1620
1621 char *saved_msg;
1622
1623 assert(root == NULL || root->refcount == 1);
1624
1621 /*
1622 * Preserve the current error message since a fini function might
1623 * call into the dynamic linker and overwrite it.
1624 */
1625 saved_msg = errmsg_save();
1625 /*
1626 * Preserve the current error message since a fini function might
1627 * call into the dynamic linker and overwrite it.
1628 */
1629 saved_msg = errmsg_save();
1626 STAILQ_FOREACH_SAFE(elm, list, link, elm_tmp) {
1627 if (elm->obj->refcount == 0 || force) {
1630 do {
1631 STAILQ_FOREACH(elm, list, link) {
1632 if (root != NULL && (elm->obj->refcount != 1 ||
1633 objlist_find(&root->dagmembers, elm->obj) == NULL))
1634 continue;
1628 dbg("calling fini function for %s at %p", elm->obj->path,
1629 (void *)elm->obj->fini);
1630 LD_UTRACE(UTRACE_FINI_CALL, elm->obj, (void *)elm->obj->fini, 0, 0,
1631 elm->obj->path);
1632 /* Remove object from fini list to prevent recursive invocation. */
1633 STAILQ_REMOVE(list, elm, Struct_Objlist_Entry, link);
1635 dbg("calling fini function for %s at %p", elm->obj->path,
1636 (void *)elm->obj->fini);
1637 LD_UTRACE(UTRACE_FINI_CALL, elm->obj, (void *)elm->obj->fini, 0, 0,
1638 elm->obj->path);
1639 /* Remove object from fini list to prevent recursive invocation. */
1640 STAILQ_REMOVE(list, elm, Struct_Objlist_Entry, link);
1641 /*
1642 * XXX: If a dlopen() call references an object while the
1643 * fini function is in progress, we might end up trying to
1644 * unload the referenced object in dlclose() or the object
1645 * won't be unloaded although its fini function has been
1646 * called.
1647 */
1634 wlock_release(rtld_bind_lock, *lockstate);
1635 call_initfini_pointer(elm->obj, elm->obj->fini);
1636 *lockstate = wlock_acquire(rtld_bind_lock);
1637 /* No need to free anything if process is going down. */
1648 wlock_release(rtld_bind_lock, *lockstate);
1649 call_initfini_pointer(elm->obj, elm->obj->fini);
1650 *lockstate = wlock_acquire(rtld_bind_lock);
1651 /* No need to free anything if process is going down. */
1638 if (!force)
1652 if (root != NULL)
1639 free(elm);
1653 free(elm);
1654 /*
1655 * We must restart the list traversal after every fini call
1656 * because a dlclose() call from the fini function or from
1657 * another thread might have modified the reference counts.
1658 */
1659 break;
1640 }
1660 }
1641 }
1661 } while (elm != NULL);
1642 errmsg_restore(saved_msg);
1643}
1644
1645/*
1646 * Call the initialization functions for each of the objects in
1647 * "list". All of the objects are expected to have non-NULL init
1648 * functions.
1649 */

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

1821 */
1822static void
1823rtld_exit(void)
1824{
1825 int lockstate;
1826
1827 lockstate = wlock_acquire(rtld_bind_lock);
1828 dbg("rtld_exit()");
1662 errmsg_restore(saved_msg);
1663}
1664
1665/*
1666 * Call the initialization functions for each of the objects in
1667 * "list". All of the objects are expected to have non-NULL init
1668 * functions.
1669 */

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

1841 */
1842static void
1843rtld_exit(void)
1844{
1845 int lockstate;
1846
1847 lockstate = wlock_acquire(rtld_bind_lock);
1848 dbg("rtld_exit()");
1829 objlist_call_fini(&list_fini, true, &lockstate);
1849 objlist_call_fini(&list_fini, NULL, &lockstate);
1830 /* No need to remove the items from the list, since we are exiting. */
1831 if (!libmap_disable)
1832 lm_fini();
1833 wlock_release(rtld_bind_lock, lockstate);
1834}
1835
1836static void *
1837path_enumerate(const char *path, path_enum_proc callback, void *arg)

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

1934 return -1;
1935 }
1936 LD_UTRACE(UTRACE_DLCLOSE_START, handle, NULL, 0, root->dl_refcount,
1937 root->path);
1938
1939 /* Unreference the object and its dependencies. */
1940 root->dl_refcount--;
1941
1850 /* No need to remove the items from the list, since we are exiting. */
1851 if (!libmap_disable)
1852 lm_fini();
1853 wlock_release(rtld_bind_lock, lockstate);
1854}
1855
1856static void *
1857path_enumerate(const char *path, path_enum_proc callback, void *arg)

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

1954 return -1;
1955 }
1956 LD_UTRACE(UTRACE_DLCLOSE_START, handle, NULL, 0, root->dl_refcount,
1957 root->path);
1958
1959 /* Unreference the object and its dependencies. */
1960 root->dl_refcount--;
1961
1942 unref_dag(root);
1943
1944 if (root->refcount == 0) {
1962 if (root->refcount == 1) {
1945 /*
1963 /*
1946 * The object is no longer referenced, so we must unload it.
1964 * The object will be no longer referenced, so we must unload it.
1947 * First, call the fini functions.
1948 */
1965 * First, call the fini functions.
1966 */
1949 objlist_call_fini(&list_fini, false, &lockstate);
1967 objlist_call_fini(&list_fini, root, &lockstate);
1950
1968
1969 unref_dag(root);
1970
1951 /* Finish cleaning up the newly-unreferenced objects. */
1952 GDB_STATE(RT_DELETE,&root->linkmap);
1953 unload_object(root);
1954 GDB_STATE(RT_CONSISTENT,NULL);
1971 /* Finish cleaning up the newly-unreferenced objects. */
1972 GDB_STATE(RT_DELETE,&root->linkmap);
1973 unload_object(root);
1974 GDB_STATE(RT_CONSISTENT,NULL);
1955 }
1975 } else
1976 unref_dag(root);
1977
1956 LD_UTRACE(UTRACE_DLCLOSE_STOP, handle, NULL, 0, 0, NULL);
1957 wlock_release(rtld_bind_lock, lockstate);
1958 return 0;
1959}
1960
1961char *
1962dlerror(void)
1963{

--- 1727 unchanged lines hidden ---
1978 LD_UTRACE(UTRACE_DLCLOSE_STOP, handle, NULL, 0, 0, NULL);
1979 wlock_release(rtld_bind_lock, lockstate);
1980 return 0;
1981}
1982
1983char *
1984dlerror(void)
1985{

--- 1727 unchanged lines hidden ---