gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elfxx-mips.c
index 3462c8b1511c670e1c5ecc8e0924ce3b4c705770..e563d56dbbedf96d38f0f388bef8a5b894c804d1 100644 (file)
@@ -1,5 +1,5 @@
 /* MIPS-specific support for ELF
-   Copyright (C) 1993-2019 Free Software Foundation, Inc.
+   Copyright (C) 1993-2020 Free Software Foundation, Inc.
 
    Most of the information added by Ian Lance Taylor, Cygnus Support,
    <ian@cygnus.com>.
@@ -1374,7 +1374,7 @@ _bfd_mips_elf_new_section_hook (bfd *abfd, asection *sec)
   if (!sec->used_by_bfd)
     {
       struct _mips_elf_section_data *sdata;
-      bfd_size_type amt = sizeof (*sdata);
+      size_t amt = sizeof (*sdata);
 
       sdata = bfd_zalloc (abfd, amt);
       if (sdata == NULL)
@@ -1413,18 +1413,23 @@ _bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section,
   /* The symbolic header contains absolute file offsets and sizes to
      read.  */
 #define READ(ptr, offset, count, size, type)                           \
-  if (symhdr->count == 0)                                              \
-    debug->ptr = NULL;                                                 \
-  else                                                                 \
+  do                                                                   \
     {                                                                  \
-      bfd_size_type amt = (bfd_size_type) size * symhdr->count;                \
-      debug->ptr = bfd_malloc (amt);                                   \
-      if (debug->ptr == NULL)                                          \
+      size_t amt;                                                      \
+      debug->ptr = NULL;                                               \
+      if (symhdr->count == 0)                                          \
+       break;                                                          \
+      if (_bfd_mul_overflow (size, symhdr->count, &amt))               \
+       {                                                               \
+         bfd_set_error (bfd_error_file_too_big);                       \
+         goto error_return;                                            \
+       }                                                               \
+      if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0)              \
        goto error_return;                                              \
-      if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0               \
-         || bfd_bread (debug->ptr, amt, abfd) != amt)                  \
+      debug->ptr = (type) _bfd_malloc_and_read (abfd, amt, amt);       \
+      if (debug->ptr == NULL)                                          \
        goto error_return;                                              \
-    }
+    } while (0)
 
   READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
   READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *);
@@ -1445,30 +1450,18 @@ _bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section,
   return TRUE;
 
  error_return:
-  if (ext_hdr != NULL)
-    free (ext_hdr);
-  if (debug->line != NULL)
-    free (debug->line);
-  if (debug->external_dnr != NULL)
-    free (debug->external_dnr);
-  if (debug->external_pdr != NULL)
-    free (debug->external_pdr);
-  if (debug->external_sym != NULL)
-    free (debug->external_sym);
-  if (debug->external_opt != NULL)
-    free (debug->external_opt);
-  if (debug->external_aux != NULL)
-    free (debug->external_aux);
-  if (debug->ss != NULL)
-    free (debug->ss);
-  if (debug->ssext != NULL)
-    free (debug->ssext);
-  if (debug->external_fdr != NULL)
-    free (debug->external_fdr);
-  if (debug->external_rfd != NULL)
-    free (debug->external_rfd);
-  if (debug->external_ext != NULL)
-    free (debug->external_ext);
+  free (ext_hdr);
+  free (debug->line);
+  free (debug->external_dnr);
+  free (debug->external_pdr);
+  free (debug->external_sym);
+  free (debug->external_opt);
+  free (debug->external_aux);
+  free (debug->ss);
+  free (debug->ssext);
+  free (debug->external_fdr);
+  free (debug->external_rfd);
+  free (debug->external_ext);
   return FALSE;
 }
 \f
@@ -1613,30 +1606,19 @@ mips_elf_create_procedure_table (void *handle, bfd *abfd,
      matters, but someday it might).  */
   s->map_head.link_order = NULL;
 
-  if (epdr != NULL)
-    free (epdr);
-  if (rpdr != NULL)
-    free (rpdr);
-  if (esym != NULL)
-    free (esym);
-  if (ss != NULL)
-    free (ss);
-  if (sv != NULL)
-    free (sv);
-
+  free (epdr);
+  free (rpdr);
+  free (esym);
+  free (ss);
+  free (sv);
   return TRUE;
 
  error_return:
-  if (epdr != NULL)
-    free (epdr);
-  if (rpdr != NULL)
-    free (rpdr);
-  if (esym != NULL)
-    free (esym);
-  if (ss != NULL)
-    free (ss);
-  if (sv != NULL)
-    free (sv);
+  free (epdr);
+  free (rpdr);
+  free (esym);
+  free (ss);
+  free (sv);
   return FALSE;
 }
 \f
