* elfcode.h (elf_slurp_reloc_table_from_section): Make "symcount"
[deliverable/binutils-gdb.git] / bfd / elfcode.h
index f782985a42a481ed95a5c47249ce8e309a291871..4f54cd35ccc6276c867d417e7a87ded5ac696e46 100644 (file)
@@ -559,9 +559,9 @@ elf_object_p (abfd)
      section header table (FIXME: See comments re sections at top of this
      file).  */
 
-  if ((elf_file_p (&x_ehdr) == false) ||
-      (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT) ||
-      (x_ehdr.e_ident[EI_CLASS] != ELFCLASS))
+  if (! elf_file_p (&x_ehdr)
+      || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT
+      || x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
     goto got_wrong_format_error;
 
   /* Check that file's byte order matches xvec's */
@@ -821,7 +821,7 @@ elf_object_p (abfd)
      information.  */
   if (ebd->elf_backend_object_p)
     {
-      if ((*ebd->elf_backend_object_p) (abfd) == false)
+      if (! (*ebd->elf_backend_object_p) (abfd))
        goto got_wrong_format_error;
     }
 
@@ -1133,10 +1133,12 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
   unsigned long symcount;      /* Number of external ELF symbols */
   elf_symbol_type *sym;                /* Pointer to current bfd symbol */
   elf_symbol_type *symbase;    /* Buffer for generated bfd symbols */
-  Elf_Internal_Sym i_sym;
-  Elf_External_Sym *x_symp = NULL;
-  Elf_External_Sym_Shndx *x_shndx = NULL;
-  Elf_External_Versym *x_versymp = NULL;
+  Elf_Internal_Sym *isym;
+  Elf_Internal_Sym *isymend;
+  Elf_Internal_Sym *isymbuf = NULL;
+  Elf_External_Versym *xver;
+  Elf_External_Versym *xverbuf = NULL;
+  struct elf_backend_data *ebd;
   bfd_size_type amt;
 
   /* Read each raw ELF symbol, converting from external ELF form to
@@ -1151,24 +1153,8 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
 
   if (! dynamic)
     {
-      Elf_Internal_Shdr *shndx_hdr;
-
       hdr = &elf_tdata (abfd)->symtab_hdr;
-      shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
       verhdr = NULL;
-
-      /* If we have a SHT_SYMTAB_SHNDX section for the symbol table,
-        read the raw contents.  */
-      if (elf_elfsections (abfd) != NULL
-         && elf_elfsections (abfd)[shndx_hdr->sh_link] == hdr)
-       {
-         amt = shndx_hdr->sh_size;
-         x_shndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
-         if (x_shndx == NULL
-             || bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
-             || bfd_bread ((PTR) x_shndx, amt, abfd) != amt)
-           goto error_return;
-       }
     }
   else
     {
@@ -1187,39 +1173,24 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
        }
     }
 
-  if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
-    goto error_return;
-
+  ebd = get_elf_backend_data (abfd);
   symcount = hdr->sh_size / sizeof (Elf_External_Sym);
