[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Ian's solution [was: What hack in ld.so?]



Hi, all!

There's been so much traffic on this thread, that I suspect most
people have missed the fact that Ian Lance Taylor has analyzed and
*solved* the problems with interaction between libtool and
libc5-compat shared libraries.

I'm quoting and reposting his message so that it doesn't get lost in
the shuffle.  Please read and understand this message before posting
more flameage.

>>>>> Ian Lance Taylor writes:

 ILT> I just spent some time looking at the ld.so sources.
 ILT> Interestingly, it seems to me that everything will work
 ILT> correctly in the sources I was looking at.  That is because the
 ILT> libc5 dynamic linker on my system (RedHat 5.2) was modified to
 ILT> search the library cache before using the application's
 ILT> DT_RPATH.

 ILT> I think that is a hack that Debian is missing: it is the final
 ILT> hack to the libc5 dynamic linker to change the search path to
 ILT> account for the moved shared libraries even when rpath is used.
 ILT> I have appended the RedHat patch below.  This is to ld.so-1.9.5.
 ILT> Of course, this will technically break the handling of DT_RPATH.
 ILT> However, we've already determined that DT_RPATH binaries will
 ILT> not work correctly anyhow, because the shared libraries were
 ILT> moved.  So using this patch should not make us any worse off.

[...]

 ILT> Although I can not test this, I now believe that if you take a
 ILT> libtool program, compile it on a libc5 Slackware and try to run
 ILT> it on a RedHat 5.2 system, it will work.

His patch follows...

-- 
 Gordon Matzigkeit <gord@fig.org> //\ I'm a FIG (http://www.fig.org/)
    Lovers of freedom, unite!     \// I use GNU (http://www.gnu.org/)
[Unfortunately, www.fig.org is broken.  Please stay tuned for details.]

--- ld.so-1.9.5/d-link/readelflib1.c.ewt	Mon Nov 17 10:04:15 1997
+++ ld.so-1.9.5/d-link/readelflib1.c	Mon Nov 17 10:23:15 1997
@@ -179,38 +179,10 @@
     goto goof;
   }
 
-  /*
-   * The ABI specifies that RPATH is searched before LD_*_PATH or
-   * the default path of /usr/lib.
-   * Check in rpath directories 
-   */
-  for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
-    if (tpnt->libtype == elf_executable) {
-      pnt1 = (char *)tpnt->dynamic_info[DT_RPATH];
-      if(pnt1) {
-	pnt1 += (unsigned int) tpnt->loadaddr + tpnt->dynamic_info[DT_STRTAB];
-	while(*pnt1){
-	  pnt2 = mylibname;
-	  while(*pnt1 && *pnt1 != ':') {
-	    if (pnt2 - mylibname < 1024)
-	      *pnt2++ = *pnt1++;
-	    else
-	      pnt1++;
-	  }
-	  if (pnt2 - mylibname >= 1024)
-	    break;
-	  if(pnt2[-1] != '/') *pnt2++ = '/';
-	  pnt = libname;
-	  while(*pnt) *pnt2++  = *pnt++;
-	  *pnt2++ = 0;
-	  tpnt1 = _dl_load_elf_shared_library(mylibname, 0);
-	  if(tpnt1) return tpnt1;
-	  if(*pnt1 == ':') pnt1++;
-	}
-      }
-    }
-  }
-  
+  /* EWT - change things around a bit... The RPATH is almost definitely
+     wrong for libc 5 apps as things got moved around so much. Rather
+     then checking it first, we'll check it last. While this could
+     cause major breakages, it probably won't. */
 
   /* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
   pnt1 = _dl_library_path;
@@ -259,6 +231,38 @@
     }
   }
 #endif
+
+  /*
+   * The ABI specifies that RPATH is searched before LD_*_PATH or
+   * the default path of /usr/lib.
+   * Check in rpath directories 
+   */
+  for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+    if (tpnt->libtype == elf_executable) {
+      pnt1 = (char *)tpnt->dynamic_info[DT_RPATH];
+      if(pnt1) {
+	pnt1 += (unsigned int) tpnt->loadaddr + tpnt->dynamic_info[DT_STRTAB];
+	while(*pnt1){
+	  pnt2 = mylibname;
+	  while(*pnt1 && *pnt1 != ':') {
+	    if (pnt2 - mylibname < 1024)
+	      *pnt2++ = *pnt1++;
+	    else
+	      pnt1++;
+	  }
+	  if (pnt2 - mylibname >= 1024)
+	    break;
+	  if(pnt2[-1] != '/') *pnt2++ = '/';
+	  pnt = libname;
+	  while(*pnt) *pnt2++  = *pnt++;
+	  *pnt2++ = 0;
+	  tpnt1 = _dl_load_elf_shared_library(mylibname, 0);
+	  if(tpnt1) return tpnt1;
+	  if(*pnt1 == ':') pnt1++;
+	}
+      }
+    }
+  }
 
   /* Check in /usr/lib */
 #ifdef IBCS_COMPATIBLE


Reply to: