* dwarf.c: #include "bfd_stdint.h".
[deliverable/binutils-gdb.git] / binutils / readelf.c
index 757fefbdd4d6bdd4b9d50e5911a7c7b0b60b39fa..b8ab55b989b2778e11526f2556d0a7b88e3cf9f0 100644 (file)
@@ -61,6 +61,7 @@
 
 #include "bfd.h"
 #include "bucomm.h"
+#include "elfcomm.h"
 #include "dwarf.h"
 
 #include "elf/common.h"
 #include "elf/mmix.h"
 #include "elf/mn10200.h"
 #include "elf/mn10300.h"
+#include "elf/moxie.h"
 #include "elf/mt.h"
 #include "elf/msp430.h"
 #include "elf/or32.h"
 #include "elf/xstormy16.h"
 #include "elf/xtensa.h"
 
-#include "aout/ar.h"
-
 #include "getopt.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
@@ -259,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)                                                \
@@ -271,8 +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 GET_ELF_SYMBOLS(file, section)                 \
   (is_32bit_elf ? get_32bit_elf_symbols (file, section)        \
    : get_64bit_elf_symbols (file, section))
@@ -282,11 +278,6 @@ 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;                            \
@@ -338,36 +329,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
@@ -501,41 +462,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 *
@@ -646,6 +572,7 @@ guess_is_rela (unsigned int e_machine)
     case EM_CYGNUS_MN10200:
     case EM_MN10300:
     case EM_CYGNUS_MN10300:
+    case EM_MOXIE:
     case EM_MSP430:
     case EM_MSP430_OLD:
     case EM_MT:
