gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf32-mips.c
index 029de279fe8b88c1e91302cf9bfb4ac390112baa..e3c4f5594ff902cab3e85cfb56e0adef6eb92817 100644 (file)
@@ -1,5 +1,5 @@
 /* MIPS-specific support for 32-bit ELF
-   Copyright (C) 1993-2016 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>.
@@ -57,11 +57,9 @@ static bfd_reloc_status_type mips32_64bit_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
   (bfd *, bfd_reloc_code_real_type);
-static reloc_howto_type *mips_elf32_rtype_to_howto
-  (unsigned int, bfd_boolean);
-static void mips_info_to_howto_rel
+static bfd_boolean mips_info_to_howto_rel
   (bfd *, arelent *, Elf_Internal_Rela *);
-static void mips_info_to_howto_rela
+static bfd_boolean mips_info_to_howto_rela
   (bfd *, arelent *, Elf_Internal_Rela *);
 static bfd_boolean mips_elf_sym_is_global
   (bfd *, asymbol *);
@@ -172,7 +170,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-                               /* This needs complex overflow
+                               /* This needs complex overflow
                                   detection, because the upper four
                                   bits must match the PC + 4.  */
         _bfd_mips_elf_generic_reloc, /* special_function */
@@ -534,7 +532,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* Protected jump conversion.  This is an optimization hint.  No
      relocation is required for correctness.  */
-  HOWTO (R_MIPS_JALR,          /* type */
+  HOWTO (R_MIPS_JALR,          /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
@@ -542,7 +540,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         _bfd_mips_elf_generic_reloc, /* special_function */
-        "R_MIPS_JALR",         /* name */
+        "R_MIPS_JALR",         /* name */
         FALSE,                 /* partial_inplace */
         0x00000000,            /* src_mask */
         0x00000000,            /* dst_mask */
@@ -838,7 +836,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-                               /* This needs complex overflow
+                               /* This needs complex overflow
                                   detection, because the upper four
                                   bits must match the PC.  */
         _bfd_mips_elf_generic_reloc, /* special_function */
@@ -860,7 +858,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
         "R_MIPS16_GPREL",      /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
-        0x0000ffff,            /* dst_mask */
+        0x0000ffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* A MIPS16 reference to the global offset table.  */
@@ -875,7 +873,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
         "R_MIPS16_GOT16",      /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
-        0x0000ffff,            /* dst_mask */
+        0x0000ffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* A MIPS16 call through the global offset table.  */
@@ -890,7 +888,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
         "R_MIPS16_CALL16",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
-        0x0000ffff,            /* dst_mask */
+        0x0000ffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* MIPS16 high 16 bits of symbol value.  */
@@ -905,7 +903,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
         "R_MIPS16_HI16",       /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
-        0x0000ffff,            /* dst_mask */
+        0x0000ffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* MIPS16 low 16 bits of symbol value.  */
@@ -920,7 +918,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
         "R_MIPS16_LO16",       /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
-        0x0000ffff,            /* dst_mask */
+        0x0000ffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* MIPS16 TLS general dynamic variable reference.  */
@@ -1058,7 +1056,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-                               /* This needs complex overflow
+                               /* This needs complex overflow
                                   detection, because the upper four
                                   bits must match the PC.  */
         _bfd_mips_elf_generic_reloc, /* special_function */
@@ -1625,8 +1623,8 @@ static reloc_howto_type elf_mips_copy_howto =
         _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_COPY",         /* name */
         FALSE,                 /* partial_inplace */
-        0x0,                   /* src_mask */
-        0x0,                   /* dst_mask */
+        0x0,                   /* src_mask */
+        0x0,                   /* dst_mask */
         FALSE);                /* pcrel_offset */
 
 /* Originally a VxWorks extension, but now used for other systems too.  */
@@ -1641,8 +1639,8 @@ static reloc_howto_type elf_mips_jump_slot_howto =
         _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_JUMP_SLOT",    /* name */
         FALSE,                 /* partial_inplace */
-        0x0,                   /* src_mask */
-        0x0,                   /* dst_mask */
+        0x0,                   /* src_mask */
+        0x0,                   /* dst_mask */
         FALSE);                /* pcrel_offset */
 
 /* Used in EH tables.  */
@@ -1658,7 +1656,7 @@ static reloc_howto_type elf_mips_eh_howto =
         "R_MIPS_EH",           /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
-        0xffffffff,            /* dst_mask */
+        0xffffffff,            /* dst_mask */
         FALSE);                /* pcrel_offset */
 
 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
@@ -2196,9 +2194,12 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
 
 static reloc_howto_type *
