summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
authorFilippo Arcidiacono <filippo.arcidiacono@st.com>2011-11-23 11:50:55 +0100
committerCarmelo Amoroso <carmelo.amoroso@st.com>2011-11-23 16:12:09 +0100
commit9b42da7d0558884e2a3cc9a8674ccfc752369610 (patch)
treece1e1dd236af048d5283c73e415b93cd4009eb8e /ldso
parent117a32a63b837730cc97b0a233ab46e9abc6c7a7 (diff)
libdl: fix size parameter when unmap library in dlclose
Fix size parameter when unmap a library by means of dlclose, by taking into account the p_vaddr of first PT_LOAD segment, so it works also for prelinked shared objects. Unmapping of dlopen shared libraries is broken since 94cc6edb78a12655c0602a246fa1cbdc8c6d0ad9 Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono@st.com> Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Diffstat (limited to 'ldso')
-rw-r--r--ldso/libdl/libdl.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index cbbbcd49e..324b76aa5 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -751,7 +751,7 @@ static int do_dlclose(void *vhandle, int need_fini)
int (*dl_elf_fini) (void);
void (*dl_brk) (void);
struct dyn_elf *handle;
- unsigned int end;
+ unsigned int end = 0, start = 0xffffffff;
unsigned int i, j;
struct r_scope_elem *ls;
#if defined(USE_TLS) && USE_TLS
@@ -813,6 +813,8 @@ static int do_dlclose(void *vhandle, int need_fini)
i < tpnt->n_phent; ppnt++, i++) {
if (ppnt->p_type != PT_LOAD)
continue;
+ if (ppnt->p_vaddr < start)
+ start = ppnt->p_vaddr;
if (end < ppnt->p_vaddr + ppnt->p_memsz)
end = ppnt->p_vaddr + ppnt->p_memsz;
}
@@ -919,7 +921,9 @@ static int do_dlclose(void *vhandle, int need_fini)
}
#endif
- DL_LIB_UNMAP (tpnt, end - tpnt->mapaddr);
+ end = (end + ADDR_ALIGN) & PAGE_ALIGN;
+ start = start & ~ADDR_ALIGN;
+ DL_LIB_UNMAP (tpnt, end - start);
/* Free elements in RTLD_LOCAL scope list */
for (runp = tpnt->rtld_local; runp; runp = tmp) {
tmp = runp->next;