asan: more readelf leaks
[deliverable/binutils-gdb.git] / binutils / readelf.c
index 6b5bebe743f34a9ebeeb85943fbbcb87757bcba2..4e21bdb56c9125e4940cb0baa6d244560aa2cab5 100644 (file)
@@ -1629,7 +1629,8 @@ dump_relocations (Filedata *          filedata,
        {
          if (symtab == NULL || symtab_index >= nsyms)
            {
-             error (_(" bad symbol index: %08lx in reloc"), (unsigned long) symtab_index);
+             error (_(" bad symbol index: %08lx in reloc\n"),
+                    (unsigned long) symtab_index);
              res = FALSE;
            }
          else
@@ -1733,7 +1734,8 @@ dump_relocations (Filedata *          filedata,
                printf (_("<string table index: %3ld>"), psym->st_name);
              else if (psym->st_name >= strtablen)
                {
-                 error (_("<corrupt string table index: %3ld>"), psym->st_name);
+                 error (_("<corrupt string table index: %3ld>\n"),
+                        psym->st_name);
                  res = FALSE;
                }
              else
@@ -3767,6 +3769,7 @@ get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
            case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
            case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
            case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
+           case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
            default:
              strcat (buf, _(", unknown")); break;
            }
@@ -6114,6 +6117,7 @@ process_section_headers (Filedata * filedata)
   Elf_Internal_Shdr * section;
   unsigned int i;
 
+  free (filedata->section_headers);
   filedata->section_headers = NULL;
 
   if (filedata->file_header.e_shnum == 0)
@@ -6169,10 +6173,20 @@ process_section_headers (Filedata * filedata)
 
   /* Scan the sections for the dynamic symbol table
      and dynamic string table and debug sections.  */
+  free (dynamic_symbols);
   dynamic_symbols = NULL;
+  num_dynamic_syms = 0;
+  free (dynamic_strings);
   dynamic_strings = NULL;
+  dynamic_strings_length = 0;
+  free (dynamic_syminfo);
   dynamic_syminfo = NULL;
-  symtab_shndx_list = NULL;
+  while (symtab_shndx_list != NULL)
+    {
+      elf_section_list *next = symtab_shndx_list->next;
+      free (symtab_shndx_list);
+      symtab_shndx_list = next;
+    }
 
   eh_addr_size = is_32bit_elf ? 4 : 8;
   switch (filedata->file_header.e_machine)
@@ -7088,7 +7102,7 @@ dump_ia64_vms_dynamic_fixups (Filedata *                  filedata,
   const char * lib_name;
 
   imfs = get_data (NULL, filedata, dynamic_addr + fixup->fixup_rela_off,
-                  1, fixup->fixup_rela_cnt * sizeof (*imfs),
+                  sizeof (*imfs), fixup->fixup_rela_cnt,
                   _("dynamic section image fixups"));
   if (!imfs)
     return FALSE;
@@ -7101,6 +7115,7 @@ dump_ia64_vms_dynamic_fixups (Filedata *                  filedata,
             (unsigned long) fixup->needed);
       lib_name = "???";
     }
+
   printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
          (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
   printf
@@ -7136,7 +7151,7 @@ dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *i
   long i;
 
   imrs = get_data (NULL, filedata, dynamic_addr + imgrela->img_rela_off,
-                  1, imgrela->img_rela_cnt * sizeof (*imrs),
+                  sizeof (*imrs), imgrela->img_rela_cnt,
                   _("dynamic section image relocations"));
   if (!imrs)
     return FALSE;
@@ -7200,6 +7215,8 @@ process_ia64_vms_dynamic_relocs (Filedata * filedata)
           if (strtab == NULL)
             strtab = get_data (NULL, filedata, dynamic_addr + strtab_off,
                                1, strtab_sz, _("dynamic string section"));
+         if (strtab == NULL)
+           strtab_sz = 0;
           break;
 
         case DT_IA_64_VMS_NEEDED_IDENT:
@@ -8786,7 +8803,7 @@ decode_arm_unwind_bytecode (Filedata *                 filedata,
            }
          if (i == sizeof (buf))
            {
-             error (_("corrupt change to vsp"));
+             error (_("corrupt change to vsp\n"));
              res = FALSE;
            }
          else
@@ -9877,7 +9894,8 @@ process_dynamic_section (Filedata * filedata)
          if ((bfd_size_type) section.sh_offset > filedata->file_size)
            {
              /* See PR 21379 for a reproducer.  */
-             error (_("Invalid DT_SYMTAB entry: %lx"), (long) section.sh_offset);
+             error (_("Invalid DT_SYMTAB entry: %lx\n"),
+                    (long) section.sh_offset);
              return FALSE;
            }
 
@@ -10891,9 +10909,9 @@ process_version_sections (Filedata * filedata)
            off = offset_from_vma (filedata,
                                   version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
                                   total * sizeof (short));
-           edata = (unsigned char *) get_data (NULL, filedata, off, total,
-                                                sizeof (short),
-                                                _("version symbol data"));
+           edata = (unsigned char *) get_data (NULL, filedata, off,
+                                               sizeof (short), total,
+                                               _("version symbol data"));
            if (!edata)
              {
                free (strtab);
@@ -11176,7 +11194,7 @@ get_symbol_visibility (unsigned int visibility)
     case STV_HIDDEN:   return "HIDDEN";
     case STV_PROTECTED: return "PROTECTED";
     default:
-      error (_("Unrecognized visibility value: %u"), visibility);
+      error (_("Unrecognized visibility value: %u\n"), visibility);
       return _("<unknown>");
     }
 }
@@ -11189,7 +11207,7 @@ get_alpha_symbol_other (unsigned int other)
     case STO_ALPHA_NOPV:       return "NOPV";
     case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
     default:
-      error (_("Unrecognized alpah specific other value: %u"), other);
+      error (_("Unrecognized alpha specific other value: %u\n"), other);
       return _("<unknown>");
     }
 }
