Carmelo AMOROSO wrote:
> based on  the patch from Nickolai, here you can find a comprehensive
> patch to fix
> dladdr function.
> 
> With the current implementation, the invocation of dladdr((void *) 1,
> &dlinfo)
> will fill dlinfo.dli_fname with the name of the application itself and
> dlinfo.dli_fbase with 0 (the current value of tpnt->loadaddr for the
> main app).
> 
> The patch solves this adding a new field into the struct elf_resolve
> named  DL_LOADADDR_TYPE mapaddr.
> For shared objects, mapaddr has exactly the same value as loadaddr,
> while for the
> main app it contains the address of the first PT_LOAD segmented loaded.
> 
> loadaddr will keep it's value and will used exactly as is (as a in
> memory offset
> with respect to relative addresses from ELF sections).
> While in the DL_ADDR_IN_LOADADDR macro, the new field mapaddr needs to
> be used.

This is broken on FD-PIC, since you treat DL_LOADADDR_TYPE variables as
pointers, defeating the point of abstracting away the type.

The following patch makes it compile on Blackfin, but I'm unable to test
this on a non-FDPIC system.  Does it still work for you?


Bernd
-- 
This footer brought to you by insane German lawmakers.
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
Index: ldso/ldso/ldso.c
===================================================================
--- ldso/ldso/ldso.c	(revision 20945)
+++ ldso/ldso/ldso.c	(working copy)
@@ -135,7 +135,7 @@ void _dl_get_ready_to_run(struct elf_res
 			  char **argv
 			  DL_GET_READY_TO_RUN_EXTRA_PARMS)
 {
-	DL_LOADADDR_TYPE app_loadaddr = NULL;
+	ElfW(Addr) app_mapaddr = NULL;
 	ElfW(Phdr) *ppnt;
 	ElfW(Dyn) *dpnt;
 	char *lpntstr;
@@ -277,8 +278,8 @@ void _dl_get_ready_to_run(struct elf_res
 			relro_addr = ppnt->p_vaddr;
 			relro_size = ppnt->p_memsz;
 		}
-		if (!app_loadaddr && (ppnt->p_type == PT_LOAD)) {
-			app_loadaddr = ppnt->p_vaddr;
+		if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
+			app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
 		}
 		if (ppnt->p_type == PT_DYNAMIC) {
 			dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
@@ -326,7 +327,7 @@ void _dl_get_ready_to_run(struct elf_res
 			_dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
 			_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
 			rpnt->dyn = _dl_loaded_modules;
-			app_tpnt->mapaddr = app_loadaddr;
+			app_tpnt->mapaddr = app_mapaddr;
 			app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
 			app_tpnt->usage_count++;
 			app_tpnt->symbol_scope = _dl_symbol_tables;
Index: ldso/ldso/dl-hash.c
===================================================================
--- ldso/ldso/dl-hash.c	(revision 20945)
+++ ldso/ldso/dl-hash.c	(working copy)
@@ -152,7 +152,8 @@ struct elf_resolve *_dl_add_elf_hash_tab
 		hash_addr += tpnt->nbucket;
 		tpnt->chains = hash_addr;
 	}
-	tpnt->loadaddr = tpnt->mapaddr = loadaddr;
+	tpnt->loadaddr = loadaddr;
+	tpnt->mapaddr = DL_RELOC_ADDR(loadaddr, 0);
 	for (i = 0; i < DYNAMIC_SIZE; i++)
 		tpnt->dynamic_info[i] = dynamic_info[i];
 	return tpnt;
Index: ldso/ldso/bfin/dl-sysdep.h
===================================================================
--- ldso/ldso/bfin/dl-sysdep.h	(revision 20945)
+++ ldso/ldso/bfin/dl-sysdep.h	(working copy)
@@ -95,7 +95,7 @@ struct funcdesc_ht;
 #define DL_LOADADDR_TYPE struct elf32_fdpic_loadaddr
 
 #define DL_RELOC_ADDR(LOADADDR, ADDR) \
-  (__reloc_pointer ((void*)(ADDR), (LOADADDR).map))
+    ((ElfW(Addr))__reloc_pointer ((void*)(ADDR), (LOADADDR).map))
 
 #define DL_ADDR_TO_FUNC_PTR(ADDR, LOADADDR) \
   ((void(*)(void)) _dl_funcdesc_for ((void*)(ADDR), (LOADADDR).got_value))
@@ -189,7 +189,7 @@ while (0)  
 #define DL_FIND_HASH_VALUE(TPNT, TYPE_CLASS, SYM) \
   (((TYPE_CLASS) & ELF_RTYPE_CLASS_DLSYM) \
    && ELF32_ST_TYPE((SYM)->st_info) == STT_FUNC \
-   ? _dl_funcdesc_for (DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value),    \
+   ? _dl_funcdesc_for ((void *)DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value), \
  		       (TPNT)->loadaddr.got_value)			     \
    : DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value))
 
Index: ldso/include/dl-hash.h
===================================================================
--- ldso/include/dl-hash.h	(revision 20945)
+++ ldso/include/dl-hash.h	(working copy)
@@ -34,7 +34,7 @@ struct elf_resolve {
   struct elf_resolve * next;
   struct elf_resolve * prev;
   /* Nothing after this address is used by gdb. */
-  DL_LOADADDR_TYPE mapaddr;    /* Address at which ELF segments (either main app and DSO) are mapped into */
+  ElfW(Addr) mapaddr;    /* Address at which ELF segments (either main app and DSO) are mapped into */
   enum {elf_lib, elf_executable,program_interpreter, loaded_file} libtype;
   struct dyn_elf * symbol_scope;
   unsigned short usage_count;
Index: ldso/libdl/libdl.c
===================================================================
--- ldso/libdl/libdl.c	(revision 20945)
+++ ldso/libdl/libdl.c	(working copy)
@@ -743,7 +743,7 @@ int dladdr(const void *__address, Dl_inf
 
 		/* Set the info for the object the address lies in */
 		__info->dli_fname = pelf->libname;
-		__info->dli_fbase = (void *) DL_LOADADDR_BASE(pelf->mapaddr);
+		__info->dli_fbase = pelf->mapaddr;
 
 		symtab = (ElfW(Sym) *) (pelf->dynamic_info[DT_SYMTAB]);
 		strtab = (char *) (pelf->dynamic_info[DT_STRTAB]);
_______________________________________________
uClibc mailing list
uClibc@uclibc.org
http://busybox.net/cgi-bin/mailman/listinfo/uclibc

Reply via email to