summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Davis <adavis@ti.com>2011-05-26 18:15:06 +0200
committerBernd Schmidt <bernds@codesourcery.com>2011-05-27 12:46:03 +0200
commit8514218c136c9a21a5ed4f123d2c49f21ef86947 (patch)
tree63f7c5443dc40be862a7c3d4592a143169203b0e
parent71d63ed75648da9b0b71afabb9c60aaad792c55c (diff)
Correct a bug when remapping textrel segments on nommu
From: Alan Davis <adavis@ti.com> On C6X, when trying to execute a program that has a textrel DSO, it fails to load. The telltale line in the LD_DEBUG output is: _dl_get_ready_to_run:779: file=''; needed by './a.out' The corresponding DT_NEEDED entry has 'libc.so.0', but here the filename is empty. This is what is happening in _dl_elf_shared_library(): First, map all segments according to their permissions. Text gets initially mapped read-only. Then, parse the dynamic information. The dynamic table is in RW but some of the tags may point to RO. For example, DT_NEEDED points to a string in .dynstr which is in RO. These pointers get computed according to the loadmap from the original mapping. Then, in response to a DT_TEXTREL tag, the RO segment gets remapped, thereby invaliding anything that points to it, in particular certain dynamic tags such as DT_NEEDED. The following patch re-parses the dynamic info after the remapping so as to re-compute any invalid pointers. Signed-off-by: Alan Davis <adavis@ti.com> Signed-off-by: Bernd Schmidt <bernds@codesourcery.com>
-rw-r--r--ldso/ldso/dl-elf.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 7b5d75146..09b3aaf01 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -714,6 +714,9 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
DL_UPDATE_LOADADDR_HDR(lib_loadaddr,
new_addr + (ppnt->p_vaddr & ADDR_ALIGN),
ppnt);
+ /* This has invalidated all pointers into the previously readonly segment.
+ Update any them to point into the remapped segment. */
+ _dl_parse_dynamic_info(dpnt, dynamic_info, NULL, lib_loadaddr);
#endif
}
}