gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf64-alpha.c
index 490860123c917241104069418f7da2754085080f..4e4efae0b1bf2d76980d7f51a6a4183674d3e1de 100644 (file)
@@ -1,5 +1,5 @@
 /* Alpha specific support for 64-bit ELF
-   Copyright (C) 1996-2019 Free Software Foundation, Inc.
+   Copyright (C) 1996-2020 Free Software Foundation, Inc.
    Contributed by Richard Henderson <rth@tamu.edu>.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -27,6 +27,7 @@
 #include "bfd.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
+#include "ecoff-bfd.h"
 
 #include "elf/alpha.h"
 
@@ -143,14 +144,14 @@ struct alpha_elf_reloc_entry
   /* Which .reloc section? */
   asection *srel;
 
-  /* What kind of relocation? */
-  unsigned int rtype;
-
-  /* Is this against read-only section? */
-  unsigned int reltext : 1;
+  /* Which section this relocation is against? */
+  asection *sec;
 
   /* How many did we find?  */
   unsigned long count;
+
+  /* What kind of relocation? */
+  unsigned int rtype;
 };
 
 struct alpha_elf_link_hash_entry
@@ -279,7 +280,7 @@ static struct bfd_link_hash_table *
 elf64_alpha_bfd_link_hash_table_create (bfd *abfd)
 {
   struct alpha_elf_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct alpha_elf_link_hash_table);
+  size_t amt = sizeof (struct alpha_elf_link_hash_table);
 
   ret = (struct alpha_elf_link_hash_table *) bfd_zmalloc (amt);
   if (ret == (struct alpha_elf_link_hash_table *) NULL)
@@ -1135,9 +1136,7 @@ elf64_alpha_info_to_howto (bfd *abfd, arelent *cache_ptr,
 \f
 /* Handle an Alpha specific section when reading an object file.  This
    is called when bfd_section_from_shdr finds a section with an unknown
-   type.
-   FIXME: We need to handle the SHF_ALPHA_GPREL flag, but I'm not sure
-   how to.  */
+   type.  */
 
 static bfd_boolean
 elf64_alpha_section_from_shdr (bfd *abfd,
@@ -1168,9 +1167,8 @@ elf64_alpha_section_from_shdr (bfd *abfd,
 
   if (hdr->sh_type == SHT_ALPHA_DEBUG)
     {
-      if (! bfd_set_section_flags (abfd, newsect,
-                                  (bfd_get_section_flags (abfd, newsect)
-                                   | SEC_DEBUGGING)))
+      if (!bfd_set_section_flags (newsect,
+                                 bfd_section_flags (newsect) | SEC_DEBUGGING))
        return FALSE;
     }
 
@@ -1180,10 +1178,10 @@ elf64_alpha_section_from_shdr (bfd *abfd,
 /* Convert Alpha specific section flags to bfd internal section flags.  */
 
 static bfd_boolean
-elf64_alpha_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
+elf64_alpha_section_flags (const Elf_Internal_Shdr *hdr)
 {
   if (hdr->sh_flags & SHF_ALPHA_GPREL)
-    *flags |= SEC_SMALL_DATA;
+    hdr->bfd_section->flags |= SEC_SMALL_DATA;
 
   return TRUE;
 }
@@ -1196,7 +1194,7 @@ elf64_alpha_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec)
 {
   register const char *name;
 
-  name = bfd_get_section_name (abfd, sec);
+  name = bfd_section_name (sec);
 
   if (strcmp (name, ".mdebug") == 0)
     {
@@ -1270,7 +1268,7 @@ elf64_alpha_create_got_section (bfd *abfd,
           | SEC_LINKER_CREATED);
   s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
   if (s == NULL
-      || !bfd_set_section_alignment (abfd, s, 3))
+      || !bfd_set_section_alignment (s, 3))
     return FALSE;
 
   alpha_elf_tdata (abfd)->got = s;
@@ -1302,7 +1300,7 @@ elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
           | (elf64_alpha_use_secureplt ? SEC_READONLY : 0));
   s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags);
   elf_hash_table (info)->splt = s;
-  if (s == NULL || ! bfd_set_section_alignment (abfd, s, 4))
+  if (s == NULL || ! bfd_set_section_alignment (s, 4))
     return FALSE;
 
   /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
@@ -1317,7 +1315,7 @@ elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
           | SEC_LINKER_CREATED | SEC_READONLY);
   s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt", flags);
   elf_hash_table (info)->srelplt = s;
-  if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
+  if (s == NULL || ! bfd_set_section_alignment (s, 3))
     return FALSE;
 
   if (elf64_alpha_use_secureplt)
@@ -1325,7 +1323,7 @@ elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
       flags = SEC_ALLOC | SEC_LINKER_CREATED;
       s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
       elf_hash_table (info)->sgotplt = s;
-      if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
+      if (s == NULL || ! bfd_set_section_alignment (s, 3))
        return FALSE;
     }
 
