[git commit] ldso: Do not add the ld.so at the end of the loaded modules list

Filippo Arcidiacono filippo.arcidiacono at st.com
Fri Jul 1 07:49:47 UTC 2011


commit: http://git.uclibc.org/uClibc/commit/?id=02f56b3ae9f620528c3c1bb42662b4499d19f383
branch: http://git.uclibc.org/uClibc/commit/?id=refs/heads/master

The dynamic linker was included indifferently at the end of the
loaded modules list. In order to be used with prelink, it is required
to included the ld.so in the local scope of each shared libraries that
depends directly on it.
Also it is included in the global scope at the first occurrence.

Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono at st.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso at st.com>
---
 ldso/ldso/ldso.c |  119 +++++++++++++++++++++++++++++-------------------------
 1 files changed, 64 insertions(+), 55 deletions(-)

diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 8c6e4d1..4a7b639 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -291,7 +291,6 @@ static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
 }
 
 #ifdef __LDSO_PRELINK_SUPPORT__
-
 static void trace_objects(struct elf_resolve *tpnt, char *str_name)
 {
 	if (_dl_strcmp(_dl_trace_prelink, tpnt->libname) == 0)
@@ -312,9 +311,50 @@ static void trace_objects(struct elf_resolve *tpnt, char *str_name)
 	else
 		_dl_dprintf (1, "\n");
 }
-
 #endif
 
+static struct elf_resolve * add_ldso(struct elf_resolve *tpnt,
+									 DL_LOADADDR_TYPE load_addr,
+									 ElfW(auxv_t) auxvt[AT_EGID + 1],
+									 struct dyn_elf *rpnt)
+{
+		ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
+		ElfW(Phdr) *myppnt = (ElfW(Phdr) *)
+								DL_RELOC_ADDR(load_addr, epnt->e_phoff);
+		int j;
+		struct stat st;
+
+		tpnt = _dl_add_elf_hash_table(tpnt->libname, tpnt->loadaddr,
+					      tpnt->dynamic_info, (unsigned long)tpnt->dynamic_addr,
+					      0);
+
+		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++) {
+			if (myppnt->p_type ==  PT_GNU_RELRO) {
+				tpnt->relro_addr = myppnt->p_vaddr;
+				tpnt->relro_size = myppnt->p_memsz;
+				break;
+			}
+		}
+		tpnt->libtype = program_interpreter;
+		if (rpnt) {
+			rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
+			rpnt->next->prev = rpnt;
+			rpnt = rpnt->next;
+		} else {
+			rpnt = _dl_zalloc(sizeof(struct dyn_elf));
+		}
+		rpnt->dyn = tpnt;
+		tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
+
+	return tpnt;
+}
+
 static ptrdiff_t _dl_build_local_scope (struct elf_resolve **list,
 										struct elf_resolve *map)
 {
@@ -343,6 +383,7 @@ void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 	struct dyn_elf *rpnt;
 	struct elf_resolve *tcurr;
 	struct elf_resolve *tpnt1;
+	struct elf_resolve *ldso_tpnt = NULL;
 	struct elf_resolve app_tpnt_tmp;
 	struct elf_resolve *app_tpnt = &app_tpnt_tmp;
 	struct r_debug *debug_addr;
@@ -353,7 +394,6 @@ void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 	struct r_scope_elem *global_scope;
 	struct elf_resolve **local_scope;
 
-	struct stat st;
 #if defined(USE_TLS) && USE_TLS
 	void *tcbp = NULL;
 #endif
@@ -944,12 +984,19 @@ of this helper program; chances are you did not intend to run this program.\n\
 
 				lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
 				name = _dl_get_last_path_component(lpntstr);
-				if (_dl_strcmp(name, UCLIBC_LDSO) == 0)
-					continue;
-
 				_dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", lpntstr, _dl_progname);
 
-				if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects)))	{
+				if (_dl_strcmp(name, UCLIBC_LDSO) == 0) {
+						if (!ldso_tpnt) {
+							/* Insert the ld.so only once */
+							ldso_tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
+						}
+						ldso_tpnt->usage_count++;
+						tpnt1 = ldso_tpnt;
+				} else
+					tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects);
+
+				if (!tpnt1) {
 #ifdef __LDSO_LDD_SUPPORT__
 					if (trace_loaded_objects || _dl_trace_prelink) {
 						_dl_dprintf(1, "\t%s => not found\n", lpntstr);
@@ -1041,41 +1088,12 @@ of this helper program; chances are you did not intend to run this program.\n\
 	 * functions in the dynamic linker and to relocate the interpreter
 	 * again once all libs are loaded.
 	 */
-	if (tpnt) {
-		ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
-		ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
-		int j;
-
-		tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
-					      tpnt->dynamic_info,
-					      (unsigned long)tpnt->dynamic_addr,
-					      0);
-
-		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++) {
-			if (myppnt->p_type ==  PT_GNU_RELRO) {
-				tpnt->relro_addr = myppnt->p_vaddr;
-				tpnt->relro_size = myppnt->p_memsz;
-				break;
-			}
-		}
-		tpnt->libtype = program_interpreter;
+	if (!ldso_tpnt) {
+		tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
 		tpnt->usage_count++;
 		nscope_elem++;
-		if (rpnt) {
-			rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
-			rpnt->next->prev = rpnt;
-			rpnt = rpnt->next;
-		} else {
-			rpnt = _dl_zalloc(sizeof(struct dyn_elf));
-		}
-		rpnt->dyn = tpnt;
-		tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
+	} else
+		tpnt = ldso_tpnt;
 
 #ifdef RERELOCATE_LDSO
 		/* Only rerelocate functions for now. */
@@ -1089,7 +1107,6 @@ of this helper program; chances are you did not intend to run this program.\n\
 		tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
 #endif
 		tpnt = NULL;
-	}
 
 	/*
 	 * Allocate the global scope array.
@@ -1124,13 +1141,9 @@ of this helper program; chances are you did not intend to run this program.\n\
 	_dl_free(local_scope);
 
 #ifdef __LDSO_LDD_SUPPORT__
-	/* End of the line for ldd.... */
-	if (trace_loaded_objects && !_dl_trace_prelink) {
-		_dl_dprintf(1, "\t%s => %s (%x)\n",
-			    rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,
-			    rpnt->dyn->libname, DL_LOADADDR_BASE(rpnt->dyn->loadaddr));
+	/* Exit if LD_TRACE_LOADED_OBJECTS is on. */
+	if (trace_loaded_objects && !_dl_trace_prelink)
 		_dl_exit(0);
-	}
 #endif
 
 #if defined(USE_TLS) && USE_TLS
@@ -1160,16 +1173,12 @@ of this helper program; chances are you did not intend to run this program.\n\
 # endif
 #endif
 
-
-	/* FIXME: The glibc code doesn't trace the ldso when LD_TRACE_OBJECT is set,
-	 *        here has been trace to mantain the original one.
-	 *        Another difference Vs Glibc is the check to verify if an object is
-	 *        "statically linked" (only if LD_TRACE_OBJECT is on).
-	 */
-
 #ifdef __LDSO_PRELINK_SUPPORT__
 	if (_dl_trace_prelink) {
-		for (i = 0; i < nscope_elem; i++)
+
+		unsigned int nscope_trace = ldso_tpnt ? nscope_elem : (nscope_elem - 1);
+
+		for (i = 0; i < nscope_trace; i++)
 			trace_objects(scope_elem_list[i],
 				_dl_get_last_path_component(scope_elem_list[i]->libname));
 
-- 
1.7.3.4



More information about the uClibc-cvs mailing list