@@ -11421,7 +11439,7 @@ get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_si
       return NULL;
     }
 
-  /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
+  /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
      attempting to allocate memory when the read is bound to fail.  */
   if (ent_size * number > filedata->file_size)
     {
@@ -11748,17 +11766,17 @@ process_symbol_table (Filedata * filedata)
       buckets = get_dynamic_data (filedata, nbuckets, hash_ent_size);
       chains  = get_dynamic_data (filedata, nchains, hash_ent_size);
 
-    no_hash:
       if (buckets == NULL || chains == NULL)
        {
-         if (do_using_dynamic)
-           return FALSE;
+       no_hash:
          free (buckets);
          free (chains);
          buckets = NULL;
          chains = NULL;
          nbuckets = 0;
          nchains = 0;
+         if (do_using_dynamic)
+           goto err_out;
        }
     }
 
@@ -11815,7 +11833,7 @@ process_symbol_table (Filedata * filedata)
        if (gnubuckets[i] != 0)
          {
            if (gnubuckets[i] < gnusymidx)
-             return FALSE;
+             goto err_out;
 
            if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
              maxchain = gnubuckets[i];
@@ -11880,21 +11898,17 @@ process_symbol_table (Filedata * filedata)
            }
 
          mipsxlat = get_dynamic_data (filedata, maxchain, 4);
-       }
-
-    no_gnu_hash:
-      if (dynamic_info_DT_MIPS_XHASH && mipsxlat == NULL)
-       {
-         free (gnuchains);
-         gnuchains = NULL;
-       }
-      if (gnuchains == NULL)
-       {
-         free (gnubuckets);
-         gnubuckets = NULL;
-         ngnubuckets = 0;
-         if (do_using_dynamic)
-           return FALSE;
+         if (mipsxlat == NULL)
+           {
+           no_gnu_hash:
+             free (gnuchains);
+             gnuchains = NULL;
+             free (gnubuckets);
+             gnubuckets = NULL;
+             ngnubuckets = 0;
+             if (do_using_dynamic)
+               goto err_out;
+           }
        }
     }
 
@@ -12111,7 +12125,7 @@ process_symbol_table (Filedata * filedata)
       if (lengths == NULL)
        {
          error (_("Out of memory allocating space for histogram buckets\n"));
-         return FALSE;
+         goto err_out;
        }
       visited = xcmalloc (nchains, 1);
       memset (visited, 0, nchains);
