summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTsugutomo Enami <tsugutomo.enami@jp.sony.com>2014-11-02 10:46:17 +0300
committerIvan Maidanski <ivmai@mail.ru>2014-11-02 10:46:17 +0300
commit8f6f15858cd5ae6c4f7fb6da935f8276632413cc (patch)
treed03c62b3ac40c52f93d20c52dc79da2be57d732e
parentb519011261256f8b5b0f3d9868536271c78b53f5 (diff)
downloadbdwgc-8f6f15858cd5ae6c4f7fb6da935f8276632413cc.tar.gz
Fix FirstDLOpenedLinkMap for case libgc not 1st dynamically linked (NetBSD)
Current GC_FirstDLOpenedLinkMap() for NetBSD calls dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &lm) to find link_map. So it will find link_map of libgc. With guile's case, libgc is link to libguile and libguile is linked to the guile command, so libgc is not the first one in the link_map chain. That is why, data section of libguile, where scm_protects exists, is not added to GC root and GC_is_visible fails. * dyn_load.c (GC_FirstDLOpenedLinkMap): Iterate over link_map (provided by dlinfo(RTLD_SELF)) to return 2nd element instead of the provided one which might not always belong to libgc (only for NETBSD and defined RTLD_DI_LINKMAP).
-rw-r--r--dyn_load.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/dyn_load.c b/dyn_load.c
index 2c866cd2..3b907185 100644
--- a/dyn_load.c
+++ b/dyn_load.c
@@ -687,8 +687,15 @@ GC_FirstDLOpenedLinkMap(void)
if( cachedResult == 0 ) {
# if defined(NETBSD) && defined(RTLD_DI_LINKMAP)
struct link_map *lm = NULL;
- if (!dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &lm))
- cachedResult = lm;
+ if (!dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &lm) && lm != NULL) {
+ /* Now lm points link_map object of libgc. Since it */
+ /* might not be the first dynamically linked object, */
+ /* try to find it (object next to the main object). */
+ while (lm->l_prev != NULL) {
+ lm = lm->l_prev;
+ }
+ cachedResult = lm->l_next;
+ }
# else
int tag;
for( dp = _DYNAMIC; (tag = dp->d_tag) != 0; dp++ ) {