[Ltrace-devel] [PATCH 05/11] Adjust in_load_libraries to have an out parameter for a discovered symbol.

Joe Damato ice799 at gmail.com
Mon Nov 8 23:47:38 UTC 2010


---
 ltrace-elf.c |   68 +++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/ltrace-elf.c b/ltrace-elf.c
index 858a313..00a7e5f 100644
--- a/ltrace-elf.c
+++ b/ltrace-elf.c
@@ -17,7 +17,7 @@ static void do_close_elf(struct ltelf *lte);
 static void add_library_symbol(GElf_Addr addr, const char *name,
 			       struct library_symbol **library_symbolspp,
 			       enum toplt type_of_plt, int is_weak);
-static int in_load_libraries(const char *name, struct ltelf *lte);
+static int in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym);
 static GElf_Addr opd2addr(struct ltelf *ltc, GElf_Addr addr);
 
 #ifdef PLT_REINITALISATION_BP
@@ -362,17 +362,17 @@ private_elf_gnu_hash(const char *name) {
 }
 
 static int
-in_load_libraries(const char *name, struct ltelf *lte) {
+in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym) {
 	size_t i;
 	unsigned long hash;
 	unsigned long gnu_hash;
 
-	if (!library_num)
+	if (!count)
 		return 1;
 
 	hash = elf_hash((const unsigned char *)name);
 	gnu_hash = private_elf_gnu_hash(name);
-	for (i = 1; i <= library_num; ++i) {
+	for (i = 0; i < count; ++i) {
 		if (lte[i].hash == NULL)
 			continue;
 
@@ -397,15 +397,20 @@ in_load_libraries(const char *name, struct ltelf *lte) {
 				do
 					if ((*hasharr & ~1u) == (gnu_hash & ~1u)) {
 						int symidx = hasharr - chain_zero;
-						GElf_Sym sym;
-
-						if (gelf_getsym(lte[i].dynsym, symidx, &sym) == NULL)
-							error(EXIT_FAILURE, 0,
-							      "Couldn't get symbol from .dynsym");
-
-						if (sym.st_value != 0
-						    && sym.st_shndx != SHN_UNDEF
-						    && strcmp(name, lte[i].dynstr + sym.st_name) == 0)
+						GElf_Sym tmp_sym;
+						GElf_Sym *tmp;
+
+						tmp = (sym) ? (sym) : (&tmp_sym);
+
+						if (gelf_getsym(lte[i].dynsym, symidx, tmp) == NULL)
+							error(EXIT_FAILURE, 0, "Couldn't get symbol from .dynsym");
+						else {
+							tmp->st_value += lte[i].base_addr;
+							debug(2, "symbol found: %s, %zd, %lx", name, i, tmp->st_value);
+						}
+						if (tmp->st_value != 0
+						    && tmp->st_shndx != SHN_UNDEF
+						    && strcmp(name, lte[i].dynstr + tmp->st_name) == 0)
 							return 1;
 					}
 				while ((*hasharr++ & 1u) == 0);
@@ -419,15 +424,22 @@ in_load_libraries(const char *name, struct ltelf *lte) {
 
 			for (symndx = buckets[hash % nbuckets];
 			     symndx != STN_UNDEF; symndx = chain[symndx]) {
-				GElf_Sym sym;
+				GElf_Sym tmp_sym;
+				GElf_Sym *tmp;
+
+				tmp = (sym) ? (sym) : (&tmp_sym);
 
-				if (gelf_getsym(lte[i].dynsym, symndx, &sym) == NULL)
+				if (gelf_getsym(lte[i].dynsym, symndx, tmp) == NULL)
 					error(EXIT_FAILURE, 0,
 					      "Couldn't get symbol from .dynsym");
+				else {
+					tmp->st_value += lte[i].base_addr;
+					debug(2, "symbol found: %s, %zd, %lx", name, i, tmp->st_value);
+				}
 
-				if (sym.st_value != 0
-				    && sym.st_shndx != SHN_UNDEF
-				    && strcmp(name, lte[i].dynstr + sym.st_name) == 0)
+				if (tmp->st_value != 0
+				    && tmp->st_shndx != SHN_UNDEF
+				    && strcmp(name, lte[i].dynstr + tmp->st_name) == 0)
 					return 1;
 			}
 		}
@@ -462,6 +474,7 @@ read_elf(Process *proc) {
 	struct opt_x_t *xptr;
 	struct library_symbol **lib_tail = NULL;
 	int exit_out = 0;
+	int count  = 0;
 
 	debug(DEBUG_FUNCTION, "read_elf(file=%s)", proc->filename);
 
@@ -526,15 +539,16 @@ read_elf(Process *proc) {
 				proc->need_to_reinitialize_breakpoints = 1;
 #endif
 
-		name = lte->dynstr + sym.st_name;
-		if (in_load_libraries(name, lte)) {
-			addr = arch_plt_sym_val(lte, i, &rela);
-			add_library_symbol(addr, name, &library_symbols,
-					   (PLTS_ARE_EXECUTABLE(lte)
-					   ?  LS_TOPLT_EXEC : LS_TOPLT_POINT),
-					   ELF64_ST_BIND(sym.st_info) == STB_WEAK);
-			if (!lib_tail)
-				lib_tail = &(library_symbols->next);
+			name = lte->dynstr + sym.st_name;
+			count = library_num ? library_num+1 : 0;
+			if (in_load_libraries(name, lte, count, NULL)) {
+				addr = arch_plt_sym_val(lte, i, &rela);
+				add_library_symbol(addr, name, &library_symbols,
+						(PLTS_ARE_EXECUTABLE(lte)
+						 ?	LS_TOPLT_EXEC : LS_TOPLT_POINT),
+						ELF64_ST_BIND(sym.st_info) == STB_WEAK);
+				if (!lib_tail)
+					lib_tail = &(library_symbols->next);
 			}
 		}
 #endif // !__mips__
-- 
1.7.0.4




More information about the Ltrace-devel mailing list