@@ -12139,7 +12153,7 @@ process_symbol_table (Filedata * filedata)
        {
          free (lengths);
          error (_("Out of memory allocating space for histogram counts\n"));
-         return FALSE;
+         goto err_out;
        }
 
       for (hn = 0; hn < nbuckets; ++hn)
@@ -12163,11 +12177,10 @@ process_symbol_table (Filedata * filedata)
       free (lengths);
     }
 
-  if (buckets != NULL)
-    {
-      free (buckets);
-      free (chains);
-    }
+  free (buckets);
+  buckets = NULL;
+  free (chains);
+  chains = NULL;
 
   if (do_histogram && gnubuckets != NULL)
     {
@@ -12190,7 +12203,7 @@ process_symbol_table (Filedata * filedata)
       if (lengths == NULL)
        {
          error (_("Out of memory allocating space for gnu histogram buckets\n"));
-         return FALSE;
+         goto err_out;
        }
 
       printf (_(" Length  Number     %% of total  Coverage\n"));
@@ -12216,7 +12229,7 @@ process_symbol_table (Filedata * filedata)
        {
          free (lengths);
          error (_("Out of memory allocating space for gnu histogram counts\n"));
-         return FALSE;
+         goto err_out;
        }
 
       for (hn = 0; hn < ngnubuckets; ++hn)
@@ -12238,12 +12251,19 @@ process_symbol_table (Filedata * filedata)
 
       free (counts);
       free (lengths);
-      free (gnubuckets);
-      free (gnuchains);
-      free (mipsxlat);
     }
-
+  free (gnubuckets);
+  free (gnuchains);
+  free (mipsxlat);
   return TRUE;
+
+ err_out:
+  free (gnubuckets);
+  free (gnuchains);
+  free (mipsxlat);
+  free (buckets);
+  free (chains);
+  return FALSE;
 }
 
 static bfd_boolean
@@ -13725,6 +13745,14 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
   end  = start + num_bytes;
   some_strings_shown = FALSE;
 
+#ifdef HAVE_MBSTATE_T
+  mbstate_t state;
+  /* Initialise the multibyte conversion state.  */
+  memset (& state, 0, sizeof (state));
+#endif
+
+  bfd_boolean continuing = FALSE;
+
   while (data < end)
     {
       while (!ISPRINT (* data))
@@ -13735,18 +13763,76 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
        {
          size_t maxlen = end - data;
 
+         if (continuing)
+           {
+             printf ("            ");
+             continuing = FALSE;
+           }
+         else
+           {
 #ifndef __MSVCRT__
-         /* PR 11128: Use two separate invocations in order to work
-             around bugs in the Solaris 8 implementation of printf.  */
-         printf ("  [%6tx]  ", data - start);
+             /* PR 11128: Use two separate invocations in order to work
+                around bugs in the Solaris 8 implementation of printf.  */
+             printf ("  [%6tx]  ", data - start);
 #else
-         printf ("  [%6Ix]  ", (size_t) (data - start));
+             printf ("  [%6Ix]  ", (size_t) (data - start));
 #endif
+           }
+
          if (maxlen > 0)
            {
-             print_symbol ((int) maxlen, (const char *) data);
-             putchar ('\n');
-             data += strnlen ((const char *) data, maxlen);
+             char c;
+
+             while (maxlen)
+               {
+                 c = *data++;
+
+                 if (c == 0)
+                   break;
+
+                 /* PR 25543: Treat new-lines as string-ending characters.  */
+                 if (c == '\n')
+                   {
+                     printf ("\\n\n");
+                     if (*data != 0)
+                       continuing = TRUE;
+                     break;
+                   }
+
+                 /* Do not print control characters directly as they can affect terminal
+                    settings.  Such characters usually appear in the names generated
+                    by the assembler for local labels.  */
+                 if (ISCNTRL (c))
+                   {
+                     printf ("^%c", c + 0x40);
+                   }
+                 else if (ISPRINT (c))
+                   {
+                     putchar (c);
+                   }
+                 else
+                   {
+                     size_t  n;
+#ifdef HAVE_MBSTATE_T
+                     wchar_t w;
+#endif
+                     /* Let printf do the hard work of displaying multibyte characters.  */
+                     printf ("%.1s", data - 1);
+#ifdef HAVE_MBSTATE_T
+                     /* Try to find out how many bytes made up the character that was
+                        just printed.  Advance the symbol pointer past the bytes that
+                        were displayed.  */
+                     n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
+#else
+                     n = 1;
+#endif
+                     if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
+                       data += (n - 1);
+                   }
+               }
+
+             if (c != '\n')
+               putchar ('\n');
            }
          else
            {
@@ -14122,7 +14208,7 @@ load_specific_debug_section (enum dwarf_section_display_enum  debug,
                      ? sizeof (Elf32_External_Chdr)
                      : sizeof (Elf64_External_Chdr)))
            {
-             warn (_("compressed section %s is too small to contain a compression header"),
+             warn (_("compressed section %s is too small to contain a compression header\n"),
                    section->name);
              return FALSE;
            }
@@ -14204,7 +14290,8 @@ get_build_id (void * data)
   Elf_Internal_Shdr * shdr;
   unsigned long i;
 
-  /* Iterate through notes to find note.gnu.build-id.  */
+  /* Iterate through notes to find note.gnu.build-id.
+     FIXME: Only the first note in any note section is examined.  */
   for (i = 0, shdr = filedata->section_headers;
        i < filedata->file_header.e_shnum && shdr != NULL;
        i++, shdr++)
@@ -14240,13 +14327,10 @@ get_build_id (void * data)
           min_notesz = offsetof (Elf_External_Note, name);
           if (data_remaining < min_notesz)
             {
-              warn (ngettext ("debuginfod: Corrupt note: only %ld byte remains, "
-                              "not enough for a full note\n",
-                              "Corrupt note: only %ld bytes remain, "
-                              "not enough for a full note\n",
-                              data_remaining),
-                    (long) data_remaining);
-              break;
+             warn (_("\
+malformed note encountered in section %s whilst scanning for build-id note\n"),
+                   printable_section_name (filedata, shdr));
+              continue;
             }
           data_remaining -= min_notesz;
 
@@ -14269,13 +14353,10 @@ get_build_id (void * data)
           min_notesz = offsetof (Elf64_External_VMS_Note, name);
           if (data_remaining < min_notesz)
             {
-              warn (ngettext ("debuginfod: Corrupt note: only %ld byte remains, "
-                              "not enough for a full note\n",
-                              "Corrupt note: only %ld bytes remain, "
-                              "not enough for a full note\n",
-                              data_remaining),
-                    (long) data_remaining);
-              break;
+             warn (_("\
+malformed note encountered in section %s whilst scanning for build-id note\n"),
+                   printable_section_name (filedata, shdr));
+              continue;
             }
           data_remaining -= min_notesz;
 
@@ -14296,9 +14377,9 @@ get_build_id (void * data)
           || ((size_t) (next - inote.descdata)
               > data_remaining - (size_t) (inote.descdata - inote.namedata)))
         {
-          warn (_("debuginfod: note with invalid namesz and/or descsz found\n"));
-          warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
-                inote.type, inote.namesz, inote.descsz, (int) align);
+         warn (_("\
+malformed note encountered in section %s whilst scanning for build-id note\n"),
+               printable_section_name (filedata, shdr));
           continue;
         }
 
@@ -14313,13 +14394,13 @@ get_build_id (void * data)
 
           build_id = malloc (inote.descsz * 2 + 1);
           if (build_id == NULL)
-              return NULL;
+           return NULL;
 
           for (j = 0; j < inote.descsz; ++j)
             sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
           build_id[inote.descsz * 2] = '\0';
 
-          return (unsigned char *)build_id;
+          return (unsigned char *) build_id;
         }
     }
 
@@ -16571,9 +16652,9 @@ process_mips_specific (Filedata * filedata)
       size_t cnt;
 
       elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