@@ -732,7 +659,7 @@ slurp_rela_relocs (FILE * file,
        {
          relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
          relas[i].r_info   = BYTE_GET (erelas[i].r_info);
-         relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
+         relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
        }
 
       free (erelas);
@@ -762,7 +689,7 @@ slurp_rela_relocs (FILE * file,
        {
          relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
          relas[i].r_info   = BYTE_GET (erelas[i].r_info);
-         relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
+         relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
 
          /* The #ifdef BFD64 below is to prevent a compile time
             warning.  We know that if we do not have a 64 bit data
@@ -1130,6 +1057,10 @@ dump_relocations (FILE * file,
          rtype = elf_mmix_reloc_type (type);
          break;
 
+       case EM_MOXIE:
+         rtype = elf_moxie_reloc_type (type);
+         break;
+
        case EM_MSP430:
        case EM_MSP430_OLD:
          rtype = elf_msp430_reloc_type (type);
@@ -1260,7 +1191,7 @@ dump_relocations (FILE * file,
        case EM_CR16_OLD:
          rtype = elf_cr16_reloc_type (type);
          break;
-       
+
        case EM_MICROBLAZE:
        case EM_MICROBLAZE_OLD:
          rtype = elf_microblaze_reloc_type (type);
@@ -1404,12 +1335,12 @@ dump_relocations (FILE * file,
 
              if (is_rela)
                {
-                 long off = (long) (bfd_signed_vma) rels[i].r_addend;
+                 bfd_signed_vma off = rels[i].r_addend;
 
                  if (off < 0)
-                   printf (" - %lx", - off);
+                   printf (" - %" BFD_VMA_FMT "x", - off);
                  else
-                   printf (" + %lx", off);
+                   printf (" + %" BFD_VMA_FMT "x", off);
                }
            }
        }
@@ -1906,6 +1837,7 @@ get_machine_name (unsigned e_machine)
     case EM_MN10300:           return "mn10300";
     case EM_CYGNUS_MN10200:
     case EM_MN10200:           return "mn10200";
+    case EM_MOXIE:             return "Moxie";
     case EM_CYGNUS_FR30:
     case EM_FR30:              return "Fujitsu FR30";
     case EM_CYGNUS_FRV:                return "Fujitsu FR-V";
@@ -2230,6 +2162,21 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
          decode_ARM_machine_flags (e_flags, buf);
          break;
 
+       case EM_BLACKFIN:
+         if (e_flags & EF_BFIN_PIC)
+           strcat (buf, ", PIC");
+
+         if (e_flags & EF_BFIN_FDPIC)
+           strcat (buf, ", FDPIC");
+
+         if (e_flags & EF_BFIN_CODE_IN_L1)
+           strcat (buf, ", code in L1");
+
+         if (e_flags & EF_BFIN_DATA_IN_L1)
+           strcat (buf, ", data in L1");
+
+         break;
+
        case EM_CYGNUS_FRV:
          switch (e_flags & EF_FRV_CPU_MASK)
            {
@@ -2303,6 +2250,13 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
                case EF_M68K_CF_ISA_B:
                  isa = "B";
                  break;
+               case EF_M68K_CF_ISA_C:
+                 isa = "C";
+                 break;
+               case EF_M68K_CF_ISA_C_NODIV:
+                 isa = "C";
+                 additional = ", nodiv";
+                 break;
                }
              strcat (buf, ", cf, isa ");
              strcat (buf, isa);
@@ -2321,6 +2275,9 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
                case EF_M68K_CF_EMAC:
                  mac = "emac";
                  break;
+               case EF_M68K_CF_EMAC_B:
+                 mac = "emac_b";
+                 break;
                }
              if (mac)
                {
@@ -2345,8 +2302,14 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
        case EM_CYGNUS_V850:
          switch (e_flags & EF_V850_ARCH)
            {
-           case E_V850E1_ARCH:
-             strcat (buf, ", v850e1");
+           case E_V850E2V3_ARCH:
+             strcat (buf, ", v850e2v3");
+             break;
+           case E_V850E2_ARCH:
+             strcat (buf, ", v850e2");
+             break;
+            case E_V850E1_ARCH:
+              strcat (buf, ", v850e1");
              break;
            case E_V850E_ARCH:
              strcat (buf, ", v850e");
@@ -2403,6 +2366,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
            case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
            case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
            case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
+           case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
            case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
            case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
            case E_MIPS_MACH_XLR:  strcat (buf, ", xlr"); break;
@@ -2598,7 +2562,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
          if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
            strcat (buf, ", 64-bit doubles");
          if (e_flags & E_FLAG_RX_DSP)
-           strcat (buf, ", dsp");        
+           strcat (buf, ", dsp");
 
        case EM_S390:
          if (e_flags & EF_S390_HIGH_GPRS)
@@ -3177,7 +3141,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, _("\
@@ -3524,7 +3488,7 @@ process_file_header (void)
       if (section_headers != NULL
          && elf_header.e_phnum == PN_XNUM
          && section_headers[0].sh_info != 0)
-       printf (_(" (%ld)"), (long) section_headers[0].sh_info);
+       printf (" (%ld)", (long) section_headers[0].sh_info);
       putc ('\n', stdout);
       printf (_("  Size of section headers:           %ld (bytes)\n"),
              (long) elf_header.e_shentsize);
@@ -3889,8 +3853,8 @@ process_program_headers (FILE * file)
 
          for (j = 1; j < elf_header.e_shnum; j++, section++)
            {
-             if (ELF_SECTION_SIZE (section, segment) != 0
-                 && ELF_SECTION_IN_SEGMENT (section, segment))
+             if (!ELF_TBSS_SPECIAL (section, segment)
+                 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
                printf ("%s ", SECTION_NAME (section));
            }
 
@@ -4023,15 +3987,30 @@ static Elf_Internal_Sym *
 get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
 {
   unsigned long number;
-  Elf32_External_Sym * esyms;
+  Elf32_External_Sym * esyms = NULL;
   Elf_External_Sym_Shndx * shndx;
-  Elf_Internal_Sym * isyms;
+  Elf_Internal_Sym * isyms = NULL;
   Elf_Internal_Sym * psym;
   unsigned int j;
 
+  /* Run some sanity checks first.  */
+  if (section->sh_entsize == 0)
+    {
+      error (_("sh_entsize is zero\n"));
+      return NULL;
+    }
+
+  number = section->sh_size / section->sh_entsize;
+
+  if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
+    {
+      error (_("Invalid sh_entsize\n"));
+      return NULL;
+    }
+
   esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
                                            section->sh_size, _("symbols"));
-  if (!esyms)
+  if (esyms == NULL)
     return NULL;
 
   shndx = NULL;
@@ -4043,28 +4022,19 @@ get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
                                                    symtab_shndx_hdr->sh_offset,
                                                    1, symtab_shndx_hdr->sh_size,
                                                    _("symtab shndx"));
-      if (!shndx)
-       {
-         free (esyms);
-         return NULL;
-       }
+      if (shndx == NULL)
+       goto exit_point;
     }
 
