clarified some int return code checking
[platform/upstream/ltrace.git] / ltrace-elf.c
index 92b642b..a6a5531 100644 (file)
@@ -361,8 +361,11 @@ ltelf_init(struct ltelf *lte, const char *filename)
 {
        memset(lte, 0, sizeof *lte);
        lte->fd = open(filename, O_RDONLY);
-       if (lte->fd == -1)
+       if (lte->fd == -1) {
+               fprintf(stderr, "Can't open %s: %s\n", filename,
+                       strerror(errno));
                return 1;
+       }
 
        elf_version(EV_CURRENT);
 
@@ -531,6 +534,38 @@ elf_read_relocs(struct ltelf *lte, Elf_Scn *scn, GElf_Shdr *shdr,
        return 0;
 }
 
+int
+elf_load_dynamic_entry(struct ltelf *lte, int tag, GElf_Addr *valuep)
+{
+       Elf_Scn *scn;
+       GElf_Shdr shdr;
+       if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0
+           || scn == NULL) {
+       fail:
+               fprintf(stderr, "Couldn't get SHT_DYNAMIC: %s\n",
+                       elf_errmsg(-1));
+               return -1;
+       }
+
+       Elf_Data *data = elf_loaddata(scn, &shdr);
+       if (data == NULL)
+               goto fail;
+
+       size_t j;
+       for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) {
+               GElf_Dyn dyn;
+               if (gelf_getdyn(data, j, &dyn) == NULL)
+                       goto fail;
+
+               if(dyn.d_tag == tag) {
+                       *valuep = dyn.d_un.d_ptr;
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
 static int
 ltelf_read_elf(struct ltelf *lte, const char *filename)
 {
@@ -824,7 +859,7 @@ populate_plt(struct process *proc, const char *filename,
        return 0;
 }
 
-static void
+void
 delete_symbol_chain(struct library_symbol *libsym)
 {
        while (libsym != NULL) {
@@ -866,13 +901,8 @@ static int
 populate_this_symtab(struct process *proc, const char *filename,
                     struct ltelf *lte, struct library *lib,
                     Elf_Data *symtab, const char *strtab, size_t count,
-                    struct library_exported_name **names)
+                    struct library_exported_name*names)
 {
-       /* If a valid NAMES is passed, we pass in *NAMES a list of
-        * symbol names that this library exports.  */
-       if (names != NULL)
-               *names = NULL;
-
        /* Using sorted array would be arguably better, but this
         * should be well enough for the number of symbols that we
         * typically deal with.  */
@@ -922,20 +952,14 @@ populate_this_symtab(struct process *proc, const char *filename,
 
                /* If we are interested in exports, store this name.  */
                if (names != NULL) {
-                       struct library_exported_name *export
-                               = malloc(sizeof *export);
                        char *name_copy = strdup(name);
-
-                       if (name_copy == NULL || export == NULL) {
-                               free(name_copy);
-                               free(export);
+                       if (name_copy == NULL ||
+                           library_exported_names_push(names,
+                                                       sym.st_value,
+                                                       name_copy, 1) != 0)
+                       {
                                fprintf(stderr, "Couldn't store symbol %s.  "
                                        "Tracing may be incomplete.\n", name);
-                       } else {
-                               export->name = name_copy;
-                               export->own_name = 1;
-                               export->next = *names;
-                               *names = export;
                        }
                }
 
@@ -1080,7 +1104,7 @@ populate_symtab(struct process *proc, const char *filename,
 
        /* Check whether we want to trace symbols implemented by this
         * library (-l).  */
-       struct library_exported_name **names = NULL;
+       struct library_exported_name*names = NULL;
        if (exports) {
                debug(DEBUG_FUNCTION, "-l matches %s", lib->soname);
                names = &lib->exported_names;