x86: Add GENERATE_DYNAMIC_RELOCATION_P
[deliverable/binutils-gdb.git] / bfd / mach-o.c
index b1bac05009e5f7e6e6feb8639cf710660463a1a5..9fe6326a299bc86d4ff4e86824b90a78e60959a3 100644 (file)
@@ -1,5 +1,5 @@
 /* Mach-O support for BFD.
-   Copyright (C) 1999-2015 Free Software Foundation, Inc.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -775,7 +775,7 @@ bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
 
   if (!bfd_mach_o_read_symtab_symbols (abfd))
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
         (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
       return 0;
     }
@@ -1299,7 +1299,7 @@ bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
 /* In addition to the need to byte-swap the symbol number, the bit positions
    of the fields in the relocation information vary per target endian-ness.  */
 
-static void
+void
 bfd_mach_o_swap_in_non_scattered_reloc (bfd *abfd, bfd_mach_o_reloc_info *rel,
                                       unsigned char *fields)
 {
@@ -1325,17 +1325,87 @@ bfd_mach_o_swap_in_non_scattered_reloc (bfd *abfd, bfd_mach_o_reloc_info *rel,
     }
 }
 
-static int
-bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
-                                   struct mach_o_reloc_info_external *raw,
-                                   arelent *res, asymbol **syms)
+/* Set syms_ptr_ptr and addend of RES.  */
+
+bfd_boolean
+bfd_mach_o_canonicalize_non_scattered_reloc (bfd *abfd,
+                                            bfd_mach_o_reloc_info *reloc,
+                                            arelent *res, asymbol **syms)
 {
   bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
-  bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
-  bfd_mach_o_reloc_info reloc;
-  bfd_vma addr;
+  unsigned int num;
   asymbol **sym;
 
+  /* Non-scattered relocation.  */
+  reloc->r_scattered = 0;
+  res->addend = 0;
+
+  num = reloc->r_value;
+
+  if (reloc->r_extern)
+    {
+      /* PR 17512: file: 8396-1185-0.004.  */
+      if (num >= (unsigned) bfd_mach_o_count_symbols (abfd))
+       sym = bfd_und_section_ptr->symbol_ptr_ptr;
+      else if (syms == NULL)
+       sym = bfd_und_section_ptr->symbol_ptr_ptr;
+      else
+       /* An external symbol number.  */
+       sym = syms + num;
+    }
+  else if (num == 0x00ffffff || num == 0)
+    {
+      /* The 'symnum' in a non-scattered PAIR is 0x00ffffff.  But as this
+        is generic code, we don't know wether this is really a PAIR.
+        This value is almost certainly not a valid section number, hence
+        this specific case to avoid an assertion failure.
+        Target specific swap_reloc_in routine should adjust that.  */
+      sym = bfd_abs_section_ptr->symbol_ptr_ptr;
+    }
+  else
+    {
+      /* PR 17512: file: 006-2964-0.004.  */
+      if (num > mdata->nsects)
+       return FALSE;
+
+      /* A section number.  */
+      sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
+      /* For a symbol defined in section S, the addend (stored in the
+        binary) contains the address of the section.  To comply with
+        bfd convention, subtract the section address.
+        Use the address from the header, so that the user can modify
+             the vma of the section.  */
+      res->addend = -mdata->sections[num - 1]->addr;
+    }
+
+  /* Note: Pairs for PPC LO/HI/HA are not scattered, but contain the offset
+     in the lower 16bits of the address value.  So we have to find the
+     'symbol' from the preceding reloc.  We do this even though the
+     section symbol is probably not needed here, because NULL symbol
+     values cause an assert in generic BFD code.  This must be done in
+     the PPC swap_reloc_in routine.  */
+  res->sym_ptr_ptr = sym;
+
+  return TRUE;
+}
+
+/* Do most of the work for canonicalize_relocs on RAW: create internal
+   representation RELOC and set most fields of RES using symbol table SYMS.
+   Each target still has to set the howto of RES and possibly adjust other
+   fields.
+   Previously the Mach-O hook point was simply swap_in, but some targets
+   (like arm64) don't follow the generic rules (symnum is a value for the
+   non-scattered relocation ADDEND).  */
+
+bfd_boolean
+bfd_mach_o_pre_canonicalize_one_reloc (bfd *abfd,
+                                      struct mach_o_reloc_info_external *raw,
+                                      bfd_mach_o_reloc_info *reloc,
+                                      arelent *res, asymbol **syms)
+{
+  bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+  bfd_vma addr;
+
   addr = bfd_get_32 (abfd, raw->r_address);
   res->sym_ptr_ptr = NULL;
   res->addend = 0;
@@ -1346,11 +1416,11 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
       bfd_vma symnum = bfd_get_32 (abfd, raw->r_symbolnum);
 
       /* Scattered relocation, can't be extern. */
-      reloc.r_scattered = 1;
-      reloc.r_extern = 0;
+      reloc->r_scattered = 1;
+      reloc->r_extern = 0;
 
       /*   Extract section and offset from r_value (symnum).  */
-      reloc.r_value = symnum;
+      reloc->r_value = symnum;
       /* FIXME: This breaks when a symbol in a reloc exactly follows the
         end of the data for the section (e.g. in a calculation of section
         data length).  At present, the symbol will end up associated with
@@ -1368,81 +1438,33 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
         }
 
       /* Extract the info and address fields from r_address.  */
-      reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr);
-      reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
-      reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL;
-      reloc.r_address = BFD_MACH_O_GET_SR_TYPE (addr);
+      reloc->r_type = BFD_MACH_O_GET_SR_TYPE (addr);
+      reloc->r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
+      reloc->r_pcrel = addr & BFD_MACH_O_SR_PCREL;
+      reloc->r_address = BFD_MACH_O_GET_SR_TYPE (addr);
       res->address = BFD_MACH_O_GET_SR_ADDRESS (addr);
     }
   else
     {
-      unsigned int num;
-
       /* Non-scattered relocation.  */
-      reloc.r_scattered = 0;
+      reloc->r_scattered = 0;
+      reloc->r_address = addr;
+      res->address = addr;
 
       /* The value and info fields have to be extracted dependent on target
          endian-ness.  */
-      bfd_mach_o_swap_in_non_scattered_reloc (abfd, &reloc, raw->r_symbolnum);
-      num = reloc.r_value;
+      bfd_mach_o_swap_in_non_scattered_reloc (abfd, reloc, raw->r_symbolnum);
 
-      if (reloc.r_extern)
-       {
-         /* PR 17512: file: 8396-1185-0.004.  */
-         if (num >= (unsigned) bfd_mach_o_count_symbols (abfd))
-           sym = bfd_und_section_ptr->symbol_ptr_ptr;
-         else if (syms == NULL)
-           sym = bfd_und_section_ptr->symbol_ptr_ptr;
-         else
-           /* An external symbol number.  */
-           sym = syms + num;
-       }
-      else if (num == 0x00ffffff || num == 0)
-       {
-         /* The 'symnum' in a non-scattered PAIR is 0x00ffffff.  But as this
-            is generic code, we don't know wether this is really a PAIR.
-            This value is almost certainly not a valid section number, hence
-            this specific case to avoid an assertion failure.
-            Target specific swap_reloc_in routine should adjust that.  */
-         sym = bfd_abs_section_ptr->symbol_ptr_ptr;
-       }
-      else
-        {
-         /* PR 17512: file: 006-2964-0.004.  */
-         if (num > mdata->nsects)
-           return -1;
-
-         /* A section number.  */
-          sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
-          /* For a symbol defined in section S, the addend (stored in the
-             binary) contains the address of the section.  To comply with
-             bfd convention, subtract the section address.
-             Use the address from the header, so that the user can modify
-             the vma of the section.  */
-          res->addend = -mdata->sections[num - 1]->addr;
-        }
-      /* Note: Pairs for PPC LO/HI/HA are not scattered, but contain the offset
-        in the lower 16bits of the address value.  So we have to find the
-        'symbol' from the preceding reloc.  We do this even though the
-        section symbol is probably not needed here, because NULL symbol
-        values cause an assert in generic BFD code.  This must be done in
-        the PPC swap_reloc_in routine.  */
-      res->sym_ptr_ptr = sym;
-
-      /* The 'address' is just r_address.
-         ??? maybe this should be masked with  0xffffff for safety.  */
-      res->address = addr;
-      reloc.r_address = addr;
+      if (!bfd_mach_o_canonicalize_non_scattered_reloc (abfd, reloc,
+                                                       res, syms))
+       return FALSE;
     }
 
   /* We have set up a reloc with all the information present, so the swapper
      can modify address, value and addend fields, if necessary, to convey
      information in the generic BFD reloc that is mach-o specific.  */
 