-  number = section->sh_size / section->sh_entsize;
   isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
 
   if (isyms == NULL)
     {
       error (_("Out of memory\n"));
-      if (shndx)
-       free (shndx);
-      free (esyms);
-      return NULL;
+      goto exit_point;
     }
 
-  for (j = 0, psym = isyms;
-       j < number;
-       j++, psym++)
+  for (j = 0, psym = isyms; j < number; j++, psym++)
     {
       psym->st_name  = BYTE_GET (esyms[j].st_name);
       psym->st_value = BYTE_GET (esyms[j].st_value);
@@ -4079,9 +4049,11 @@ get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
       psym->st_other = BYTE_GET (esyms[j].st_other);
     }
 
+ exit_point:
   if (shndx)
     free (shndx);
-  free (esyms);
+  if (esyms)
+    free (esyms);
 
   return isyms;
 }
@@ -4096,6 +4068,21 @@ get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
   Elf_Internal_Sym * psym;
   unsigned int j;
 
+  /* Run some sanity checks first.  */
+  if (section->sh_entsize == 0)
+    {
+      error (_("sh_entsize is zero\n"));
+      return NULL;
+    }
+
+  number = section->sh_size / section->sh_entsize;
+
+  if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
+    {
+      error (_("Invalid sh_entsize\n"));
+      return NULL;
+    }
+
   esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
                                            section->sh_size, _("symbols"));
   if (!esyms)
@@ -4117,7 +4104,6 @@ get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
        }
     }
 
-  number = section->sh_size / section->sh_entsize;
   isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
 
   if (isyms == NULL)
@@ -4578,6 +4564,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)
@@ -4816,10 +4804,19 @@ process_section_headers (FILE * file)
     }
 
   if (!do_section_details)
