---
 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


_______________________________________________
Ltrace-devel mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/ltrace-devel

Reply via email to