-                                              liblistno,
-                                              sizeof (Elf32_External_Lib),
-                                              _("liblist section data"));
+                                             sizeof (Elf32_External_Lib),
+                                             liblistno,
+                                             _("liblist section data"));
       if (elib)
        {
          printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
@@ -16940,8 +17021,8 @@ process_mips_specific (Filedata * filedata)
          Elf32_External_Conflict * econf32;
 
          econf32 = (Elf32_External_Conflict *)
-              get_data (NULL, filedata, conflicts_offset, conflictsno,
-                        sizeof (* econf32), _("conflict"));
+           get_data (NULL, filedata, conflicts_offset,
+                     sizeof (*econf32), conflictsno, _("conflict"));
          if (!econf32)
            return FALSE;
 
@@ -16955,8 +17036,8 @@ process_mips_specific (Filedata * filedata)
          Elf64_External_Conflict * econf64;
 
          econf64 = (Elf64_External_Conflict *)
-              get_data (NULL, filedata, conflicts_offset, conflictsno,
-                        sizeof (* econf64), _("conflict"));
+           get_data (NULL, filedata, conflicts_offset,
+                     sizeof (*econf64), conflictsno, _("conflict"));
          if (!econf64)
            return FALSE;
 
@@ -18062,7 +18143,7 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
        printf ("%02x ", ptr[j] & 0xff);
       printf (">");
 
-next:
+    next:
       ptr += ((datasz + (size - 1)) & ~ (size - 1));
       if (ptr == ptr_end)
        break;
@@ -18694,6 +18775,14 @@ print_ia64_vms_note (Elf_Internal_Note * pnote)
   return FALSE;
 }
 
+struct build_attr_cache {
+  Filedata *filedata;
+  char *strtab;
+  unsigned long strtablen;
+  Elf_Internal_Sym *symtab;
+  unsigned long nsyms;
+} ba_cache;
+
 /* Find the symbol associated with a build attribute that is attached
    to address OFFSET.  If PNAME is non-NULL then store the name of
    the symbol (if found) in the provided pointer,  Returns NULL if a
@@ -18705,19 +18794,19 @@ get_symbol_for_build_attribute (Filedata *       filedata,
                                bfd_boolean      is_open_attr,
                                const char **    pname)
 {
-  static Filedata *         saved_filedata = NULL;
-  static char *             strtab;
-  static unsigned long      strtablen;
-  static Elf_Internal_Sym * symtab;
-  static unsigned long      nsyms;
-  Elf_Internal_Sym *        saved_sym = NULL;
-  Elf_Internal_Sym *        sym;
+  Elf_Internal_Sym *saved_sym = NULL;
+  Elf_Internal_Sym *sym;
 
   if (filedata->section_headers != NULL
-      && (saved_filedata == NULL || filedata != saved_filedata))
+      && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
     {
       Elf_Internal_Shdr * symsec;
 
+      free (ba_cache.strtab);
+      ba_cache.strtab = NULL;
+      free (ba_cache.symtab);
+      ba_cache.symtab = NULL;
+
       /* Load the symbol and string sections.  */
       for (symsec = filedata->section_headers;
           symsec < filedata->section_headers + filedata->file_header.e_shnum;
@@ -18725,41 +18814,52 @@ get_symbol_for_build_attribute (Filedata *       filedata,
        {
          if (symsec->sh_type == SHT_SYMTAB)
            {
-             symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
+             ba_cache.symtab = GET_ELF_SYMBOLS (filedata, symsec,
+                                                &ba_cache.nsyms);
 
-             if (symsec->sh_link < filedata->file_header.e_shnum)
+             if (ba_cache.symtab != NULL
+                 && symsec->sh_link < filedata->file_header.e_shnum)
                {
-                 Elf_Internal_Shdr * strtab_sec = filedata->section_headers + symsec->sh_link;
-
-                 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
-                                             1, strtab_sec->sh_size,
-                                             _("string table"));
-                 strtablen = strtab != NULL ? strtab_sec->sh_size : 0;
+                 Elf_Internal_Shdr *strtab_sec
+                   = filedata->section_headers + symsec->sh_link;
+
+                 ba_cache.strtab
+                   = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
+                                        1, strtab_sec->sh_size,
+                                        _("string table"));
+                 ba_cache.strtablen = strtab_sec->sh_size;
                }
+             if (ba_cache.strtab == NULL)
+               {
+                 free (ba_cache.symtab);
+                 ba_cache.symtab = NULL;
+               }
+             if (ba_cache.symtab != NULL)
+               break;
            }
        }
-      saved_filedata = filedata;
+      ba_cache.filedata = filedata;
     }
 
-  if (symtab == NULL || strtab == NULL)
+  if (ba_cache.symtab == NULL)
     return NULL;
 
   /* Find a symbol whose value matches offset.  */
