From: Tsugutomo Enami Date: Sun, 2 Nov 2014 07:46:17 +0000 (+0300) Subject: Fix FirstDLOpenedLinkMap for case libgc not 1st dynamically linked (NetBSD) X-Git-Tag: gc7_6_0~205^2~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8f6f15858cd5ae6c4f7fb6da935f8276632413cc;p=gc 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). --- 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++ ) {