-mips_elf32_rtype_to_howto (unsigned int r_type,
+mips_elf32_rtype_to_howto (bfd *abfd,
+                          unsigned int r_type,
                           bfd_boolean rela_p ATTRIBUTE_UNUSED)
 {
+  reloc_howto_type *howto = NULL;
+
   switch (r_type)
     {
     case R_MIPS_GNU_VTINHERIT:
@@ -2217,30 +2218,33 @@ mips_elf32_rtype_to_howto (unsigned int r_type,
       return &elf_mips_eh_howto;
     default:
       if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
-       return &elf_micromips_howto_table_rel[r_type - R_MICROMIPS_min];
+       howto = &elf_micromips_howto_table_rel[r_type - R_MICROMIPS_min];
       if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
-        return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
-      if (r_type >= (unsigned int) R_MIPS_max)
-       {
-         (*_bfd_error_handler) (_("Unrecognised MIPS reloc number: %d"), r_type);
-         bfd_set_error (bfd_error_bad_value);
-         r_type = R_MIPS_NONE;
-       }
-      return &elf_mips_howto_table_rel[r_type];
+       howto = &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
+      if (r_type < R_MIPS_max)
+       howto = &elf_mips_howto_table_rel[r_type];
+      if (howto != NULL && howto->name != NULL)
+       return howto;
+
+      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                         abfd, r_type);
+      bfd_set_error (bfd_error_bad_value);
+      return NULL;
     }
 }
 
 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
 
-static void
+static bfd_boolean
 mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
 {
-  const struct elf_backend_data *bed;
   unsigned int r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
-  bed = get_elf_backend_data (abfd);
-  cache_ptr->howto = bed->elf_backend_mips_rtype_to_howto (r_type, FALSE);
+  cache_ptr->howto = mips_elf32_rtype_to_howto (abfd, r_type, FALSE);
+
+  if (cache_ptr->howto == NULL)
+    return FALSE;
 
   /* The addend for a GPREL16 or LITERAL relocation comes from the GP
      value for the object file.  We get the addend now, rather than
@@ -2249,14 +2253,16 @@ mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
   if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
       && (gprel16_reloc_p (r_type) || literal_reloc_p (r_type)))
     cache_ptr->addend = elf_gp (abfd);
+
+  return TRUE;
 }
 
 /* Given a MIPS Elf_Internal_Rela, fill in an arelent structure.  */
 
-static void
+static bfd_boolean
 mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
 {
-  mips_info_to_howto_rel (abfd, cache_ptr, dst);
+  return mips_info_to_howto_rel (abfd, cache_ptr, dst);
 
   /* If we ever need to do any extra processing with dst->r_addend
      (the field omitted in an Elf_Internal_Rel) we can do it here.  */
@@ -2275,8 +2281,8 @@ mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
     return (sym->flags & BSF_SECTION_SYM) == 0;
   else
     return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
-           || bfd_is_und_section (bfd_get_section (sym))
-           || bfd_is_com_section (bfd_get_section (sym)));
+           || bfd_is_und_section (bfd_asymbol_section (sym))
+           || bfd_is_com_section (bfd_asymbol_section (sym)));
 }
 \f
 /* Set the right machine number for a MIPS ELF file.  */
@@ -2353,6 +2359,8 @@ elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
        return FALSE;
 
       case 128:                /* Linux/MIPS elf_prpsinfo */
+       elf_tdata (abfd)->core->pid
+        = bfd_get_32 (abfd, note->descdata + 16);
        elf_tdata (abfd)->core->program
         = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
        elf_tdata (abfd)->core->command
@@ -2373,6 +2381,56 @@ elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
   return TRUE;
 }
+
+/* Write Linux core PRSTATUS note into core file.  */
+
+static char *
+elf32_mips_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
+                            ...)
+{
+  switch (note_type)
+    {
+    default:
+      return NULL;
+
+    case NT_PRPSINFO:
+      BFD_FAIL ();
+      return NULL;
+
+    case NT_PRSTATUS:
+      {
+       char data[256];
+       va_list ap;
+       long pid;
+       int cursig;
+       const void *greg;
+
+       va_start (ap, note_type);
+       memset (data, 0, 72);
+       pid = va_arg (ap, long);
+       bfd_put_32 (abfd, pid, data + 24);
+       cursig = va_arg (ap, int);
+       bfd_put_16 (abfd, cursig, data + 12);
+       greg = va_arg (ap, const void *);
+       memcpy (data + 72, greg, 180);
+       memset (data + 252, 0, 4);
+       va_end (ap);
+       return elfcore_write_note (abfd, buf, bufsiz,
+                                  "CORE", note_type, data, sizeof (data));
+      }
+    }
+}
+
+/* Remove the magic _gp_disp symbol from the symbol tables.  */
+
+static bfd_boolean
+elf32_mips_fixup_symbol (struct bfd_link_info *info,
+                        struct elf_link_hash_entry *h)
+{
+  if (strcmp (h->root.root.string, "_gp_disp") == 0)
+    _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
+  return TRUE;
+}
 \f
 /* Depending on the target vector we generate some version of Irix
    executables or "normal" MIPS ELF ABI executables.  */