-  for (sym = symtab; sym < symtab + nsyms; sym ++)
+  for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
     if (sym->st_value == offset)
       {
-       if (sym->st_name >= strtablen)
+       if (sym->st_name >= ba_cache.strtablen)
          /* Huh ?  This should not happen.  */
          continue;
 
-       if (strtab[sym->st_name] == 0)
+       if (ba_cache.strtab[sym->st_name] == 0)
          continue;
 
        /* The AArch64 and ARM architectures define mapping symbols
           (eg $d, $x, $t) which we want to ignore.  */
-       if (strtab[sym->st_name] == '$'
-           && strtab[sym->st_name + 1] != 0
-           && strtab[sym->st_name + 2] == 0)
+       if (ba_cache.strtab[sym->st_name] == '$'
+           && ba_cache.strtab[sym->st_name + 1] != 0
+           && ba_cache.strtab[sym->st_name + 2] == 0)
          continue;
 
        if (is_open_attr)
@@ -18776,7 +18876,7 @@ get_symbol_for_build_attribute (Filedata *       filedata,
                  {
                    /* If the symbol has a size associated
                       with it then we can stop searching.  */
-                   sym = symtab + nsyms;
+                   sym = ba_cache.symtab + ba_cache.nsyms;
                  }
                continue;
 
@@ -18816,7 +18916,7 @@ get_symbol_for_build_attribute (Filedata *       filedata,
       }
 
   if (saved_sym && pname)
-    * pname = strtab + saved_sym->st_name;
+    * pname = ba_cache.strtab + saved_sym->st_name;
 
   return saved_sym;
 }
@@ -20053,6 +20153,13 @@ process_object (Filedata * filedata)
       dynamic_section = NULL;
     }
 
+  while (symtab_shndx_list != NULL)
+    {
+      elf_section_list *next = symtab_shndx_list->next;
+      free (symtab_shndx_list);
+      symtab_shndx_list = next;
+    }
+
   if (section_headers_groups)
     {
       free (section_headers_groups);
@@ -20152,6 +20259,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
                          putchar ('\n');
                          free (qualified_name);
                        }
+                     free (member_name);
                    }
                }
 
@@ -20254,6 +20362,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
       if (qualified_name == NULL)
        {
          error (_("%s: bad archive file name\n"), arch.file_name);
+         free (name);
          ret = FALSE;
          break;
        }
@@ -20265,8 +20374,10 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
           char * member_file_name = adjust_relative_path
            (filedata->file_name, name, namelen);
 
+         free (name);
           if (member_file_name == NULL)
             {
+             free (qualified_name);
               ret = FALSE;
               break;
             }
@@ -20276,6 +20387,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
             {
               error (_("Input file '%s' is not readable.\n"), member_file_name);
               free (member_file_name);
+             free (qualified_name);
               ret = FALSE;
               break;
             }
@@ -20288,6 +20400,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
 
           close_file (member_filedata);
           free (member_file_name);
+         free (qualified_name);
         }
       else if (is_thin_archive)
         {
@@ -20300,9 +20413,12 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
            {
              error (_("%s: contains corrupt thin archive: %s\n"),
                     qualified_name, name);
+             free (qualified_name);
+             free (name);
              ret = FALSE;
              break;
            }
+         free (name);
 
           /* This is a proxy for a member of a nested archive.  */
           archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
@@ -20312,6 +20428,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
           if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
             {
               error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
+             free (qualified_name);
               ret = FALSE;
               break;
             }
@@ -20324,6 +20441,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
         }
       else
         {
+         free (name);
           archive_file_offset = arch.next_arhdr_offset;
           arch.next_arhdr_offset += archive_file_size;
 
@@ -20418,8 +20536,16 @@ process_file (char * file_name)
     }
 
   fclose (filedata->handle);
+  free (filedata->section_headers);
+  free (filedata->program_headers);
+  free (filedata->string_table);
+  free (filedata->dump_sects);
   free (filedata);
 
+  free (ba_cache.strtab);
+  free (ba_cache.symtab);
+  ba_cache.filedata = NULL;
+
   return ret;
 }
 
This page took 0.040081 seconds and 4 git commands to generate.