-  if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
-    return -1;
-
-  return 0;
+  return TRUE;
 }
 
 static int
@@ -1450,6 +1472,7 @@ bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
                                 unsigned long count,
                                 arelent *res, asymbol **syms)
 {
+  bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
   unsigned long i;
   struct mach_o_reloc_info_external *native_relocs;
   bfd_size_type native_size;
@@ -1472,8 +1495,8 @@ bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
 
   for (i = 0; i < count; i++)
     {
-      if (bfd_mach_o_canonicalize_one_reloc (abfd, &native_relocs[i],
-                                             &res[i], syms) < 0)
+      if (!(*bed->_bfd_mach_o_canonicalize_one_reloc)(abfd, &native_relocs[i],
+                                                     &res[i], syms, res))
         goto err;
     }
   free (native_relocs);
@@ -1495,7 +1518,7 @@ bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
     return 0;
 
   /* No need to go further if we don't know how to read relocs.  */
-  if (bed->_bfd_mach_o_swap_reloc_in == NULL)
+  if (bed->_bfd_mach_o_canonicalize_one_reloc == NULL)
     return 0;
 
   if (asect->relocation == NULL)
@@ -1550,7 +1573,7 @@ bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
     return 0;
 
   /* No need to go further if we don't know how to read relocs.  */
-  if (bed->_bfd_mach_o_swap_reloc_in == NULL)
+  if (bed->_bfd_mach_o_canonicalize_one_reloc == NULL)
     return 0;
 
   if (mdata->dyn_reloc_cache == NULL)
@@ -1875,7 +1898,7 @@ bfd_mach_o_write_symtab_content (bfd *abfd, bfd_mach_o_symtab_command *sym)
   if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0)
     goto err;
 