@@ -1343,7 +1341,7 @@ elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   s = bfd_make_section_anyway_with_flags (abfd, ".rela.got", flags);
   elf_hash_table (info)->srelgot = s;
   if (s == NULL
-      || !bfd_set_section_alignment (abfd, s, 3))
+      || !bfd_set_section_alignment (s, 3))
     return FALSE;
 
   /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the
@@ -1387,18 +1385,23 @@ elf64_alpha_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 = (type) 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, (file_ptr) 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 *);
@@ -1419,30 +1422,18 @@ elf64_alpha_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;
 }
 
@@ -1468,7 +1459,8 @@ elf64_alpha_find_nearest_line (bfd *abfd, asymbol **symbols,
                                     filename_ptr, functionname_ptr,
                                     line_ptr, discriminator_ptr,
                                     dwarf_debug_sections,
-                                    &elf_tdata (abfd)->dwarf2_find_line_info))
+                                    &elf_tdata (abfd)->dwarf2_find_line_info)
+      == 1)
     return TRUE;
 
   msec = bfd_get_section_by_name (abfd, ".mdebug");
@@ -1616,7 +1608,7 @@ elf64_alpha_output_extsym (struct alpha_elf_link_hash_entry *h, void * data)
            h->esym.asym.sc = scUndefined;
          else
            {
-             name = bfd_section_name (output_section->owner, output_section);
+             name = bfd_section_name (output_section);
 
              if (strcmp (name, ".text") == 0)
                h->esym.asym.sc = scText;
@@ -1723,7 +1715,7 @@ get_got_entry (bfd *abfd, struct alpha_elf_link_hash_entry *h,
   if (!gotent)
     {
       int entry_size;
-      bfd_size_type amt;
+      size_t amt;
 
       amt = sizeof (struct alpha_elf_got_entry);
       gotent = (struct alpha_elf_got_entry *) bfd_alloc (abfd, amt);
@@ -1786,7 +1778,6 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
   Elf_Internal_Shdr *symtab_hdr;
   struct alpha_elf_link_hash_entry **sym_hashes;
   const Elf_Internal_Rela *rel, *relend;
-  bfd_size_type amt;
 
   if (bfd_link_relocatable (info))
     return TRUE;
@@ -1989,15 +1980,15 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
              if (!rent)
                {
-                 amt = sizeof (struct alpha_elf_reloc_entry);
+                 size_t amt = sizeof (struct alpha_elf_reloc_entry);
                  rent = (struct alpha_elf_reloc_entry *) bfd_alloc (abfd, amt);
                  if (!rent)
                    return FALSE;
 
                  rent->srel = sreloc;
+                 rent->sec = sec;
                  rent->rtype = r_type;
                  rent->count = 1;
-                 rent->reltext = (sec->flags & SEC_READONLY) != 0;
 
                  rent->next = h->reloc_entries;
                  h->reloc_entries = rent;
@@ -2011,7 +2002,13 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
                 loaded into memory, we need a RELATIVE reloc.  */
              sreloc->size += sizeof (Elf64_External_Rela);
              if (sec->flags & SEC_READONLY)
-               info->flags |= DF_TEXTREL;
+               {
+                 info->flags |= DF_TEXTREL;
+                 info->callbacks->minfo
+                   (_("%pB: dynamic relocation against `%pT' in "
+                      "read-only section `%pA'\n"),
+                    sec->owner, h->root.root.root.string, sec);
+               }
            }
        }
     }
@@ -2696,10 +2693,17 @@ elf64_alpha_calc_dynrel_sizes (struct alpha_elf_link_hash_entry *h,
                                                 bfd_link_pie (info));
       if (entries)
        {
+         asection *sec = relent->sec;
          relent->srel->size +=
            entries * sizeof (Elf64_External_Rela) * relent->count;
-         if (relent->reltext)
-           info->flags |= DT_TEXTREL;
+         if ((sec->flags & SEC_READONLY) != 0)
+           {
+             info->flags |= DT_TEXTREL;
+             info->callbacks->minfo
+               (_("%pB: dynamic relocation against `%pT' in "
+                  "read-only section `%pA'\n"),
+                sec->owner, h->root.root.root.string, sec);
+           }
        }
     }
 
