diff options
author | Filippo Arcidiacono <filippo.arcidiacono@st.com> | 2011-11-23 11:50:55 +0100 |
---|---|---|
committer | Carmelo Amoroso <carmelo.amoroso@st.com> | 2011-11-23 16:12:09 +0100 |
commit | 9b42da7d0558884e2a3cc9a8674ccfc752369610 (patch) | |
tree | ce1e1dd236af048d5283c73e415b93cd4009eb8e | |
parent | 117a32a63b837730cc97b0a233ab46e9abc6c7a7 (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>
-rw-r--r-- | ldso/libdl/libdl.c | 8 |
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; |