-  if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
+  if (!_bfd_stringtab_emit (abfd, strtab))
     goto err;
 
   /* Pad string table.  */
@@ -1955,8 +1978,8 @@ bfd_mach_o_build_dysymtab (bfd *abfd, bfd_mach_o_dysymtab_command *cmd)
       || cmd->ntoc != 0
       || cmd->nextrefsyms != 0)
     {
-      (*_bfd_error_handler) (_("sorry: modtab, toc and extrefsyms are not yet"
-                               " implemented for dysymtab commands."));
+      _bfd_error_handler (_("sorry: modtab, toc and extrefsyms are not yet"
+                           " implemented for dysymtab commands."));
       return FALSE;
     }
 
@@ -2398,8 +2421,8 @@ bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
   /* We need to check that this can be done...  */
   if (nsect > 255)
     {
-      (*_bfd_error_handler) (_("mach-o: there are too many sections (%u)"
-                              " maximum is 255,\n"), nsect);
+      _bfd_error_handler (_("mach-o: there are too many sections (%u)"
+                           " maximum is 255,\n"), nsect);
       return FALSE;
     }
 
@@ -2504,9 +2527,9 @@ bfd_mach_o_write_contents (bfd *abfd)
        /* Nothing to do.  */
        break;
       default:
-       (*_bfd_error_handler)
-         (_("unable to allocate data for load command 0x%lx"),
-          (unsigned long) cmd->type);
+       _bfd_error_handler
+         (_("unable to allocate data for load command %#x"),
+          cmd->type);
        break;
       }
 
@@ -2609,9 +2632,9 @@ bfd_mach_o_write_contents (bfd *abfd)
            return FALSE;
          break;
        default:
-         (*_bfd_error_handler)
-           (_("unable to write unknown load command 0x%lx"),
-            (unsigned long) cmd->type);
+         _bfd_error_handler
+           (_("unable to write unknown load command %#x"),
+            cmd->type);
          return FALSE;
        }
     }
@@ -2792,9 +2815,10 @@ bfd_mach_o_build_exec_seg_command (bfd *abfd, bfd_mach_o_segment_command *seg)
 
       if (s->addr < vma)
        {
-         (*_bfd_error_handler)
-           (_("section address (%lx) below start of segment (%lx)"),
-              (unsigned long) s->addr, (unsigned long) vma);
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("section address (%#Lx) below start of segment (%#Lx)"),
+              s->addr, vma);
          return FALSE;
        }
 
