From: "Edgar E. Iglesias" <[email protected]>

No functional change. Will be used by the MIPS backend.

Signed-off-by: Edgar E. Iglesias <[email protected]>
---
 backend.h    |   15 +++++++++++++++
 ltrace-elf.c |   54 ++++++++++++++++++++++++++++++++++--------------------
 2 files changed, 49 insertions(+), 20 deletions(-)

diff --git a/backend.h b/backend.h
index bae53bd..e241eab 100644
--- a/backend.h
+++ b/backend.h
@@ -266,6 +266,21 @@ void arch_process_destroy(struct Process *proc);
 int arch_process_clone(struct Process *retp, struct Process *proc);
 int arch_process_exec(struct Process *proc);
 
+/* The following callback has to be implemented in backend if arch.h
+ * defines ARCH_HAVE_GET_SYM_INFO.
+ *
+ * This is called for every PLT relocation R in ELF file LTE, that
+ * ltrace is about to add to it's internal representation of the
+ * program under trace.
+ * The corresponding PLT entry is for SYM_INDEX-th relocation in the file.
+ *
+ * The callback is responsible for initializing RELA and SYM.
+ *
+ * Return 0 if OK.
+ * Return a negative value if this symbol (SYM_INDEX) should be ignored.  */
+int arch_get_sym_info(struct ltelf *lte, const char *filename,
+                     size_t sym_index, GElf_Rela *rela, GElf_Sym *sym);
+
 enum plt_status {
        plt_fail,
        plt_ok,
diff --git a/ltrace-elf.c b/ltrace-elf.c
index bc99c6a..80f18df 100644
--- a/ltrace-elf.c
+++ b/ltrace-elf.c
@@ -510,35 +510,49 @@ do_close_elf(struct ltelf *lte) {
        close(lte->fd);
 }
 
+#ifndef ARCH_HAVE_GET_SYMINFO
+int
+arch_get_sym_info(struct ltelf *lte, const char *filename,
+                 size_t sym_index, GElf_Rela *rela, GElf_Sym *sym)
+{
+       int i = sym_index;
+       GElf_Rel rel;
+       void *ret;
+
+       if (lte->relplt->d_type == ELF_T_REL) {
+               ret = gelf_getrel(lte->relplt, i, &rel);
+               rela->r_offset = rel.r_offset;
+               rela->r_info = rel.r_info;
+               rela->r_addend = 0;
+       } else {
+               ret = gelf_getrela(lte->relplt, i, rela);
+       }
+
+       if (ret == NULL
+           || ELF64_R_SYM(rela->r_info) >= lte->dynsym_count
+           || gelf_getsym(lte->dynsym, ELF64_R_SYM(rela->r_info),
+                          sym) == NULL) {
+               fprintf(stderr,
+                       "Couldn't get relocation from \"%s\": %s\n",
+                       filename, elf_errmsg(-1));
+               exit(EXIT_FAILURE);
+       }
+
+       return 0;
+}
+#endif
+
 static int
 populate_plt(struct Process *proc, const char *filename,
             struct ltelf *lte, struct library *lib)
 {
        size_t i;
        for (i = 0; i < lte->relplt_count; ++i) {
-               GElf_Rel rel;
                GElf_Rela rela;
                GElf_Sym sym;
-               void *ret;
-
-               if (lte->relplt->d_type == ELF_T_REL) {
-                       ret = gelf_getrel(lte->relplt, i, &rel);
-                       rela.r_offset = rel.r_offset;
-                       rela.r_info = rel.r_info;
-                       rela.r_addend = 0;
-               } else {
-                       ret = gelf_getrela(lte->relplt, i, &rela);
-               }
 
-               if (ret == NULL
-                   || ELF64_R_SYM(rela.r_info) >= lte->dynsym_count
-                   || gelf_getsym(lte->dynsym, ELF64_R_SYM(rela.r_info),
-                                  &sym) == NULL) {
-                       fprintf(stderr,
-                               "Couldn't get relocation from \"%s\": %s\n",
-                               filename, elf_errmsg(-1));
-                       exit(EXIT_FAILURE);
-               }
+               if (arch_get_sym_info(lte, filename, i, &rela, &sym) < 0)
+                       continue; /* Skip this entry.  */
 
                char const *name = lte->dynstr + sym.st_name;
 
-- 
1.7.8.6


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

Reply via email to