From d8ec745969b48a75412b6260f42f0cc294b42094 Mon Sep 17 00:00:00 2001
From: Filippo Arcidiacono filippo.arcidiac...@st.com
Date: Wed, 30 Nov 2011 14:13:02 +0100
Subject: [PATCH V3] ldso: fix fdpic support broken from prelink patch
The fdpic support has been broken since the prelink support was added,
because it didn't take into account DL_LOADADDR_TYPE could be a different
type of ElfW(Addr).
Signed-off-by: Filippo Arcidiacono filippo.arcidiac...@st.com
Signed-off-by: Mike Frysinger vap...@gentoo.org
---
ldso/include/dl-defs.h | 21 +
ldso/ldso/c6x/dl-sysdep.h | 11 +++
ldso/ldso/dl-elf.c | 27 ++-
ldso/ldso/dl-startup.c |8 +++-
ldso/ldso/fdpic/dl-sysdep.h | 12
ldso/ldso/ldso.c| 17 +++--
6 files changed, 76 insertions(+), 20 deletions(-)
diff --git a/ldso/include/dl-defs.h b/ldso/include/dl-defs.h
index 11edc4d..7b4e3ac 100644
--- a/ldso/include/dl-defs.h
+++ b/ldso/include/dl-defs.h
@@ -259,4 +259,25 @@ typedef struct {
# define DL_MAP_SEGMENT(EPNT, PPNT, INFILE, FLAGS) 0
#endif
+/* Define this to declare the library offset. */
+#ifndef DL_DEF_LIB_OFFSET
+#define DL_DEF_LIB_OFFSET static unsigned long _dl_library_offset;
+#endif
+
+/* Define this to get the library offset. */
+#ifndef DL_GET_LIB_OFFSET
+#define DL_GET_LIB_OFFSET _dl_library_offset
+#endif
+
+/* Define this to set the library offset as difference beetwen the mapped
+ library address and the smallest virtual address of the first PT_LOAD
+ segment. */
+#ifndef DL_SET_LIB_OFFSET
+# define DL_SET_LIB_OFFSET(offset) (_dl_library_offset = (offset))
+#endif
+
+/* Define this to get the real object's map address. */
+#ifndef DL_GET_LOADADDR_MAPADDR
+# define DL_GET_LOADADDR_MAPADDR(loadaddr, mapaddr) (mapaddr)
+#endif
#endif /* _LD_DEFS_H */
diff --git a/ldso/ldso/c6x/dl-sysdep.h b/ldso/ldso/c6x/dl-sysdep.h
index ff7accd..9cb158c 100644
--- a/ldso/ldso/c6x/dl-sysdep.h
+++ b/ldso/ldso/c6x/dl-sysdep.h
@@ -166,6 +166,17 @@ while (0)
#define DL_BOOT_COMPUTE_DYN(dpnt, got, load_addr) \
((dpnt) = dl_boot_ldso_dyn_pointer)
+/* Define this to declare the library offset. */
+#define DL_DEF_LIB_OFFSET
+
+/* Define this to get the library offset. */
+#define DL_GET_LIB_OFFSET 0
+
+/* Define this to set the library offset. */
+#define DL_SET_LIB_OFFSET(offset)
+
+/* Define this to get the real object's load address. */
+#define DL_GET_LOADADDR_MAPADDR(loadaddr, mapaddr) (loadaddr)
#ifdef __USE_GNU
# include link.h
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index b9de199..c43e2a4 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -315,6 +315,9 @@ goof:
return NULL;
}
+/* Define the _dl_library_offset for the architectures that need it */
+DL_DEF_LIB_OFFSET
+
/*
* Make a writeable mapping of a segment, regardless of whether PF_W is
* set or not.
@@ -357,7 +360,7 @@ map_writeable (int infile, ElfW(Phdr) *ppnt, int piclib,
int flags,
}
tryaddr = piclib == 2 ? piclib2map
- : ((char*) (piclib ? libaddr : 0) +
+ : ((char *) (piclib ? libaddr : DL_GET_LIB_OFFSET) +
(ppnt-p_vaddr PAGE_ALIGN));
size = (ppnt-p_vaddr ADDR_ALIGN) + ppnt-p_filesz;
@@ -459,7 +462,7 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned
rflags,
size_t relro_size = 0;
struct stat st;
uint32_t *p32;
- DL_LOADADDR_TYPE lib_loadaddr = 0;
+ DL_LOADADDR_TYPE lib_loadaddr;
DL_INIT_LOADADDR_EXTRA_DECLS
libaddr = 0;
@@ -617,6 +620,8 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned
rflags,
ppnt = (ElfW(Phdr) *)(intptr_t) header[epnt-e_phoff];
DL_INIT_LOADADDR(lib_loadaddr, libaddr - minvma, ppnt,
epnt-e_phnum);
+ /* Set _dl_library_offset to lib_loadaddr or 0. */
+ DL_SET_LIB_OFFSET(lib_loadaddr);
for (i = 0; i epnt-e_phnum; i++) {
if (DL_IS_SPECIAL_SEGMENT (epnt, ppnt)) {
@@ -648,7 +653,7 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned
rflags,
} else {
tryaddr = (piclib == 2 ? 0
: (char *) (ppnt-p_vaddr
PAGE_ALIGN)
- + (piclib ? libaddr :
lib_loadaddr));
+ + (piclib ? libaddr :
DL_GET_LIB_OFFSET));
size = (ppnt-p_vaddr ADDR_ALIGN) +
ppnt-p_filesz;
status = (char *) _dl_mmap
(tryaddr, size,
LXFLAGS(ppnt-p_flags),
@@ -675,7 +680,11 @@ struct elf_resolve
*_dl_load_elf_shared_library(unsigned rflags,
* The dynamic_addr must be take into acount lib_loadaddr value, to
note
* it is zero when the SO has been mapped to the elf's physical addr
*/
- if (lib_loadaddr) {
+#ifdef