@@ -2933,9 +2957,9 @@ bfd_mach_o_layout_commands (bfd_mach_o_data_struct *mdata)
                 + BFD_MACH_O_LC_SIZE;
          break;
        default:
-         (*_bfd_error_handler)
-           (_("unable to layout unknown load command 0x%lx"),
-            (unsigned long) cmd->type);
+         _bfd_error_handler
+           (_("unable to layout unknown load command %#x"),
+            cmd->type);
          ret = FALSE;
          break;
        }
@@ -3469,8 +3493,9 @@ bfd_mach_o_read_section_32 (bfd *abfd, unsigned long prot)
   /* PR 17512: file: 0017eb76.  */
   if (section->align > 64)
     {
-      (*_bfd_error_handler) (_("bfd_mach_o_read_section_32: overlarge alignment value: 0x%x, using 32 instead"),
-                            section->align);
+      _bfd_error_handler
+       (_("bfd_mach_o_read_section_32: overlarge alignment value: %#lx, "
+          "using 32 instead"), section->align);
       section->align = 32;
     }
   section->reloff = bfd_h_get_32 (abfd, raw.reloff);
@@ -3511,8 +3536,9 @@ bfd_mach_o_read_section_64 (bfd *abfd, unsigned long prot)
   section->align = bfd_h_get_32 (abfd, raw.align);
   if (section->align > 64)
     {
-      (*_bfd_error_handler) (_("bfd_mach_o_read_section_64: overlarge alignment value: 0x%x, using 32 instead"),
-                            section->align);
+      _bfd_error_handler
+       (_("bfd_mach_o_read_section_64: overlarge alignment value: %#lx, "
+          "using 32 instead"), section->align);
       section->align = 32;
     }
   section->reloff = bfd_h_get_32 (abfd, raw.reloff);
@@ -3560,9 +3586,10 @@ bfd_mach_o_read_symtab_symbol (bfd *abfd,
   if (bfd_seek (abfd, symoff, SEEK_SET) != 0
       || bfd_bread (&raw, symwidth, abfd) != symwidth)
     {
-      (*_bfd_error_handler)
-        (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
-         symwidth, (unsigned long) symoff);
+      _bfd_error_handler
+       /* xgettext:c-format */
+        (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %u"),
+         symwidth, symoff);
       return FALSE;
     }
 
@@ -3578,10 +3605,11 @@ bfd_mach_o_read_symtab_symbol (bfd *abfd,
 
   if (stroff >= sym->strsize)
     {
-      (*_bfd_error_handler)
-        (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
-         (unsigned long) stroff,
-         (unsigned long) sym->strsize);
+      _bfd_error_handler
+       /* xgettext:c-format */
+        (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %u)"),
+         stroff,
+         sym->strsize);
       return FALSE;
     }
 
@@ -3660,9 +3688,12 @@ bfd_mach_o_read_symtab_symbol (bfd *abfd,
              /* Mach-O uses 0 to mean "no section"; not an error.  */
              if (section != 0)
                {
-                 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
-                                          "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
-                                        s->symbol.name, section, mdata->nsects);
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("bfd_mach_o_read_symtab_symbol: "
+                      "symbol \"%s\" specified invalid section %d (max %lu): "
+                      "setting to undefined"),
+                    s->symbol.name, section, mdata->nsects);
                }
              s->symbol.section = bfd_und_section_ptr;
            }
@@ -3676,9 +3707,11 @@ bfd_mach_o_read_symtab_symbol (bfd *abfd,
          s->symbol.value = 0;
          break;
        default:
-         (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
-                                  "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
-                                s->symbol.name, symtype);
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("bfd_mach_o_read_symtab_symbol: "
+              "symbol \"%s\" specified invalid type field 0x%x: "
+              "setting to undefined"), s->symbol.name, symtype);
          s->symbol.section = bfd_und_section_ptr;
          break;
        }
