Fwd: dlopen uclibc patch

Bernd Schmidt bernds at codesourcery.com
Thu Mar 21 20:02:03 UTC 2013


Another patch from Nathan.  Ok to commit?

Bernd
==

This patch fixes some fragileness in dlopen/do_dlopen wrapper & worker
pair.
do_dlopen contains __builtin_return_address to determine from whence it was
called, and uses that to determine which dynamic object's data it should
use to
start the search.  (In the bug I was tracking, this related to whether the
application's RPATH was used or not.)  For that to work, it has to have
been
inlined into the wrapper function.

As it happens, it wasn't being inlined.  That's an unfortunate compiler
behaviour, but it isn't wrong and shouldn't have caused dlopen to fail.

This patch changes things so the wrapper function determines the return
address,
and passes it to the worker.  If the worker's inlined, the generated
code should
be exactly the same as before.

nathan
-- 
Nathan Sidwell



-------------- next part --------------
2013-03-21  Nathan Sidwell  <nathan at codesourcery.com>

	* ldso/libdl/libdl.c (do_dlopen): Add FROM parameter.
	(dlopen): Determine return address here.

Index: ldso/libdl/libdl.c
===================================================================
--- ldso/libdl/libdl.c	(revision 405512)
+++ ldso/libdl/libdl.c	(working copy)
@@ -296,11 +296,10 @@ static ptrdiff_t _dl_build_local_scope (
 	return p - list;
 }
 
-static void *do_dlopen(const char *libname, int flag)
+static void *do_dlopen(const char *libname, int flag, ElfW(Addr) from)
 {
 	struct elf_resolve *tpnt, *tfrom;
 	struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr, *relro_ptr, *handle;
-	ElfW(Addr) from;
 	struct elf_resolve *tpnt1;
 	void (*dl_brk) (void);
 	int now_flag;
@@ -320,8 +319,6 @@ static void *do_dlopen(const char *libna
 		return NULL;
 	}
 
-	from = (ElfW(Addr)) __builtin_return_address(0);
-
 	if (!_dl_init) {
 		_dl_init = true;
 		_dl_malloc_function = malloc;
@@ -676,7 +673,8 @@ void *dlopen(const char *libname, int fl
 	void *ret;
 
 	__UCLIBC_MUTEX_CONDITIONAL_LOCK(_dl_mutex, 1);
-	ret = do_dlopen(libname, flag);
+	ret = do_dlopen(libname, flag,
+			(ElfW(Addr)) __builtin_return_address(0));
 	__UCLIBC_MUTEX_CONDITIONAL_UNLOCK(_dl_mutex, 1);
 
 	return ret;



More information about the uClibc mailing list