@@ -5644,11 +5626,12 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
        }
       else
        {
-         bfd_boolean reject_undefined
-           = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
-              || ELF_ST_VISIBILITY (h->root.other) != STV_DEFAULT);
+          bfd_boolean reject_undefined
+           = (info->unresolved_syms_in_objects == RM_DIAGNOSE
+              && !info->warn_unresolved_syms)
+           || ELF_ST_VISIBILITY (h->root.other) != STV_DEFAULT;
 
-         (*info->callbacks->undefined_symbol)
+         info->callbacks->undefined_symbol
            (info, h->root.root.root.string, input_bfd,
             input_section, relocation->r_offset, reject_undefined);
 
@@ -6602,7 +6585,7 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
        }
 
       /* Make this the JALX opcode.  */
-      x = (x & ~(0x3f << 26)) | (jalx_opcode << 26);
+      x = (x & ~(0x3fu << 26)) | (jalx_opcode << 26);
     }
   else if (cross_mode_jump_p && b_reloc_p (r_type))
     {
@@ -7420,10 +7403,7 @@ _bfd_mips_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *hdr)
 
 /* Handle a MIPS specific section when reading an object file.  This
    is called when elfcode.h finds a section with an unknown type.
-   This routine supports both the 32-bit and 64-bit ELF ABI.
-
-   FIXME: We need to handle the SHF_MIPS_GPREL flag, but I'm not sure
-   how to.  */
+   This routine supports both the 32-bit and 64-bit ELF ABI.  */
 
 bfd_boolean
 _bfd_mips_elf_section_from_shdr (bfd *abfd,
@@ -7512,6 +7492,9 @@ _bfd_mips_elf_section_from_shdr (bfd *abfd,
   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
     return FALSE;
 
+  if (hdr->sh_flags & SHF_MIPS_GPREL)
+    flags |= SEC_SMALL_DATA;
+
   if (flags)
     {
       if (!bfd_set_section_flags (hdr->bfd_section,
@@ -7830,7 +7813,7 @@ _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
        {
          asymbol *elf_text_symbol;
          asection *elf_text_section;
-         bfd_size_type amt = sizeof (asection);
+         size_t amt = sizeof (asection);
 
          elf_text_section = bfd_zalloc (abfd, amt);
          if (elf_text_section == NULL)
@@ -7871,7 +7854,7 @@ _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
        {
          asymbol *elf_data_symbol;
          asection *elf_data_section;
-         bfd_size_type amt = sizeof (asection);
+         size_t amt = sizeof (asection);
 
          elf_data_section = bfd_zalloc (abfd, amt);
          if (elf_data_section == NULL)
@@ -9305,12 +9288,21 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   hmips = (struct mips_elf_link_hash_entry *) h;
 
   /* Make sure we know what is going on here.  */
-  BFD_ASSERT (dynobj != NULL
-             && (h->needs_plt
-                 || h->is_weakalias
-                 || (h->def_dynamic
-                     && h->ref_regular
-                     && !h->def_regular)));
+  if (dynobj == NULL
+      || (! h->needs_plt
+         && ! h->is_weakalias
+         && (! h->def_dynamic
+             || ! h->ref_regular
+             || h->def_regular)))
+    {
+      if (h->type == STT_GNU_IFUNC)
+       _bfd_error_handler (_("IFUNC symbol %s in dynamic symbol table - IFUNCS are not supported"),
+                           h->root.root.string);
+      else
+       _bfd_error_handler (_("non-dynamic symbol %s in dynamic symbol table"),
+                           h->root.root.string);
+      return TRUE;
+    }
 
   hmips = (struct mips_elf_link_hash_entry *) h;
 
@@ -12549,7 +12541,7 @@ _bfd_mips_elf_modify_segment_map (bfd *abfd,
 {
   asection *s;
   struct elf_segment_map *m, **pm;
-  bfd_size_type amt;
+  size_t amt;
 
   /* If there is a .reginfo section, we need a PT_MIPS_REGINFO
      segment.  */
@@ -12752,7 +12744,7 @@ _bfd_mips_elf_modify_segment_map (bfd *abfd,
                && s->vma + s->size <= high)
              ++c;
 
-         amt = sizeof *n + (bfd_size_type) (c - 1) * sizeof (asection *);
+         amt = sizeof *n - sizeof (asection *) + c * sizeof (asection *);
          n = bfd_zalloc (abfd, amt);
          if (n == NULL)
            return FALSE;
@@ -13079,26 +13071,17 @@ _bfd_mips_elf_find_nearest_line (bfd *abfd, asymbol **symbols,
                                     line_ptr, discriminator_ptr,
                                     dwarf_debug_sections,
                                     &elf_tdata (abfd)->dwarf2_find_line_info)
-      || _bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
-                                       filename_ptr, functionname_ptr,
-                                       line_ptr))
-    {
-      /* PR 22789: If the function name or filename was not found through
-        the debug information, then try an ordinary lookup instead.  */
-      if ((functionname_ptr != NULL && *functionname_ptr == NULL)
-         || (filename_ptr != NULL && *filename_ptr == NULL))
-       {
-         /* Do not override already discovered names.  */
-         if (functionname_ptr != NULL && *functionname_ptr != NULL)
-           functionname_ptr = NULL;
-
-         if (filename_ptr != NULL && *filename_ptr != NULL)
-           filename_ptr = NULL;
-
-         _bfd_elf_find_function (abfd, symbols, section, offset,
-                                 filename_ptr, functionname_ptr);
-       }
+      == 1)
+    return TRUE;
 
+  if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
+                                    filename_ptr, functionname_ptr,
+                                    line_ptr))
+    {
+      if (!*functionname_ptr)
+       _bfd_elf_find_function (abfd, symbols, section, offset,
+                               *filename_ptr ? NULL : filename_ptr,
+                               functionname_ptr);
       return TRUE;
     }
 
@@ -13212,7 +13195,7 @@ _bfd_mips_elf_set_section_contents (bfd *abfd, sec_ptr section,
 
       if (elf_section_data (section) == NULL)
        {
-         bfd_size_type amt = sizeof (struct bfd_elf_section_data);
+         size_t amt = sizeof (struct bfd_elf_section_data);
          section->used_by_bfd = bfd_zalloc (abfd, amt);
          if (elf_section_data (section) == NULL)
            return FALSE;
@@ -13385,13 +13368,11 @@ _bfd_elf_mips_get_relocated_section_contents
            }
        }
     }
-  if (reloc_vector != NULL)
-    free (reloc_vector);
+  free (reloc_vector);
   return data;
 
-error_return:
-  if (reloc_vector != NULL)
-    free (reloc_vector);
+ error_return:
+  free (reloc_vector);
   return NULL;
 }
 \f
@@ -14268,21 +14249,17 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
        }
     }
 
-  if (internal_relocs != NULL
-      && elf_section_data (sec)->relocs != internal_relocs)
+  if (elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
 
   return TRUE;
 
  error_return:
-  if (isymbuf != NULL
-      && symtab_hdr->contents != (unsigned char *) isymbuf)
+  if (symtab_hdr->contents != (unsigned char *) isymbuf)
     free (isymbuf);
-  if (contents != NULL
-      && elf_section_data (sec)->this_hdr.contents != contents)
+  if (elf_section_data (sec)->this_hdr.contents != contents)
     free (contents);
-  if (internal_relocs != NULL
-      && elf_section_data (sec)->relocs != internal_relocs)
+  if (elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
 
   return FALSE;
@@ -14294,7 +14271,7 @@ struct bfd_link_hash_table *
 _bfd_mips_elf_link_hash_table_create (bfd *abfd)
 {
   struct mips_elf_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct mips_elf_link_hash_table);
+  size_t amt = sizeof (struct mips_elf_link_hash_table);
 
   ret = bfd_zmalloc (amt);
   if (ret == NULL)
@@ -15761,6 +15738,7 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   /* Check to see if the input BFD actually contains any sections.  If not,
      then it has no attributes, and its flags may not have been initialized
      either, but it cannot actually cause any incompatibility.  */
+  /* FIXME: This excludes any input shared library from consideration.  */
   for (sec = ibfd->sections; sec != NULL; sec = sec->next)
     {
       /* Ignore synthetic sections and empty .text, .data and .bss sections
@@ -16645,12 +16623,15 @@ enum
   MIPS_LIBC_ABI_MAX
 };
 
-void
-_bfd_mips_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
+bfd_boolean
+_bfd_mips_init_file_header (bfd *abfd, struct bfd_link_info *link_info)
 {
   struct mips_elf_link_hash_table *htab = NULL;
   Elf_Internal_Ehdr *i_ehdrp;
 
+  if (!_bfd_elf_init_file_header (abfd, link_info))
+    return FALSE;
+
   i_ehdrp = elf_elfheader (abfd);
   if (link_info)
     {
@@ -16673,8 +16654,7 @@ _bfd_mips_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
      if it is the only hash section that will be created.  */
   if (link_info && link_info->emit_gnu_hash && !link_info->emit_hash)
     i_ehdrp->e_ident[EI_ABIVERSION] = MIPS_LIBC_ABI_XHASH;
-
-  _bfd_elf_post_process_headers (abfd, link_info);
+  return TRUE;
 }
 
 int
This page took 0.033732 seconds and 4 git commands to generate.