@@ -3716,6 +3749,9 @@ bfd_mach_o_read_symtab_strtab (bfd *abfd)
     }
   else
     {
+      /* See PR 21840 for a reproducer.  */
+      if ((sym->strsize + 1) == 0)
+       return FALSE;
       sym->strtab = bfd_alloc (abfd, sym->strsize + 1);
       if (sym->strtab == NULL)
         return FALSE;
@@ -3750,7 +3786,8 @@ bfd_mach_o_read_symtab_symbols (bfd *abfd)
   sym->symbols = bfd_alloc2 (abfd, sym->nsyms, sizeof (bfd_mach_o_asymbol));
   if (sym->symbols == NULL)
     {
-      (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
+      _bfd_error_handler (_("bfd_mach_o_read_symtab_symbols: "
+                           "unable to allocate memory for symbols"));
       sym->nsyms = 0;
       return FALSE;
     }
@@ -4722,8 +4759,8 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
       break;
     default:
       command->len = 0;
-      (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"),
-                           abfd, (unsigned long) command->type);
+      _bfd_error_handler (_("%B: unknown load command %#x"),
+                         abfd, command->type);
       return FALSE;
     }
 
@@ -4911,7 +4948,8 @@ bfd_mach_o_scan (bfd *abfd,
                                   &cputype, &cpusubtype);
   if (cputype == bfd_arch_unknown)
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
+       /* xgettext:c-format */
         (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
          header->cputype, header->cpusubtype);
       return FALSE;
@@ -5017,8 +5055,8 @@ bfd_mach_o_header_p (bfd *abfd,
   if (! (header.byteorder == BFD_ENDIAN_BIG
         || header.byteorder == BFD_ENDIAN_LITTLE))
     {
-      (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
-                            (unsigned long) header.byteorder);
+      _bfd_error_handler (_("unknown header byte-order value %#x"),
+                         header.byteorder);
       goto wrong;
     }
 
@@ -5606,9 +5644,9 @@ bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
 static bfd_mach_o_uuid_command *
 bfd_mach_o_lookup_uuid_command (bfd *abfd)
 {
-  bfd_mach_o_load_command *uuid_cmd;
+  bfd_mach_o_load_command *uuid_cmd = NULL;
   int ncmd = bfd_mach_o_lookup_command (abfd, BFD_MACH_O_LC_UUID, &uuid_cmd);
-  if (ncmd != 1)
+  if (ncmd != 1 || uuid_cmd == NULL)
     return FALSE;
   return &uuid_cmd->command.uuid;
 }
@@ -5685,7 +5723,7 @@ bfd_mach_o_follow_dsym (bfd *abfd)
   if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_mach_o_flavour)
     return NULL;
 
-  if (abfd->my_archive)
+  if (abfd->my_archive && !bfd_is_thin_archive (abfd->my_archive))
     base_bfd = abfd->my_archive;
   /* BFD may have been opened from a stream. */
   if (base_bfd->filename == NULL)
@@ -5775,14 +5813,26 @@ bfd_mach_o_close_and_cleanup (bfd *abfd)
       if (mdata->dsym_bfd != NULL)
         {
           bfd *fat_bfd = mdata->dsym_bfd->my_archive;
+#if 0
+         /* FIXME: PR 19435: This calculation to find the memory allocated by
+            bfd_mach_o_follow_dsym for the filename does not always end up
+            selecting the correct pointer.  Unfortunately this problem is
+            very hard to reproduce on a non Mach-O native system, so until it
+            can be traced and fixed on such a system, this code will remain
+            commented out.  This does mean that there will be a memory leak,
+            but it is small, and happens when we are closing down, so it
+            should not matter too much.  */
           char *dsym_filename = (char *)(fat_bfd
                                          ? fat_bfd->filename
                                          : mdata->dsym_bfd->filename);
+#endif
           bfd_close (mdata->dsym_bfd);
           mdata->dsym_bfd = NULL;
           if (fat_bfd)
             bfd_close (fat_bfd);
+#if 0
           free (dsym_filename);
+#endif
         }
     }
 
@@ -5807,7 +5857,7 @@ bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd)
 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
 #define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
 
-#define bfd_mach_o_swap_reloc_in NULL
+#define bfd_mach_o_canonicalize_one_reloc NULL
 #define bfd_mach_o_swap_reloc_out NULL
 #define bfd_mach_o_print_thread NULL
 #define bfd_mach_o_tgt_seg_table NULL
This page took 0.0377 seconds and 4 git commands to generate.