X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Freadelf.c;h=d17537aa52ae53549fde411e3a2206eb344871f5;hb=61865e301bd3c544e5380542b9d0072c421e3b32;hp=8c20888930fd543dbd4efb2533981676b7c5c811;hpb=3832723d11b381c5d2930834f2cc33dfae25819e;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/readelf.c b/binutils/readelf.c index 8c20888930..d17537aa52 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -1,6 +1,6 @@ /* readelf.c -- display contents of an ELF format file Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010 + 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Originally developed by Eric Youngdale @@ -61,6 +61,7 @@ #include "bfd.h" #include "bucomm.h" +#include "elfcomm.h" #include "dwarf.h" #include "elf/common.h" @@ -146,8 +147,6 @@ #include "elf/xstormy16.h" #include "elf/xtensa.h" -#include "aout/ar.h" - #include "getopt.h" #include "libiberty.h" #include "safe-ctype.h" @@ -260,8 +259,6 @@ typedef enum print_mode } print_mode; -static void (* byte_put) (unsigned char *, bfd_vma, int); - #define UNKNOWN -1 #define SECTION_NAME(X) \ @@ -272,9 +269,6 @@ static void (* byte_put) (unsigned char *, bfd_vma, int); #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ -#define BYTE_GET(field) byte_get (field, sizeof (field)) -#define BYTE_GET_SIGNED(field) byte_get_signed (field, sizeof (field)) - #define GET_ELF_SYMBOLS(file, section) \ (is_32bit_elf ? get_32bit_elf_symbols (file, section) \ : get_64bit_elf_symbols (file, section)) @@ -284,15 +278,13 @@ static void (* byte_put) (unsigned char *, bfd_vma, int); already been called and verified that the string exists. */ #define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset) -/* This is just a bit of syntatic sugar. */ -#define streq(a,b) (strcmp ((a), (b)) == 0) -#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) -#define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0) - -#define REMOVE_ARCH_BITS(ADDR) do { \ - if (elf_header.e_machine == EM_ARM) \ - (ADDR) &= ~1; \ - } while (0) +#define REMOVE_ARCH_BITS(ADDR) \ + do \ + { \ + if (elf_header.e_machine == EM_ARM) \ + (ADDR) &= ~1; \ + } \ + while (0) static void * get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb, @@ -340,36 +332,6 @@ get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb, return mvar; } -static void -byte_put_little_endian (unsigned char * field, bfd_vma value, int size) -{ - switch (size) - { - case 8: - field[7] = (((value >> 24) >> 24) >> 8) & 0xff; - field[6] = ((value >> 24) >> 24) & 0xff; - field[5] = ((value >> 24) >> 16) & 0xff; - field[4] = ((value >> 24) >> 8) & 0xff; - /* Fall through. */ - case 4: - field[3] = (value >> 24) & 0xff; - /* Fall through. */ - case 3: - field[2] = (value >> 16) & 0xff; - /* Fall through. */ - case 2: - field[1] = (value >> 8) & 0xff; - /* Fall through. */ - case 1: - field[0] = value & 0xff; - break; - - default: - error (_("Unhandled data length: %d\n"), size); - abort (); - } -} - /* Print a VMA value. */ static int @@ -421,15 +383,16 @@ print_vma (bfd_vma vma, print_mode mode) Returns the number of emitted characters. */ static unsigned int -print_symbol (int width, const char * symbol) +print_symbol (int width, const char *symbol) { - const char * c; + const char *c; bfd_boolean extra_padding = FALSE; unsigned int num_printed = 0; if (do_wide) { - /* Set the width to a very large value. This simplifies the code below. */ + /* Set the width to a very large value. This simplifies the + code below. */ width = INT_MAX; } else if (width < 0) @@ -448,7 +411,7 @@ print_symbol (int width, const char * symbol) /* Look for non-printing symbols inside the symbol's name. This test is triggered in particular by the names generated by the assembler for local labels. */ - while (ISPRINT (* c)) + while (ISPRINT (*c)) c++; len = c - symbol; @@ -464,12 +427,12 @@ print_symbol (int width, const char * symbol) num_printed += len; } - if (* c == 0 || width == 0) + if (*c == 0 || width == 0) break; /* Now display the non-printing character, if there is room left in which to dipslay it. */ - if (*c < 32) + if ((unsigned char) *c < 32) { if (width < 2) break; @@ -484,7 +447,7 @@ print_symbol (int width, const char * symbol) if (width < 6) break; - printf ("<0x%.2x>", *c); + printf ("<0x%.2x>", (unsigned char) *c); width -= 6; num_printed += 6; @@ -503,41 +466,6 @@ print_symbol (int width, const char * symbol) return num_printed; } -static void -byte_put_big_endian (unsigned char * field, bfd_vma value, int size) -{ - switch (size) - { - case 8: - field[7] = value & 0xff; - field[6] = (value >> 8) & 0xff; - field[5] = (value >> 16) & 0xff; - field[4] = (value >> 24) & 0xff; - value >>= 16; - value >>= 16; - /* Fall through. */ - case 4: - field[3] = value & 0xff; - value >>= 8; - /* Fall through. */ - case 3: - field[2] = value & 0xff; - value >>= 8; - /* Fall through. */ - case 2: - field[1] = value & 0xff; - value >>= 8; - /* Fall through. */ - case 1: - field[0] = value & 0xff; - break; - - default: - error (_("Unhandled data length: %d\n"), size); - abort (); - } -} - /* Return a pointer to section NAME, or NULL if no such section exists. */ static Elf_Internal_Shdr * @@ -1954,7 +1882,7 @@ get_machine_name (unsigned e_machine) case EM_S390_OLD: case EM_S390: return "IBM S/390"; case EM_SCORE: return "SUNPLUS S+Core"; - case EM_XSTORMY16: return "Sanyo Xstormy16 CPU core"; + case EM_XSTORMY16: return "Sanyo XStormy16 CPU core"; case EM_OPENRISC: case EM_OR32: return "OpenRISC"; case EM_ARC_A5: return "ARC International ARCompact processor"; @@ -3217,7 +3145,7 @@ usage (FILE * stream) -w[lLiaprmfFsoRt] or\n\ --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\ =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\ - =trace_info,=trace_abbrev,=trace_aranges]\n\ + =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\ Display the contents of DWARF2 debug sections\n")); #ifdef SUPPORT_DISASSEMBLY fprintf (stream, _("\ @@ -3713,7 +3641,11 @@ process_program_headers (FILE * file) if (elf_header.e_phnum == 0) { - if (do_segments) + /* PR binutils/12467. */ + if (elf_header.e_phoff != 0) + warn (_("possibly corrupt ELF header - it has a non-zero program" + " header offset, but no program headers")); + else if (do_segments) printf (_("\nThere are no program headers in this file.\n")); return 0; } @@ -4452,7 +4384,11 @@ process_section_headers (FILE * file) if (elf_header.e_shnum == 0) { - if (do_sections) + /* PR binutils/12467. */ + if (elf_header.e_shoff != 0) + warn (_("possibly corrupt ELF file header - it has a non-zero" + " section header offset, but no section headers\n")); + else if (do_sections) printf (_("\nThere are no sections in this file.\n")); return 1; @@ -4640,6 +4576,8 @@ process_section_headers (FILE * file) request_dump_bynumber (i, DEBUG_DUMP); else if (do_debug_frames && streq (name, ".eh_frame")) request_dump_bynumber (i, DEBUG_DUMP); + else if (do_gdb_index && streq (name, ".gdb_index")) + request_dump_bynumber (i, DEBUG_DUMP); /* Trace sections for Itanium VMS. */ else if ((do_debugging || do_trace_info || do_trace_abbrevs || do_trace_aranges) @@ -4933,7 +4871,7 @@ process_section_groups (FILE * file) if (elf_header.e_shnum == 0) { if (do_section_groups) - printf (_("\nThere are no sections in this file.\n")); + printf (_("\nThere are no sections to group in this file.\n")); return 1; } @@ -6533,11 +6471,13 @@ decode_arm_unwind (struct arm_unw_aux_info *aux, if ((op & 0xc0) == 0x00) { int offset = ((op & 0x3f) << 2) + 4; + printf (" vsp = vsp + %d", offset); } else if ((op & 0xc0) == 0x40) { int offset = ((op & 0x3f) << 2) + 4; + printf (" vsp = vsp - %d", offset); } else if ((op & 0xf0) == 0x80) @@ -6576,6 +6516,7 @@ decode_arm_unwind (struct arm_unw_aux_info *aux, int end = 4 + (op & 0x07); int first = 1; int i; + printf (" pop {"); for (i = 4; i <= end; i++) { @@ -6605,6 +6546,7 @@ decode_arm_unwind (struct arm_unw_aux_info *aux, unsigned int mask = op2 & 0x0f; int first = 1; int i; + printf ("pop {"); for (i = 0; i < 12; i++) if (mask & (1 << i)) @@ -6623,6 +6565,7 @@ decode_arm_unwind (struct arm_unw_aux_info *aux, unsigned char buf[9]; unsigned int i, len; unsigned long offset; + for (i = 0; i < sizeof (buf); i++) { GET_OP (buf[i]); @@ -6635,18 +6578,76 @@ decode_arm_unwind (struct arm_unw_aux_info *aux, offset = offset * 4 + 0x204; printf ("vsp = vsp + %ld", offset); } - else + else if (op == 0xb3 || op == 0xc8 || op == 0xc9) { - if (op == 0xb3 || op == 0xc6 || op == 0xc7 || op == 0xc8 || op == 0xc9) - { - GET_OP (op2); - printf (_("[unsupported two-byte opcode]")); - } + unsigned int first, last; + + GET_OP (op2); + first = op2 >> 4; + last = op2 & 0x0f; + if (op == 0xc8) + first = first + 16; + printf ("pop {D%d", first); + if (last) + printf ("-D%d", first + last); + printf ("}"); + } + else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0) + { + unsigned int count = op & 0x07; + + printf ("pop {D8"); + if (count) + printf ("-D%d", 8 + count); + printf ("}"); + } + else if (op >= 0xc0 && op <= 0xc5) + { + unsigned int count = op & 0x07; + + printf (" pop {wR10"); + if (count) + printf ("-wR%d", 10 + count); + printf ("}"); + } + else if (op == 0xc6) + { + unsigned int first, last; + + GET_OP (op2); + first = op2 >> 4; + last = op2 & 0x0f; + printf ("pop {wR%d", first); + if (last) + printf ("-wR%d", first + last); + printf ("}"); + } + else if (op == 0xc7) + { + GET_OP (op2); + if (op2 == 0 || (op2 & 0xf0) != 0) + printf (_("[Spare]")); else { - printf (_(" [unsupported opcode]")); + unsigned int mask = op2 & 0x0f; + int first = 1; + int i; + + printf ("pop {"); + for (i = 0; i < 4; i++) + if (mask & (1 << i)) + { + if (first) + first = 0; + else + printf (", "); + printf ("wCGR%d", i); + } + printf ("}"); } } + else + printf (_(" [unsupported opcode]")); printf ("\n"); } @@ -12478,6 +12479,12 @@ process_object (char * file_name, FILE * file) dynamic_syminfo = NULL; } + if (dynamic_section) + { + free (dynamic_section); + dynamic_section = NULL; + } + if (section_headers_groups) { free (section_headers_groups); @@ -12507,432 +12514,6 @@ process_object (char * file_name, FILE * file) return 0; } -/* Return the path name for a proxy entry in a thin archive, adjusted relative - to the path name of the thin archive itself if necessary. Always returns - a pointer to malloc'ed memory. */ - -static char * -adjust_relative_path (char * file_name, char * name, int name_len) -{ - char * member_file_name; - const char * base_name = lbasename (file_name); - - /* This is a proxy entry for a thin archive member. - If the extended name table contains an absolute path - name, or if the archive is in the current directory, - use the path name as given. Otherwise, we need to - find the member relative to the directory where the - archive is located. */ - if (IS_ABSOLUTE_PATH (name) || base_name == file_name) - { - member_file_name = (char *) malloc (name_len + 1); - if (member_file_name == NULL) - { - error (_("Out of memory\n")); - return NULL; - } - memcpy (member_file_name, name, name_len); - member_file_name[name_len] = '\0'; - } - else - { - /* Concatenate the path components of the archive file name - to the relative path name from the extended name table. */ - size_t prefix_len = base_name - file_name; - member_file_name = (char *) malloc (prefix_len + name_len + 1); - if (member_file_name == NULL) - { - error (_("Out of memory\n")); - return NULL; - } - memcpy (member_file_name, file_name, prefix_len); - memcpy (member_file_name + prefix_len, name, name_len); - member_file_name[prefix_len + name_len] = '\0'; - } - return member_file_name; -} - -/* Structure to hold information about an archive file. */ - -struct archive_info -{ - char * file_name; /* Archive file name. */ - FILE * file; /* Open file descriptor. */ - unsigned long index_num; /* Number of symbols in table. */ - unsigned long * index_array; /* The array of member offsets. */ - char * sym_table; /* The symbol table. */ - unsigned long sym_size; /* Size of the symbol table. */ - char * longnames; /* The long file names table. */ - unsigned long longnames_size; /* Size of the long file names table. */ - unsigned long nested_member_origin; /* Origin in the nested archive of the current member. */ - unsigned long next_arhdr_offset; /* Offset of the next archive header. */ - bfd_boolean is_thin_archive; /* TRUE if this is a thin archive. */ - struct ar_hdr arhdr; /* Current archive header. */ -}; - -/* Read the symbol table and long-name table from an archive. */ - -static int -setup_archive (struct archive_info * arch, char * file_name, FILE * file, - bfd_boolean is_thin_archive, bfd_boolean read_symbols) -{ - size_t got; - unsigned long size; - - arch->file_name = strdup (file_name); - arch->file = file; - arch->index_num = 0; - arch->index_array = NULL; - arch->sym_table = NULL; - arch->sym_size = 0; - arch->longnames = NULL; - arch->longnames_size = 0; - arch->nested_member_origin = 0; - arch->is_thin_archive = is_thin_archive; - arch->next_arhdr_offset = SARMAG; - - /* Read the first archive member header. */ - if (fseek (file, SARMAG, SEEK_SET) != 0) - { - error (_("%s: failed to seek to first archive header\n"), file_name); - return 1; - } - got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file); - if (got != sizeof arch->arhdr) - { - if (got == 0) - return 0; - - error (_("%s: failed to read archive header\n"), file_name); - return 1; - } - - /* See if this is the archive symbol table. */ - if (const_strneq (arch->arhdr.ar_name, "/ ") - || const_strneq (arch->arhdr.ar_name, "/SYM64/ ")) - { - size = strtoul (arch->arhdr.ar_size, NULL, 10); - size = size + (size & 1); - - arch->next_arhdr_offset += sizeof arch->arhdr + size; - - if (read_symbols) - { - unsigned long i; - /* A buffer used to hold numbers read in from an archive index. - These are always 4 bytes long and stored in big-endian format. */ -#define SIZEOF_AR_INDEX_NUMBERS 4 - unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS]; - unsigned char * index_buffer; - - /* Check the size of the archive index. */ - if (size < SIZEOF_AR_INDEX_NUMBERS) - { - error (_("%s: the archive index is empty\n"), file_name); - return 1; - } - - /* Read the numer of entries in the archive index. */ - got = fread (integer_buffer, 1, sizeof integer_buffer, file); - if (got != sizeof (integer_buffer)) - { - error (_("%s: failed to read archive index\n"), file_name); - return 1; - } - arch->index_num = byte_get_big_endian (integer_buffer, sizeof integer_buffer); - size -= SIZEOF_AR_INDEX_NUMBERS; - - /* Read in the archive index. */ - if (size < arch->index_num * SIZEOF_AR_INDEX_NUMBERS) - { - error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"), - file_name, arch->index_num); - return 1; - } - index_buffer = (unsigned char *) - malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS); - if (index_buffer == NULL) - { - error (_("Out of memory whilst trying to read archive symbol index\n")); - return 1; - } - got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, arch->index_num, file); - if (got != arch->index_num) - { - free (index_buffer); - error (_("%s: failed to read archive index\n"), file_name); - return 1; - } - size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS; - - /* Convert the index numbers into the host's numeric format. */ - arch->index_array = (long unsigned int *) - malloc (arch->index_num * sizeof (* arch->index_array)); - if (arch->index_array == NULL) - { - free (index_buffer); - error (_("Out of memory whilst trying to convert the archive symbol index\n")); - return 1; - } - - for (i = 0; i < arch->index_num; i++) - arch->index_array[i] = byte_get_big_endian ((unsigned char *) (index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)), - SIZEOF_AR_INDEX_NUMBERS); - free (index_buffer); - - /* The remaining space in the header is taken up by the symbol table. */ - if (size < 1) - { - error (_("%s: the archive has an index but no symbols\n"), file_name); - return 1; - } - arch->sym_table = (char *) malloc (size); - arch->sym_size = size; - if (arch->sym_table == NULL) - { - error (_("Out of memory whilst trying to read archive index symbol table\n")); - return 1; - } - got = fread (arch->sym_table, 1, size, file); - if (got != size) - { - error (_("%s: failed to read archive index symbol table\n"), file_name); - return 1; - } - } - else - { - if (fseek (file, size, SEEK_CUR) != 0) - { - error (_("%s: failed to skip archive symbol table\n"), file_name); - return 1; - } - } - - /* Read the next archive header. */ - got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file); - if (got != sizeof arch->arhdr) - { - if (got == 0) - return 0; - error (_("%s: failed to read archive header following archive index\n"), file_name); - return 1; - } - } - else if (read_symbols) - printf (_("%s has no archive index\n"), file_name); - - if (const_strneq (arch->arhdr.ar_name, "// ")) - { - /* This is the archive string table holding long member names. */ - arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10); - arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size; - - arch->longnames = (char *) malloc (arch->longnames_size); - if (arch->longnames == NULL) - { - error (_("Out of memory reading long symbol names in archive\n")); - return 1; - } - - if (fread (arch->longnames, arch->longnames_size, 1, file) != 1) - { - free (arch->longnames); - arch->longnames = NULL; - error (_("%s: failed to read long symbol name string table\n"), file_name); - return 1; - } - - if ((arch->longnames_size & 1) != 0) - getc (file); - } - - return 0; -} - -/* Release the memory used for the archive information. */ - -static void -release_archive (struct archive_info * arch) -{ - if (arch->file_name != NULL) - free (arch->file_name); - if (arch->index_array != NULL) - free (arch->index_array); - if (arch->sym_table != NULL) - free (arch->sym_table); - if (arch->longnames != NULL) - free (arch->longnames); -} - -/* Open and setup a nested archive, if not already open. */ - -static int -setup_nested_archive (struct archive_info * nested_arch, char * member_file_name) -{ - FILE * member_file; - - /* Have we already setup this archive? */ - if (nested_arch->file_name != NULL - && streq (nested_arch->file_name, member_file_name)) - return 0; - - /* Close previous file and discard cached information. */ - if (nested_arch->file != NULL) - fclose (nested_arch->file); - release_archive (nested_arch); - - member_file = fopen (member_file_name, "rb"); - if (member_file == NULL) - return 1; - return setup_archive (nested_arch, member_file_name, member_file, FALSE, FALSE); -} - -static char * -get_archive_member_name_at (struct archive_info * arch, - unsigned long offset, - struct archive_info * nested_arch); - -/* Get the name of an archive member from the current archive header. - For simple names, this will modify the ar_name field of the current - archive header. For long names, it will return a pointer to the - longnames table. For nested archives, it will open the nested archive - and get the name recursively. NESTED_ARCH is a single-entry cache so - we don't keep rereading the same information from a nested archive. */ - -static char * -get_archive_member_name (struct archive_info * arch, - struct archive_info * nested_arch) -{ - unsigned long j, k; - - if (arch->arhdr.ar_name[0] == '/') - { - /* We have a long name. */ - char * endp; - char * member_file_name; - char * member_name; - - arch->nested_member_origin = 0; - k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10); - if (arch->is_thin_archive && endp != NULL && * endp == ':') - arch->nested_member_origin = strtoul (endp + 1, NULL, 10); - - while ((j < arch->longnames_size) - && (arch->longnames[j] != '\n') - && (arch->longnames[j] != '\0')) - j++; - if (arch->longnames[j-1] == '/') - j--; - arch->longnames[j] = '\0'; - - if (!arch->is_thin_archive || arch->nested_member_origin == 0) - return arch->longnames + k; - - /* This is a proxy for a member of a nested archive. - Find the name of the member in that archive. */ - member_file_name = adjust_relative_path (arch->file_name, - arch->longnames + k, j - k); - if (member_file_name != NULL - && setup_nested_archive (nested_arch, member_file_name) == 0) - { - member_name = get_archive_member_name_at (nested_arch, - arch->nested_member_origin, - NULL); - if (member_name != NULL) - { - free (member_file_name); - return member_name; - } - } - free (member_file_name); - - /* Last resort: just return the name of the nested archive. */ - return arch->longnames + k; - } - - /* We have a normal (short) name. */ - for (j = 0; j < sizeof (arch->arhdr.ar_name); j++) - if (arch->arhdr.ar_name[j] == '/') - { - arch->arhdr.ar_name[j] = '\0'; - return arch->arhdr.ar_name; - } - - /* The full ar_name field is used. Don't rely on ar_date starting - with a zero byte. */ - { - char *name = xmalloc (sizeof (arch->arhdr.ar_name) + 1); - memcpy (name, arch->arhdr.ar_name, sizeof (arch->arhdr.ar_name)); - name[sizeof (arch->arhdr.ar_name)] = '\0'; - return name; - } -} - -/* Get the name of an archive member at a given OFFSET within an archive ARCH. */ - -static char * -get_archive_member_name_at (struct archive_info * arch, - unsigned long offset, - struct archive_info * nested_arch) -{ - size_t got; - - if (fseek (arch->file, offset, SEEK_SET) != 0) - { - error (_("%s: failed to seek to next file name\n"), arch->file_name); - return NULL; - } - got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file); - if (got != sizeof arch->arhdr) - { - error (_("%s: failed to read archive header\n"), arch->file_name); - return NULL; - } - if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0) - { - error (_("%s: did not find a valid archive header\n"), arch->file_name); - return NULL; - } - - return get_archive_member_name (arch, nested_arch); -} - -/* Construct a string showing the name of the archive member, qualified - with the name of the containing archive file. For thin archives, we - use square brackets to denote the indirection. For nested archives, - we show the qualified name of the external member inside the square - brackets (e.g., "thin.a[normal.a(foo.o)]"). */ - -static char * -make_qualified_name (struct archive_info * arch, - struct archive_info * nested_arch, - char * member_name) -{ - size_t len; - char * name; - - len = strlen (arch->file_name) + strlen (member_name) + 3; - if (arch->is_thin_archive && arch->nested_member_origin != 0) - len += strlen (nested_arch->file_name) + 2; - - name = (char *) malloc (len); - if (name == NULL) - { - error (_("Out of memory\n")); - return NULL; - } - - if (arch->is_thin_archive && arch->nested_member_origin != 0) - snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name); - else if (arch->is_thin_archive) - snprintf (name, len, "%s[%s]", arch->file_name, member_name); - else - snprintf (name, len, "%s(%s)", arch->file_name, member_name); - - return name; -} - /* Process an ELF archive. On entry the file is positioned just after the ARMAG string. */ @@ -13139,6 +12720,13 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive) ret |= process_object (qualified_name, file); } + if (dump_sects != NULL) + { + free (dump_sects); + dump_sects = NULL; + num_dump_sects = 0; + } + free (qualified_name); }