-
   if (symcount == 0)
     sym = symbase = NULL;
   else
     {
-      unsigned long i;
-
-      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
-       goto error_return;
+      isymbuf = bfd_elf_get_elf_syms (abfd, hdr, symcount, 0,
+                                     NULL, NULL, NULL);
+      if (isymbuf == NULL)
+       return -1;
 
       amt = symcount;
       amt *= sizeof (elf_symbol_type);
       symbase = (elf_symbol_type *) bfd_zalloc (abfd, amt);
       if (symbase == (elf_symbol_type *) NULL)
        goto error_return;
-      sym = symbase;
-
-      /* Temporarily allocate room for the raw ELF symbols.  */
-      amt = symcount;
-      amt *= sizeof (Elf_External_Sym);
-      x_symp = (Elf_External_Sym *) bfd_malloc (amt);
-      if (x_symp == NULL)
-       goto error_return;
-
-      if (bfd_bread ((PTR) x_symp, amt, abfd) != amt)
-       goto error_return;
 
       /* Read the raw ELF version symbol information.  */
-
       if (verhdr != NULL
          && verhdr->sh_size / sizeof (Elf_External_Versym) != symcount)
        {
@@ -1239,42 +1210,40 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
          if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0)
            goto error_return;
 
-         x_versymp = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
-         if (x_versymp == NULL && verhdr->sh_size != 0)
+         xverbuf = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
+         if (xverbuf == NULL && verhdr->sh_size != 0)
            goto error_return;
 
-         if (bfd_bread ((PTR) x_versymp, verhdr->sh_size, abfd)
+         if (bfd_bread ((PTR) xverbuf, verhdr->sh_size, abfd)
              != verhdr->sh_size)
            goto error_return;
        }
 
       /* Skip first symbol, which is a null dummy.  */
-      for (i = 1; i < symcount; i++)
+      xver = xverbuf;
+      if (xver != NULL)
+       ++xver;
+      isymend = isymbuf + symcount;
+      for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++)
        {
-         elf_swap_symbol_in (abfd, (const PTR) (x_symp + i),
-                             (const PTR) (x_shndx + (x_shndx ? i : 0)),
-                             &i_sym);
-         memcpy (&sym->internal_elf_sym, &i_sym, sizeof (Elf_Internal_Sym));
-#ifdef ELF_KEEP_EXTSYM
-         memcpy (&sym->native_elf_sym, x_symp + i, sizeof (Elf_External_Sym));
-#endif
+         memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
          sym->symbol.the_bfd = abfd;
 
          sym->symbol.name = bfd_elf_string_from_elf_section (abfd,
                                                              hdr->sh_link,
-                                                             i_sym.st_name);
+                                                             isym->st_name);
 
-         sym->symbol.value = i_sym.st_value;
+         sym->symbol.value = isym->st_value;
 
-         if (i_sym.st_shndx == SHN_UNDEF)
+         if (isym->st_shndx == SHN_UNDEF)
            {
              sym->symbol.section = bfd_und_section_ptr;
            }
-         else if (i_sym.st_shndx < SHN_LORESERVE
-                  || i_sym.st_shndx > SHN_HIRESERVE)
+         else if (isym->st_shndx < SHN_LORESERVE
+                  || isym->st_shndx > SHN_HIRESERVE)
            {
              sym->symbol.section = section_from_elf_index (abfd,
-                                                           i_sym.st_shndx);
+                                                           isym->st_shndx);
              if (sym->symbol.section == NULL)
                {
                  /* This symbol is in a section for which we did not
@@ -1283,18 +1252,18 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
                  sym->symbol.section = bfd_abs_section_ptr;
                }
            }
-         else if (i_sym.st_shndx == SHN_ABS)
+         else if (isym->st_shndx == SHN_ABS)
            {
              sym->symbol.section = bfd_abs_section_ptr;
            }
-         else if (i_sym.st_shndx == SHN_COMMON)
+         else if (isym->st_shndx == SHN_COMMON)
            {
              sym->symbol.section = bfd_com_section_ptr;
              /* Elf puts the alignment into the `value' field, and
                 the size into the `size' field.  BFD wants to see the
                 size in the value field, and doesn't care (at the
                 moment) about the alignment.  */
-             sym->symbol.value = i_sym.st_size;
+             sym->symbol.value = isym->st_size;
            }
          else
            sym->symbol.section = bfd_abs_section_ptr;
@@ -1304,14 +1273,13 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
          if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
            sym->symbol.value -= sym->symbol.section->vma;
 