-    printf (_("Key to Flags:\n\
+    {
+      if (elf_header.e_machine == EM_X86_64
+         || elf_header.e_machine == EM_L1OM)
+       printf (_("Key to Flags:\n\
+  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
+  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
+  O (extra OS processing required) o (OS specific), p (processor specific)\n"));
+      else
+       printf (_("Key to Flags:\n\
   W (write), A (alloc), X (execute), M (merge), S (strings)\n\
-  I (info), L (link order), G (group), x (unknown)\n\
+  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
   O (extra OS processing required) o (OS specific), p (processor specific)\n"));
+    }  
 
   return 1;
 }
@@ -4942,6 +4939,12 @@ process_section_groups (FILE * file)
              symtab = GET_ELF_SYMBOLS (file, symtab_sec);
            }
 
+         if (symtab == NULL)
+           {
+             error (_("Corrupt header in group section `%s'\n"), name);
+             continue;
+           }
+
          sym = symtab + section->sh_info;
 
          if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
@@ -5112,7 +5115,7 @@ dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
   else
     {
       warn ("corrupt library name index of 0x%lx found in dynamic entry",
-            fixup->needed);
+            (unsigned long) fixup->needed);
       lib_name = "???";
     }
   printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
@@ -6365,7 +6368,7 @@ decode_arm_unwind (struct arm_unw_aux_info *aux,
       printf (_("[Truncated opcode]\n"));      \
       return;                          \
     }                                  \
-  printf (_("0x%02x "), OP)
+  printf ("0x%02x ", OP)
 
   if (remaining == 0)
     {
@@ -6417,7 +6420,6 @@ decode_arm_unwind (struct arm_unw_aux_info *aux,
     }
   else
     {
-      
       per_index = (word >> 24) & 0x7f;
       if (per_index != 0 && per_index != 1 && per_index != 2)
        {
@@ -6452,17 +6454,17 @@ decode_arm_unwind (struct arm_unw_aux_info *aux,
       op = word >> 24;
       word <<= 8;
 
-      printf (_("  0x%02x "), op);
+      printf ("  0x%02x ", op);
 
       if ((op & 0xc0) == 0x00)
        {
          int offset = ((op & 0x3f) << 2) + 4;
-         printf (_("     vsp = vsp + %d"), offset);
+         printf ("     vsp = vsp + %d", offset);
        }
       else if ((op & 0xc0) == 0x40)
        {
          int offset = ((op & 0x3f) << 2) + 4;
-         printf (_("     vsp = vsp - %d"), offset);
+         printf ("     vsp = vsp - %d", offset);
        }
       else if ((op & 0xf0) == 0x80)
        {
@@ -6493,7 +6495,7 @@ decode_arm_unwind (struct arm_unw_aux_info *aux,
          if (op == 0x9d || op == 0x9f)
            printf (_("     [Reserved]"));
          else
-           printf (_("     vsp = r%d"), op & 0x0f);
+           printf ("     vsp = r%d", op & 0x0f);
        }
       else if ((op & 0xf0) == 0xa0)
        {
@@ -6557,7 +6559,7 @@ decode_arm_unwind (struct arm_unw_aux_info *aux,
          offset = read_uleb128 (buf, &len);
          assert (len == i + 1);
          offset = offset * 4 + 0x204;
-         printf (_("vsp = vsp + %ld"), offset);
+         printf ("vsp = vsp + %ld", offset);
        }
       else
        {
@@ -7750,6 +7752,10 @@ process_version_sections (FILE * file)
                int j;
                int isum;
 
+               /* Check for negative or very large indicies.  */
+               if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
+                 break;
+
                vstart = ((char *) edefs) + idx;
                if (vstart + sizeof (*edef) > endbuf)
                  break;
@@ -7770,6 +7776,11 @@ process_version_sections (FILE * file)
                printf (_("  Index: %d  Cnt: %d  "),
                        ent.vd_ndx, ent.vd_cnt);
 
+               /* Check for overflow.  */
+               if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
+                   || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
+                 break;
+
                vstart += ent.vd_aux;
 
                eaux = (Elf_External_Verdaux *) vstart;
@@ -7786,6 +7797,11 @@ process_version_sections (FILE * file)
 
                for (j = 1; j < ent.vd_cnt; j++)
                  {
+                   /* Check for overflow.  */
+                   if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
+                       || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
+                     break;
+
                    isum   += aux.vda_next;
                    vstart += aux.vda_next;
 
@@ -7803,11 +7819,13 @@ process_version_sections (FILE * file)
                      printf (_("  %#06x: Parent %d, name index: %ld\n"),
                              isum, j, aux.vda_name);
                  }
+
                if (j < ent.vd_cnt)
                  printf (_("  Version def aux past end of section\n"));
 
                idx += ent.vd_next;
              }
+
            if (cnt < section->sh_info)
              printf (_("  Version definition past end of section\n"));
 
@@ -7851,6 +7869,9 @@ process_version_sections (FILE * file)
                int isum;
                char * vstart;
 
+               if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
+                 break;
+
                vstart = ((char *) eneed) + idx;
                if (vstart + sizeof (*entry) > endbuf)
                  break;
@@ -7872,6 +7893,11 @@ process_version_sections (FILE * file)
 
                printf (_("  Cnt: %d\n"), ent.vn_cnt);
 
+               /* Check for overflow.  */
+               if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
+                   || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
+                 break;
+
                vstart += ent.vn_aux;
 
                for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
@@ -7899,6 +7925,11 @@ process_version_sections (FILE * file)
                    printf (_("  Flags: %s  Version: %d\n"),
                            get_ver_flags (aux.vna_flags), aux.vna_other);
 
+                   /* Check for overflow.  */
+                   if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
+                       || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
+                     break;
+
                    isum   += aux.vna_next;
                    vstart += aux.vna_next;
                  }
@@ -7938,6 +7969,8 @@ process_version_sections (FILE * file)
            found = 1;
 
            symbols = GET_ELF_SYMBOLS (file, link_section);
+           if (symbols == NULL)
+             break;
 
            string_sec = section_headers + link_section->sh_link;
 
@@ -7999,6 +8032,16 @@ process_version_sections (FILE * file)
                      nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
                                   data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
 
+                     /* If this index value is greater than the size of the symbols
+                        array, break to avoid an out-of-bounds read,  */
+                     if ((unsigned long)(cnt + j) >=
+                        ((unsigned long)link_section->sh_size /
+                         (unsigned long)link_section->sh_entsize))
+                       {
+                         warn (_("invalid index into symbol array\n"));
+                         break;
+                       }
+
                      check_def = 1;
                      check_need = 1;
                      if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
@@ -8706,9 +8749,17 @@ process_symbol_table (FILE * file)
                  && section->sh_type == SHT_SYMTAB))
            continue;
 
+         if (section->sh_entsize == 0)
+           {
+             printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
+                     SECTION_NAME (section));
+             continue;
+           }
+
          printf (_("\nSymbol table '%s' contains %lu entries:\n"),
                  SECTION_NAME (section),
                  (unsigned long) (section->sh_size / section->sh_entsize));
+
          if (is_32bit_elf)
            printf (_("   Num:    Value  Size Type    Bind   Vis      Ndx Name\n"));
          else
@@ -9177,8 +9228,10 @@ is_32bit_abs_reloc (unsigned int reloc_type)
       return reloc_type == 1; /* R_68K_32.  */
     case EM_860:
       return reloc_type == 1; /* R_860_32.  */
+    case EM_960:
+      return reloc_type == 2; /* R_960_32.  */
     case EM_ALPHA:
-      return reloc_type == 1; /* XXX Is this right ?  */
+      return reloc_type == 1; /* R_ALPHA_REFLONG.  */
     case EM_ARC:
       return reloc_type == 1; /* R_ARC_32.  */
     case EM_ARM:
@@ -9230,6 +9283,8 @@ is_32bit_abs_reloc (unsigned int reloc_type)
       return reloc_type == 1; /* R_MCORE_ADDR32.  */
     case EM_CYGNUS_MEP:
       return reloc_type == 4; /* R_MEP_32.  */
+    case EM_MICROBLAZE:
+      return reloc_type == 1; /* R_MICROBLAZE_32.  */
     case EM_MIPS:
       return reloc_type == 2; /* R_MIPS_32.  */
     case EM_MMIX:
@@ -9240,6 +9295,8 @@ is_32bit_abs_reloc (unsigned int reloc_type)
     case EM_CYGNUS_MN10300:
     case EM_MN10300:
       return reloc_type == 1; /* R_MN10300_32.  */
+    case EM_MOXIE:
+      return reloc_type == 1; /* R_MOXIE_32.  */
     case EM_MSP430_OLD:
     case EM_MSP430:
       return reloc_type == 1; /* R_MSP43_32.  */
@@ -9321,6 +9378,8 @@ is_32bit_pcrel_reloc (unsigned int reloc_type)
       return reloc_type == 10; /* R_ALPHA_SREL32.  */
     case EM_ARM:
       return reloc_type == 3;  /* R_ARM_REL32 */
+    case EM_MICROBLAZE:
+      return reloc_type == 2;  /* R_MICROBLAZE_32_PCREL.  */
     case EM_PARISC:
       return reloc_type == 9;  /* R_PARISC_PCREL32.  */
     case EM_PPC:
@@ -9501,6 +9560,7 @@ is_none_reloc (unsigned int reloc_type)
     case EM_X86_64:  /* R_X86_64_NONE.  */
     case EM_L1OM:    /* R_X86_64_NONE.  */
     case EM_MN10300: /* R_MN10300_NONE.  */
+    case EM_MOXIE:   /* R_MOXIE_NONE.  */
     case EM_M32R:    /* R_M32R_NONE.  */
     case EM_TI_C6000:/* R_C6000_NONE.  */
     case EM_XC16X:
@@ -9641,13 +9701,17 @@ apply_relocations (void * file,
          addend = 0;
          if (is_rela)
            addend += rp->r_addend;
-         /* R_XTENSA_32 and R_PJ_DATA_DIR32 are partial_inplace.  */
+         /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
+            partial_inplace.  */
          if (!is_rela
              || (elf_header.e_machine == EM_XTENSA
                  && reloc_type == 1)
              || ((elf_header.e_machine == EM_PJ
                   || elf_header.e_machine == EM_PJ_OLD)
-                 && reloc_type == 1))
+                 && reloc_type == 1)
+             || ((elf_header.e_machine == EM_D30V
+                  || elf_header.e_machine == EM_CYGNUS_D30V)
+                 && reloc_type == 12))
            addend += byte_get (rloc, reloc_size);
 
          if (is_32bit_pcrel_reloc (reloc_type)
@@ -9703,7 +9767,7 @@ get_section_contents (Elf_Internal_Shdr * section, FILE * file)
                              _("section contents"));
 }
 
-                     
+
 static void
 dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
 {
@@ -9865,16 +9929,13 @@ dump_section_as_bytes (Elf_Internal_Shdr * section,
   putchar ('\n');
 }
 
-/* Uncompresses a section that was compressed using zlib, in place.
-   This is a copy of bfd_uncompress_section_contents, in bfd/compress.c  */
+/* Uncompresses a section that was compressed using zlib, in place.  */
 
 static int
-uncompress_section_contents (unsigned char ** buffer, dwarf_size_type * size)
+uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
+                            dwarf_size_type *size ATTRIBUTE_UNUSED)
 {
 #ifndef HAVE_ZLIB_H
-  /* These are just to quiet gcc.  */
-  buffer = 0;
-  size = 0;
   return FALSE;
 #else
   dwarf_size_type compressed_size = *size;
@@ -9934,6 +9995,8 @@ uncompress_section_contents (unsigned char ** buffer, dwarf_size_type * size)
 
  fail:
   free (uncompressed_buffer);
+  /* Indicate decompression failure.  */
+  *buffer = NULL;
   return 0;
 #endif  /* HAVE_ZLIB_H */
 }
@@ -9944,27 +10007,23 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
 {
   struct dwarf_section * section = &debug_displays [debug].section;
   char buf [64];
-  int section_is_compressed;
 
   /* If it is already loaded, do nothing.  */
   if (section->start != NULL)
     return 1;
 
-  section_is_compressed = section->name == section->compressed_name;
-
   snprintf (buf, sizeof (buf), _("%s section data"), section->name);
   section->address = sec->sh_addr;
   section->size = sec->sh_size;
   section->start = (unsigned char *) get_data (NULL, (FILE *) file,
                                                sec->sh_offset, 1,
                                                sec->sh_size, buf);
+  if (uncompress_section_contents (&section->start, &section->size))
+    sec->sh_size = section->size;
+
   if (section->start == NULL)
     return 0;
 
-  if (section_is_compressed)
-    if (! uncompress_section_contents (&section->start, &section->size))
-      return 0;
-
   if (debug_displays [debug].relocate)
     apply_relocations ((FILE *) file, sec, section->start);
 
@@ -10175,7 +10234,7 @@ static const char * arm_attr_tag_THUMB_ISA_use[] =
 static const char * arm_attr_tag_FP_arch[] =
   {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
 static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
-static const char * arm_attr_tag_Advanced_SIMD_arch[] = 
+static const char * arm_attr_tag_Advanced_SIMD_arch[] =
   {"No", "NEONv1", "NEONv1 with Fused-MAC"};
 static const char * arm_attr_tag_PCS_config[] =
   {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
@@ -10216,16 +10275,16 @@ static const char * arm_attr_tag_FP_HP_extension[] =
   {"Not Allowed", "Allowed"};
 static const char * arm_attr_tag_ABI_FP_16bit_format[] =
   {"None", "IEEE 754", "Alternative Format"};
-static const char * arm_attr_tag_MPextension_use[] = 
+static const char * arm_attr_tag_MPextension_use[] =
   {"Not Allowed", "Allowed"};
 static const char * arm_attr_tag_DIV_use[] =
-  {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed", 
+  {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
     "Allowed in v7-A with integer division extension"};
 static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
 static const char * arm_attr_tag_Virtualization_use[] =
-  {"Not Allowed", "TrustZone", "Virtualization Extensions", 
+  {"Not Allowed", "TrustZone", "Virtualization Extensions",
     "TrustZone and Virtualization Extensions"};
-static const char * arm_attr_tag_MPextension_use_legacy[] = 
+static const char * arm_attr_tag_MPextension_use_legacy[] =
   {"Not Allowed", "Allowed"};
 
 #define LOOKUP(id, name) \
@@ -10330,7 +10389,7 @@ display_arm_attribute (unsigned char * p)
                case 3: printf ("??? 3\n"); break;
                default:
                  if (val <= 12)
-                   printf (_("8-byte and up to %d-byte extended\n"), 
+                   printf (_("8-byte and up to %d-byte extended\n"),
                            1 << val);
                  else
                    printf ("??? (%d)\n", val);
@@ -10349,7 +10408,7 @@ display_arm_attribute (unsigned char * p)
                case 3: printf ("??? 3\n"); break;
                default:
                  if (val <= 12)
-                   printf (_("8-byte and up to %d-byte extended\n"), 
+                   printf (_("8-byte and up to %d-byte extended\n"),
                            1 << val);
                  else
                    printf ("??? (%d)\n", val);
@@ -10611,7 +10670,7 @@ display_mips_gnu_attribute (unsigned char * p, int tag)
          printf (_("Soft float\n"));
          break;
        case 4:
-         printf (_("64-bit float (-mips32r2 -mfp64)\n"));
+         printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
          break;
        default:
          printf ("??? (%d)\n", val);
@@ -10641,6 +10700,240 @@ display_mips_gnu_attribute (unsigned char * p, int tag)
   return p;
 }
 
+static unsigned char *
+display_tic6x_attribute (unsigned char * p)
+{
+  int tag;
+  unsigned int len;
+  int val;
+
+  tag = read_uleb128 (p, &len);
+  p += len;
+
+  switch (tag)
+    {
+    case Tag_ISA:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ISA: ");
+
+      switch (val)
+       {
+       case C6XABI_Tag_ISA_none:
+         printf (_("None\n"));
+         break;
+       case C6XABI_Tag_ISA_C62X:
+         printf ("C62x\n");
+         break;
+       case C6XABI_Tag_ISA_C67X:
+         printf ("C67x\n");
+         break;
+       case C6XABI_Tag_ISA_C67XP:
+         printf ("C67x+\n");
+         break;
+       case C6XABI_Tag_ISA_C64X:
+         printf ("C64x\n");
+         break;
+       case C6XABI_Tag_ISA_C64XP:
+         printf ("C64x+\n");
+         break;
+       case C6XABI_Tag_ISA_C674X:
+         printf ("C674x\n");
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_wchar_t:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_wchar_t: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("Not used\n"));
+         break;
+       case 1:
+         printf (_("2 bytes\n"));
+         break;
+       case 2:
+         printf (_("4 bytes\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_stack_align_needed:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_stack_align_needed: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("8-byte\n"));
+         break;
+       case 1:
+         printf (_("16-byte\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_stack_align_preserved:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_stack_align_preserved: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("8-byte\n"));
+         break;
+       case 1:
+         printf (_("16-byte\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_DSBT:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_DSBT: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("DSBT addressing not used\n"));
+         break;
+       case 1:
+         printf (_("DSBT addressing used\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_PID:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_PID: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("Data addressing position-dependent\n"));
+         break;
+       case 1:
+         printf (_("Data addressing position-independent, GOT near DP\n"));
+         break;
+       case 2:
+         printf (_("Data addressing position-independent, GOT far from DP\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_PIC:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_PIC: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("Code addressing position-dependent\n"));
+         break;
+       case 1:
+         printf (_("Code addressing position-independent\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_array_object_alignment:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_array_object_alignment: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("8-byte\n"));
+         break;
+       case 1:
+         printf (_("4-byte\n"));
+         break;
+       case 2:
+         printf (_("16-byte\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_array_object_align_expected:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_array_object_align_expected: ");
+      switch (val)
+       {
+       case 0:
+         printf (_("8-byte\n"));
+         break;
+       case 1:
+         printf (_("4-byte\n"));
+         break;
+       case 2:
+         printf (_("16-byte\n"));
+         break;
+       default:
+         printf ("??? (%d)\n", val);
+         break;
+       }
+      return p;
+
+    case Tag_ABI_compatibility:
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("  Tag_ABI_compatibility: ");
+      printf (_("flag = %d, vendor = %s\n"), val, p);
+      p += strlen ((char *) p) + 1;
+      return p;
+
+    case Tag_ABI_conformance:
+      printf ("  Tag_ABI_conformance: ");
+      printf ("\"%s\"\n", p);
+      p += strlen ((char *) p) + 1;
+      return p;
+    }
+
+  printf ("  Tag_unknown_%d: ", tag);
+
+  if (tag & 1)
+    {
+      printf ("\"%s\"\n", p);
+      p += strlen ((char *) p) + 1;
+    }
+  else
+    {
+      val = read_uleb128 (p, &len);
+      p += len;
+      printf ("%d (0x%x)\n", val, val);
+    }
+
+  return p;
+}
+
 static int
 process_attributes (FILE * file,
                    const char * public_name,
@@ -10797,6 +11090,13 @@ process_power_specific (FILE * file)
                             display_power_gnu_attribute);
 }
 
+static int
+process_tic6x_specific (FILE * file)
+{
+  return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
+                            display_tic6x_attribute, NULL);
+}
+
 /* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
    Print the Address, Access and Initial fields of an entry at VMA ADDR
    and return the VMA of the next entry.  */
@@ -11310,7 +11610,7 @@ process_mips_specific (FILE * file)
       if (ent < local_end)
        {
          printf (_(" Local entries:\n"));
-         printf (_("  %*s %10s %*s\n"),
+         printf ("  %*s %10s %*s\n",
                  addr_size * 2, _("Address"), _("Access"),
                  addr_size * 2, _("Initial"));
          while (ent < local_end)
@@ -11326,7 +11626,7 @@ process_mips_specific (FILE * file)
          int sym_width;
 
          printf (_(" Global entries:\n"));
-         printf (_("  %*s %10s %*s %*s %-7s %3s %s\n"),
+         printf ("  %*s %10s %*s %*s %-7s %3s %s\n",
                  addr_size * 2, _("Address"), _("Access"),
                  addr_size * 2, _("Initial"),
                  addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
@@ -11394,7 +11694,7 @@ process_mips_specific (FILE * file)
       printf ("\n");
 
       printf (_(" Entries:\n"));
-      printf (_("  %*s %*s %*s %-7s %3s %s\n"),
+      printf ("  %*s %*s %*s %-7s %3s %s\n",
              addr_size * 2, _("Address"),
              addr_size * 2, _("Initial"),
              addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
@@ -11720,7 +12020,7 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
 
   pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
                                            _("notes"));
-  if (!pnotes)
+  if (pnotes == NULL)
     return 0;
 
   external = pnotes;
@@ -11744,7 +12044,8 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
 
       next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
 
-      if (((char *) next) > (((char *) pnotes) + length))
+      if (   ((char *) next > ((char *) pnotes) + length)
+         || ((char *) next <  (char *) pnotes))
        {
          warn (_("corrupt note found at offset %lx into core notes\n"),
                (unsigned long) ((char *) external - (char *) pnotes));
@@ -11755,6 +12056,17 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
 
       external = next;
 
+      /* Prevent out-of-bounds indexing.  */
+      if (inote.namedata + inote.namesz >= (char *) pnotes + length
+         || inote.namedata + inote.namesz < inote.namedata)
+        {
+          warn (_("corrupt note found at offset %lx into core notes\n"),
+                (unsigned long) ((char *) external - (char *) pnotes));
+          warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
+                inote.type, inote.namesz, inote.descsz);
+          break;
+        }
+
       /* Verify that name is null terminated.  It appears that at least
         one version of Linux (RedHat 6.0) generates corefiles that don't
         comply with the ELF spec by failing to include the null byte in
@@ -11867,6 +12179,9 @@ process_arch_specific (FILE * file)
     case EM_PPC:
       return process_power_specific (file);
       break;
+    case EM_TI_C6000:
+      return process_tic6x_specific (file);
+      break;
     default:
       break;
     }
@@ -12118,416 +12433,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)) != 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.  */
-  j = 0;
-  while ((arch->arhdr.ar_name[j] != '/') && (j < 16))
-    j++;
-  arch->arhdr.ar_name[j] = '\0';
-  return arch->arhdr.ar_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.  */
 
This page took 0.045376 seconds and 4 git commands to generate.