svn commit: branches/uClibc_0_9_29/ldso: include ldso libdl

carmelo at uclibc.org carmelo at uclibc.org
Mon Jan 21 09:42:30 UTC 2008


Author: carmelo
Date: 2008-01-21 01:42:25 -0800 (Mon, 21 Jan 2008)
New Revision: 20881

Log:
This patch solves a problem in dladdr caused by the wrong value
of elf_resolve's loadaddr field for the main application.
Backported to 0.9.29 stable release from trunk, with some spaces
and tabs tidy-up.

Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono at st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso at st.com>


Modified:
   branches/uClibc_0_9_29/ldso/include/dl-defs.h
   branches/uClibc_0_9_29/ldso/include/dl-hash.h
   branches/uClibc_0_9_29/ldso/ldso/dl-hash.c
   branches/uClibc_0_9_29/ldso/ldso/ldso.c
   branches/uClibc_0_9_29/ldso/libdl/libdl.c


Changeset:
Modified: branches/uClibc_0_9_29/ldso/include/dl-defs.h
===================================================================
--- branches/uClibc_0_9_29/ldso/include/dl-defs.h	2008-01-19 19:30:04 UTC (rev 20880)
+++ branches/uClibc_0_9_29/ldso/include/dl-defs.h	2008-01-21 09:42:25 UTC (rev 20881)
@@ -148,8 +148,8 @@
  */
 #ifndef DL_ADDR_IN_LOADADDR
 # define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
-	((void*)(TPNT)->loadaddr < (void*)(ADDR) \
-	 && (!(TFROM) || (TFROM)->loadaddr < (TPNT)->loadaddr))
+	((void*)(TPNT)->mapaddr < (void*)(ADDR) \
+	 && (!(TFROM) || (TFROM)->mapaddr < (TPNT)->mapaddr))
 #endif
 
 /* Use this macro to convert a pointer to a function's entry point to

Modified: branches/uClibc_0_9_29/ldso/include/dl-hash.h
===================================================================
--- branches/uClibc_0_9_29/ldso/include/dl-hash.h	2008-01-19 19:30:04 UTC (rev 20880)
+++ branches/uClibc_0_9_29/ldso/include/dl-hash.h	2008-01-21 09:42:25 UTC (rev 20881)
@@ -34,6 +34,7 @@
   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 */
   enum {elf_lib, elf_executable,program_interpreter, loaded_file} libtype;
   struct dyn_elf * symbol_scope;
   unsigned short usage_count;
@@ -90,7 +91,7 @@
 
 static inline int _dl_symbol(char * name)
 {
-  if(name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_')
+  if (name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_')
     return 0;
   return 1;
 }

Modified: branches/uClibc_0_9_29/ldso/ldso/dl-hash.c
===================================================================
--- branches/uClibc_0_9_29/ldso/ldso/dl-hash.c	2008-01-19 19:30:04 UTC (rev 20880)
+++ branches/uClibc_0_9_29/ldso/ldso/dl-hash.c	2008-01-21 09:42:25 UTC (rev 20881)
@@ -101,7 +101,7 @@
 		_dl_memset(tpnt->next, 0, sizeof(struct elf_resolve));
 		tpnt->next->prev = tpnt;
 		tpnt = tpnt->next;
-	};
+	}
 
 	tpnt->next = NULL;
 	tpnt->init_flag = 0;
@@ -117,7 +117,7 @@
 		hash_addr += tpnt->nbucket;
 		tpnt->chains = hash_addr;
 	}
-	tpnt->loadaddr = loadaddr;
+	tpnt->loadaddr = tpnt->mapaddr = loadaddr;
 	for (i = 0; i < DYNAMIC_SIZE; i++)
 		tpnt->dynamic_info[i] = dynamic_info[i];
 	return tpnt;

Modified: branches/uClibc_0_9_29/ldso/ldso/ldso.c
===================================================================
--- branches/uClibc_0_9_29/ldso/ldso/ldso.c	2008-01-19 19:30:04 UTC (rev 20880)
+++ branches/uClibc_0_9_29/ldso/ldso/ldso.c	2008-01-21 09:42:25 UTC (rev 20881)
@@ -133,6 +133,7 @@
                           ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp,
                           char **argv)
 {
+	DL_LOADADDR_TYPE app_loadaddr = NULL;
 	ElfW(Phdr) *ppnt;
 	ElfW(Dyn) *dpnt;
 	char *lpntstr;
@@ -274,6 +275,9 @@
 			relro_addr = ppnt->p_vaddr;
 			relro_size = ppnt->p_memsz;
 		}
+		if (!app_loadaddr && (ppnt->p_type == PT_LOAD)) {
+			app_loadaddr = ppnt->p_vaddr;
+		}
 		if (ppnt->p_type == PT_DYNAMIC) {
 			dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
 			_dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
@@ -312,7 +316,7 @@
 			/* OK, we have what we need - slip this one into the list. */
 			app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
 					app_tpnt->dynamic_info,
-					DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
+					(unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
 					ppnt->p_filesz);
 			_dl_loaded_modules->libtype = elf_executable;
 			_dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
@@ -320,6 +324,7 @@
 			_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->rtld_flags = unlazy | RTLD_GLOBAL;
 			app_tpnt->usage_count++;
 			app_tpnt->symbol_scope = _dl_symbol_tables;
@@ -344,7 +349,7 @@
 			if (ptmp != _dl_ldsopath)
 				*ptmp = '\0';
 
-			_dl_debug_early("Lib Loader: (%x) %s\n", DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
+			_dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
 		}
 	}
 	app_tpnt->relro_addr = relro_addr;