-         switch (ELF_ST_BIND (i_sym.st_info))
+         switch (ELF_ST_BIND (isym->st_info))
            {
            case STB_LOCAL:
              sym->symbol.flags |= BSF_LOCAL;
              break;
            case STB_GLOBAL:
-             if (i_sym.st_shndx != SHN_UNDEF
-                 && i_sym.st_shndx != SHN_COMMON)
+             if (isym->st_shndx != SHN_UNDEF && isym->st_shndx != SHN_COMMON)
                sym->symbol.flags |= BSF_GLOBAL;
              break;
            case STB_WEAK:
@@ -1319,7 +1287,7 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
              break;
            }
 
-         switch (ELF_ST_TYPE (i_sym.st_info))
+         switch (ELF_ST_TYPE (isym->st_info))
            {
            case STT_SECTION:
              sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING;
@@ -1338,31 +1306,24 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
          if (dynamic)
            sym->symbol.flags |= BSF_DYNAMIC;
 
-         if (x_versymp != NULL)
+         if (xver != NULL)
            {
              Elf_Internal_Versym iversym;
 
-             _bfd_elf_swap_versym_in (abfd, x_versymp + i, &iversym);
+             _bfd_elf_swap_versym_in (abfd, xver, &iversym);
              sym->version = iversym.vs_vers;
+             xver++;
            }
 
          /* Do some backend-specific processing on this symbol.  */
-         {
-           struct elf_backend_data *ebd = get_elf_backend_data (abfd);
-           if (ebd->elf_backend_symbol_processing)
-             (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
-         }
-
-         sym++;
+         if (ebd->elf_backend_symbol_processing)
+           (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
        }
     }
 
   /* Do some backend-specific processing on this symbol table.  */
-  {
-    struct elf_backend_data *ebd = get_elf_backend_data (abfd);
-    if (ebd->elf_backend_symbol_table_processing)
-      (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount);
-  }
+  if (ebd->elf_backend_symbol_table_processing)
+    (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount);
 
   /* We rely on the zalloc to clear out the final symbol entry.  */
 
@@ -1382,21 +1343,17 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
       *symptrs = 0;            /* Final null pointer */
     }
 
-  if (x_shndx != NULL)
-    free (x_shndx);
-  if (x_versymp != NULL)
-    free (x_versymp);
-  if (x_symp != NULL)
-    free (x_symp);
+  if (xverbuf != NULL)
+    free (xverbuf);
+  if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
+    free (isymbuf);
   return symcount;
 
 error_return:
-  if (x_shndx != NULL)
-    free (x_shndx);
-  if (x_versymp != NULL)
-    free (x_versymp);
-  if (x_symp != NULL)
-    free (x_symp);
+  if (xverbuf != NULL)
+    free (xverbuf);
+  if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
+    free (isymbuf);
   return -1;
 }
 
@@ -1420,6 +1377,7 @@ elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count,
   arelent *relent;
   unsigned int i;
   int entsize;
+  unsigned int symcount;
 
   allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
   if (allocated == NULL)
@@ -1436,6 +1394,11 @@ elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count,
   BFD_ASSERT (entsize == sizeof (Elf_External_Rel)
              || entsize == sizeof (Elf_External_Rela));
 
+  if (dynamic)
+    symcount = bfd_get_dynamic_symcount (abfd);
+  else
+    symcount = bfd_get_symcount (abfd);
+
   for (i = 0, relent = relents;
        i < reloc_count;
        i++, relent++, native_relocs += entsize)
@@ -1464,6 +1427,13 @@ elf_slurp_reloc_table_from_section (abfd, asect, rel_hdr, reloc_count,
 
       if (ELF_R_SYM (rela.r_info) == 0)
        relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+      else if (ELF_R_SYM (rela.r_info) > symcount)
+       {
+         (*_bfd_error_handler)
+           (_("%s(%s): relocation %d has invalid symbol index %ld"),
+            abfd->filename, asect->name, i, ELF_R_SYM (rela.r_info));
+         relent->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;
+       }
       else
        {
          asymbol **ps, *s;
This page took 0.029875 seconds and 4 git commands to generate.