@@ -2860,7 +2864,7 @@ elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
       /* It's OK to base decisions on the section name, because none
         of the dynobj section names depend upon the input files.  */
-      name = bfd_get_section_name (dynobj, s);
+      name = bfd_section_name (s);
 
       if (CONST_STRNEQ (name, ".rela"))
        {
@@ -3170,12 +3174,10 @@ elf64_alpha_relax_opt_call (struct alpha_relax_info *info, bfd_vma symval)
 
       if (!gpdisp || gpdisp->r_addend != 4)
        {
-         if (tsec_free)
-           free (tsec_free);
+         free (tsec_free);
          return 0;
        }
-      if (tsec_free)
-       free (tsec_free);
+      free (tsec_free);
     }
 
   /* We've now determined that we can skip an initial gp load.  Verify
@@ -4021,14 +4023,11 @@ elf64_alpha_relax_section (bfd *abfd, asection *sec,
   return TRUE;
 
  error_return:
-  if (isymbuf != NULL
-      && symtab_hdr->contents != (unsigned char *) isymbuf)
+  if (symtab_hdr->contents != (unsigned char *) isymbuf)
     free (isymbuf);
-  if (info.contents != NULL
-      && elf_section_data (sec)->this_hdr.contents != info.contents)
+  if (elf_section_data (sec)->this_hdr.contents != info.contents)
     free (info.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;
 }
@@ -4508,7 +4507,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                    if (name == NULL)
                      name = _("<unknown>");
                    else if (name[0] == 0)
-                     name = bfd_section_name (input_bfd, sec);
+                     name = bfd_section_name (sec);
                  }
                _bfd_error_handler
                  /* xgettext:c-format */
@@ -4779,7 +4778,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                if (name == NULL)
                  return FALSE;
                if (*name == '\0')
-                 name = bfd_section_name (input_bfd, sec);
+                 name = bfd_section_name (sec);
              }
            (*info->callbacks->reloc_overflow)
              (info, (h ? &h->root.root : NULL), name, howto->name,
@@ -5522,6 +5521,9 @@ static const struct elf_size_info alpha_elf_size_info =
 #define elf_backend_special_sections \
   elf64_alpha_special_sections
 
+#define elf_backend_strip_zero_sized_dynamic_sections \
+  _bfd_elf_strip_zero_sized_dynamic_sections
+
 /* A few constants that determine how the .plt section is set up.  */
 #define elf_backend_want_got_plt 0
 #define elf_backend_plt_readonly 0
@@ -5544,12 +5546,14 @@ static const struct elf_size_info alpha_elf_size_info =
    "FreeBSD" label in the ELF header.  So we put this label on all
    executables and (for simplicity) also all other object files.  */
 
-static void
-elf64_alpha_fbsd_post_process_headers (bfd * abfd,
-       struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
+static bfd_boolean
+elf64_alpha_fbsd_init_file_header (bfd *abfd, struct bfd_link_info *info)
 {
   Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form.  */
 
+  if (!_bfd_elf_init_file_header (abfd, info))
+    return FALSE;
+
   i_ehdrp = elf_elfheader (abfd);
 
   /* Put an ABI label supported by FreeBSD >= 4.1.  */
@@ -5558,11 +5562,12 @@ elf64_alpha_fbsd_post_process_headers (bfd * abfd,
   /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard.  */
   memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
 #endif
+  return TRUE;
 }
 
-#undef elf_backend_post_process_headers
-#define elf_backend_post_process_headers \
-  elf64_alpha_fbsd_post_process_headers
+#undef elf_backend_init_file_header
+#define elf_backend_init_file_header \
+  elf64_alpha_fbsd_init_file_header
 
 #undef  elf64_bed
 #define elf64_bed elf64_alpha_fbsd_bed
This page took 0.055802 seconds and 4 git commands to generate.