@@ -692,7 +697,7 @@
 		if (_dl_stat(tpnt->libname, &st) >= 0) {
 			tpnt->st_dev = st.st_dev;
 			tpnt->st_ino = st.st_ino;
-		} 
+		}
 		tpnt->n_phent = epnt->e_phnum;
 		tpnt->ppnt = myppnt;
 		for (j = 0; j < epnt->e_phnum; j++, myppnt++) {

Modified: branches/uClibc_0_9_29/ldso/libdl/libdl.c
===================================================================
--- branches/uClibc_0_9_29/ldso/libdl/libdl.c	2008-01-19 19:30:04 UTC (rev 20880)
+++ branches/uClibc_0_9_29/ldso/libdl/libdl.c	2008-01-21 09:42:25 UTC (rev 20881)
@@ -186,7 +186,7 @@
 			_dl_debug_bindings = strstr(_dl_debug, "bind");
 		}
 	}
-# endif	
+# endif
 #endif
 
 	_dl_map_cache();
@@ -208,7 +208,7 @@
 				tfrom = tpnt;
 		}
 	}
-	for(rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next);
+	for (rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next);
 
 	relro_ptr = rpnt;
 	now_flag = (flag & RTLD_NOW) ? RTLD_NOW : 0;
@@ -218,8 +218,8 @@
 #ifndef SHARED
 	/* When statically linked, the _dl_library_path is not yet initialized */
 	_dl_library_path = getenv("LD_LIBRARY_PATH");
-#endif	
-	
+#endif
+
 	/* Try to load the specified library */
 	_dl_if_debug_print("Trying to dlopen '%s', RTLD_GLOBAL:%d RTLD_NOW:%d\n",
 			(char*)libname, (flag & RTLD_GLOBAL ? 1:0), (now_flag & RTLD_NOW ? 1:0));
@@ -244,7 +244,7 @@
 			if (handle->dyn == tpnt) {
 				dyn_chain->init_fini.init_fini = handle->init_fini.init_fini;
 				dyn_chain->init_fini.nlist = handle->init_fini.nlist;
-				for(i=0; i < dyn_chain->init_fini.nlist; i++)
+				for (i = 0; i < dyn_chain->init_fini.nlist; i++)
 					dyn_chain->init_fini.init_fini[i]->rtld_flags |= (flag & RTLD_GLOBAL);
 				dyn_chain->next = handle->next;
 				break;
@@ -314,7 +314,7 @@
 	i = 0;
 	for (runp2 = dep_list; runp2; runp2 = runp2->next) {
 		init_fini_list[i++] = runp2->tpnt;
-		for(runp = runp2->tpnt->init_fini; runp; runp = runp->next){
+		for (runp = runp2->tpnt->init_fini; runp; runp = runp->next) {
 			if (!(runp->tpnt->rtld_flags & RTLD_GLOBAL)) {
 				tmp = malloc(sizeof(struct init_fini_list));
 				tmp->tpnt = runp->tpnt;
@@ -346,9 +346,9 @@
 		}
 	}
 #ifdef __SUPPORT_LD_DEBUG__
-	if(_dl_debug) {
+	if (_dl_debug) {
 		fprintf(stderr, "\nINIT/FINI order and dependencies:\n");
-		for (i=0;i < nlist;i++) {
+		for (i = 0; i < nlist; i++) {
 			fprintf(stderr, "lib: %s has deps:\n", init_fini_list[i]->libname);
 			runp = init_fini_list[i]->init_fini;
 			for (; runp; runp = runp->next)
@@ -703,9 +703,12 @@
 		char *strtab;
 		ElfW(Sym) *symtab;
 		unsigned int hn, si, sn, sf;
-		ElfW(Addr) sa;
+		ElfW(Addr) sa = 0;
 
-		sa = 0;
+		/* Set the info for the object the address lies in */
+		__info->dli_fname = pelf->libname;
+		__info->dli_fbase = (void *) DL_LOADADDR_BASE(pelf->mapaddr);
+
 		symtab = (ElfW(Sym) *) (pelf->dynamic_info[DT_SYMTAB]);
 		strtab = (char *) (pelf->dynamic_info[DT_STRTAB]);
 
@@ -727,10 +730,14 @@
 		}
 
 		if (sf) {
-			__info->dli_fname = pelf->libname;
-			__info->dli_fbase = (void *) DL_LOADADDR_BASE(pelf->loadaddr);
+			/* A nearest symbol has been found; fill the entries */
 			__info->dli_sname = strtab + symtab[sn].st_name;
 			__info->dli_saddr = (void *)sa;
+		} else {
+			/* No symbol found, fill entries with NULL value,
+			only the containing object will be returned. */
+			__info->dli_sname = NULL;
+			__info->dli_saddr = NULL;
 		}
 		return 1;
 	}




More information about the uClibc-cvs mailing list