9e30c5c2b1
Signed-off-by: Vicente Olivert Riera <Vincent.Riera@imgtec.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
67 lines
2.3 KiB
Diff
67 lines
2.3 KiB
Diff
From 2f0580cece3ab2baaf9214f434c7146e389566a4 Mon Sep 17 00:00:00 2001
|
|
From: Nathan Sidwell <nathan@codesourcery.com>
|
|
Date: Fri, 22 Mar 2013 17:48:51 +0100
|
|
Subject: [PATCH] Fix 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.
|
|
|
|
Signed-off-by: Nathan Sidwell <nathan@codesourcery.com>
|
|
Signed-off-by: Bernd Schmidt <bernds@codesourcery.com>
|
|
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
|
|
---
|
|
ldso/libdl/libdl.c | 8 +++-----
|
|
1 file changed, 3 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
|
|
index 71ade1f..018c720 100644
|
|
--- a/ldso/libdl/libdl.c
|
|
+++ b/ldso/libdl/libdl.c
|
|
@@ -296,11 +296,10 @@ static ptrdiff_t _dl_build_local_scope (struct elf_resolve **list,
|
|
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 *libname, int flag)
|
|
return NULL;
|
|
}
|
|
|
|
- from = (ElfW(Addr)) __builtin_return_address(0);
|
|
-
|
|
if (!_dl_init) {
|
|
_dl_init = true;
|
|
_dl_malloc_function = malloc;
|
|
@@ -661,7 +658,8 @@ void *dlopen(const char *libname, int flag)
|
|
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;
|
|
--
|
|
1.7.10.4
|
|
|