@@ -2474,14 +2532,16 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
                                        _bfd_mips_elf_additional_program_headers
 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
 #define elf_backend_gc_mark_hook       _bfd_mips_elf_gc_mark_hook
-#define elf_backend_gc_sweep_hook      _bfd_mips_elf_gc_sweep_hook
 #define elf_backend_copy_indirect_symbol \
                                        _bfd_mips_elf_copy_indirect_symbol
+#define elf_backend_hide_symbol                _bfd_mips_elf_hide_symbol
+#define elf_backend_fixup_symbol       elf32_mips_fixup_symbol
 #define elf_backend_grok_prstatus      elf32_mips_grok_prstatus
 #define elf_backend_grok_psinfo                elf32_mips_grok_psinfo
 #define elf_backend_ecoff_debug_swap   &mips_elf32_ecoff_debug_swap
 
 #define elf_backend_got_header_size    (4 * MIPS_RESERVED_GOTNO)
+#define elf_backend_want_dynrelro      1
 #define elf_backend_may_use_rel_p      1
 #define elf_backend_may_use_rela_p     0
 #define elf_backend_default_use_rela_p 0
@@ -2540,10 +2600,10 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
 #undef ELF_MAXPAGESIZE
 #undef ELF_COMMONPAGESIZE
 
-#define TARGET_LITTLE_SYM               mips_elf32_trad_le_vec
-#define TARGET_LITTLE_NAME              "elf32-tradlittlemips"
-#define TARGET_BIG_SYM                  mips_elf32_trad_be_vec
-#define TARGET_BIG_NAME                 "elf32-tradbigmips"
+#define TARGET_LITTLE_SYM              mips_elf32_trad_le_vec
+#define TARGET_LITTLE_NAME             "elf32-tradlittlemips"
+#define TARGET_BIG_SYM                 mips_elf32_trad_be_vec
+#define TARGET_BIG_NAME                        "elf32-tradbigmips"
 
 /* The MIPS ABI says at Page 5-1:
    Virtual addresses and file offsets for MIPS segments are congruent
@@ -2554,6 +2614,9 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
 #define ELF_COMMONPAGESIZE             0x1000
 #define elf32_bed                      elf32_tradbed
 
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note    elf32_mips_write_core_note
+
 /* Include the target file again for this target.  */
 #include "elf32-target.h"
 
@@ -2575,14 +2638,16 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
 #undef elf32_bed
 #define elf32_bed                              elf32_fbsd_tradbed
 
+#undef elf_backend_write_core_note
+
 #include "elf32-target.h"
 /* Implement elf_backend_final_write_processing for VxWorks.  */
 
-static void
-mips_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
+static bfd_boolean
+mips_vxworks_final_write_processing (bfd *abfd)
 {
-  _bfd_mips_elf_final_write_processing (abfd, linker);
-  elf_vxworks_final_write_processing (abfd, linker);
+  _bfd_mips_final_write_processing (abfd);
+  return elf_vxworks_final_write_processing (abfd);
 }
 
 #undef TARGET_LITTLE_SYM
@@ -2593,10 +2658,10 @@ mips_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
 #undef ELF_MAXPAGESIZE
 #undef ELF_COMMONPAGESIZE
 
-#define TARGET_LITTLE_SYM               mips_elf32_vxworks_le_vec
-#define TARGET_LITTLE_NAME              "elf32-littlemips-vxworks"
-#define TARGET_BIG_SYM                  mips_elf32_vxworks_be_vec
-#define TARGET_BIG_NAME                 "elf32-bigmips-vxworks"
+#define TARGET_LITTLE_SYM              mips_elf32_vxworks_le_vec
+#define TARGET_LITTLE_NAME             "elf32-littlemips-vxworks"
+#define TARGET_BIG_SYM                 mips_elf32_vxworks_be_vec
+#define TARGET_BIG_NAME                        "elf32-bigmips-vxworks"
 #undef ELF_OSABI
 
 #undef elf32_bed
@@ -2617,6 +2682,8 @@ mips_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
 #define elf_backend_default_use_rela_p         1
 #undef elf_backend_got_header_size
 #define elf_backend_got_header_size            (4 * 3)
+#undef elf_backend_dtrel_excludes_plt
+#define elf_backend_dtrel_excludes_plt         1
 
 #undef elf_backend_finish_dynamic_symbol
 #define elf_backend_finish_dynamic_symbol \
This page took 0.028974 seconds and 4 git commands to generate.