gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / simple.c
index c2a741c6f90478e20ea137c76f231070bdd7dfc0..bbdef23a140d623631614ded8eb88723c28fae3c 100644 (file)
@@ -1,13 +1,12 @@
 /* simple.c -- BFD simple client routines
-   Copyright 2002, 2003
-   Free Software Foundation, Inc.
+   Copyright (C) 2002-2020 Free Software Foundation, Inc.
    Contributed by MontaVista Software, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "bfdlink.h"
 
-static bfd_boolean
+static void
 simple_dummy_warning (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
                      const char *warning ATTRIBUTE_UNUSED,
                      const char *symbol ATTRIBUTE_UNUSED,
@@ -32,10 +32,9 @@ simple_dummy_warning (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
                      asection *section ATTRIBUTE_UNUSED,
                      bfd_vma address ATTRIBUTE_UNUSED)
 {
-  return TRUE;
 }
 
-static bfd_boolean
+static void
 simple_dummy_undefined_symbol (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
                               const char *name ATTRIBUTE_UNUSED,
                               bfd *abfd ATTRIBUTE_UNUSED,
@@ -43,11 +42,11 @@ simple_dummy_undefined_symbol (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
                               bfd_vma address ATTRIBUTE_UNUSED,
                               bfd_boolean fatal ATTRIBUTE_UNUSED)
 {
-  return TRUE;
 }
 
-static bfd_boolean
+static void
 simple_dummy_reloc_overflow (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+                            struct bfd_link_hash_entry *entry ATTRIBUTE_UNUSED,
                             const char *name ATTRIBUTE_UNUSED,
                             const char *reloc_name ATTRIBUTE_UNUSED,
                             bfd_vma addend ATTRIBUTE_UNUSED,
@@ -55,27 +54,38 @@ simple_dummy_reloc_overflow (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
                             asection *section ATTRIBUTE_UNUSED,
                             bfd_vma address ATTRIBUTE_UNUSED)
 {
-  return TRUE;
 }
 
-static bfd_boolean
+static void
 simple_dummy_reloc_dangerous (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
                              const char *message ATTRIBUTE_UNUSED,
                              bfd *abfd ATTRIBUTE_UNUSED,
                              asection *section ATTRIBUTE_UNUSED,
                              bfd_vma address ATTRIBUTE_UNUSED)
 {
-  return TRUE;
 }
 
-static bfd_boolean
+static void
 simple_dummy_unattached_reloc (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
                               const char *name ATTRIBUTE_UNUSED,
                               bfd *abfd ATTRIBUTE_UNUSED,
                               asection *section ATTRIBUTE_UNUSED,
                               bfd_vma address ATTRIBUTE_UNUSED)
 {
-  return TRUE;
+}
+
+static void
+simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+                                 struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+                                 bfd *nbfd ATTRIBUTE_UNUSED,
+                                 asection *nsec ATTRIBUTE_UNUSED,
+                                 bfd_vma nval ATTRIBUTE_UNUSED)
+{
+}
+
+static void
+simple_dummy_einfo (const char *fmt ATTRIBUTE_UNUSED, ...)
+{
 }
 
 struct saved_output_info
@@ -84,16 +94,45 @@ struct saved_output_info
   asection *section;
 };
 
+struct saved_offsets
+{
+  unsigned int section_count;
+  struct saved_output_info *sections;
+};
+
+/* The sections in ABFD may already have output sections and offsets
+   set if we are here during linking.
+
+   DWARF-2 specifies offsets into debug sections in many cases and
+   bfd_simple_get_relocated_section_contents is called to relocate
+   debug info for a single relocatable object file.  So we want
+   offsets relative to that object file's sections, not offsets in the
+   output file.  For that reason, reset a debug section->output_offset
+   to zero.
+
+   If not called during linking then set section->output_section to
+   point back to the input section, because output_section must not be
+   NULL when calling the relocation routines.
+
+   Save the original output offset and section to restore later.  */
+
 static void
 simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED,
                         asection *section,
                         void *ptr)
 {
-  struct saved_output_info *output_info = ptr;
-  output_info[section->index].offset = section->output_offset;
-  output_info[section->index].section = section->output_section;
-  section->output_offset = 0;
-  section->output_section = section;
+  struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
+  struct saved_output_info *output_info;
+
+  output_info = &saved_offsets->sections[section->index];
+  output_info->offset = section->output_offset;
+  output_info->section = section->output_section;
+  if ((section->flags & SEC_DEBUGGING) != 0
+      || section->output_section == NULL)
+    {
+      section->output_offset = 0;
+      section->output_section = section;
+    }
 }
 
 static void
@@ -101,9 +140,15 @@ simple_restore_output_info (bfd *abfd ATTRIBUTE_UNUSED,
                            asection *section,
                            void *ptr)
 {
-  struct saved_output_info *output_info = ptr;
-  section->output_offset = output_info[section->index].offset;
-  section->output_section = output_info[section->index].section;
+  struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
+  struct saved_output_info *output_info;
+
+  if (section->index >= saved_offsets->section_count)
+    return;
+
+  output_info = &saved_offsets->sections[section->index];
+  section->output_offset = output_info->offset;
+  section->output_section = output_info->section;
 }
 
 /*
@@ -117,13 +162,10 @@ SYNOPSIS
 DESCRIPTION
        Returns the relocated contents of section @var{sec}.  The symbols in
        @var{symbol_table} will be used, or the symbols from @var{abfd} if
-       @var{symbol_table} is NULL.  The output offsets for all sections will
+       @var{symbol_table} is NULL.  The output offsets for debug sections will
        be temporarily reset to 0.  The result will be stored at @var{outbuf}
        or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}.
 
-       Generally all sections in @var{abfd} should have their
-       @code{output_section} pointing back to the original section.
-
        Returns @code{NULL} on a fatal error; ignores errors applying
        particular relocations.
 */
@@ -139,43 +181,18 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
   struct bfd_link_callbacks callbacks;
   bfd_byte *contents, *data;
   int storage_needed;
-  void *saved_offsets;
-  bfd_boolean saved_reloc_done = sec->reloc_done;
-
-#undef RETURN
-#define RETURN(x)                              \
-  do                                           \
-    {                                          \
-      sec->reloc_done = saved_reloc_done;      \
-      return (x);                              \
-    }                                          \
-  while (0)
-
-  /* Foul hack to prevent bfd_section_size aborts.  The reloc_done flag
-     only controls that macro (and the related size macros), selecting
-     between _raw_size and _cooked_size.  We may be called with relocation
-     done or not, so we need to save the done-flag and mark the section as
-     not relocated.
-
-     Debug sections won't change size while we're only relocating.  There
-     may be trouble here someday if it tries to run relaxation
-     unexpectedly, so make sure.  */
-  BFD_ASSERT (sec->_raw_size == sec->_cooked_size);
-  sec->reloc_done = 0;
-
-  if (! (sec->flags & SEC_RELOC))
-    {
-      bfd_size_type size = bfd_section_size (abfd, sec);
-
-      if (outbuf == NULL)
-       contents = bfd_malloc (size);
-      else
-       contents = outbuf;
+  struct saved_offsets saved_offsets;
+  bfd *link_next;
 
-      if (contents)
-       bfd_get_section_contents (abfd, sec, contents, 0, size);
-
-      RETURN (contents);
+  /* Don't apply relocation on executable and shared library.  See
+     PR 4756.  */
+  if ((abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC)) != HAS_RELOC
+      || ! (sec->flags & SEC_RELOC))
+    {
+      contents = outbuf;
+      if (!bfd_get_full_section_contents (abfd, sec, &contents))
+       return NULL;
+      return contents;
     }
 
   /* In order to use bfd_get_relocated_section_contents, we need
@@ -183,57 +200,61 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
 
   /* Fill in the bare minimum number of fields for our purposes.  */
   memset (&link_info, 0, sizeof (link_info));
+  link_info.output_bfd = abfd;
   link_info.input_bfds = abfd;
+  link_info.input_bfds_tail = &abfd->link.next;
 
-  link_info.hash = bfd_link_hash_table_create (abfd);
+  link_next = abfd->link.next;
+  abfd->link.next = NULL;
+  link_info.hash = _bfd_generic_link_hash_table_create (abfd);
   link_info.callbacks = &callbacks;
   callbacks.warning = simple_dummy_warning;
   callbacks.undefined_symbol = simple_dummy_undefined_symbol;
   callbacks.reloc_overflow = simple_dummy_reloc_overflow;
   callbacks.reloc_dangerous = simple_dummy_reloc_dangerous;
   callbacks.unattached_reloc = simple_dummy_unattached_reloc;
+  callbacks.multiple_definition = simple_dummy_multiple_definition;
+  callbacks.einfo = simple_dummy_einfo;
 
   memset (&link_order, 0, sizeof (link_order));
   link_order.next = NULL;
   link_order.type = bfd_indirect_link_order;
   link_order.offset = 0;
-  link_order.size = bfd_section_size (abfd, sec);
+  link_order.size = sec->size;
   link_order.u.indirect.section = sec;
 
   data = NULL;
   if (outbuf == NULL)
     {
-      data = bfd_malloc (bfd_section_size (abfd, sec));
+      bfd_size_type amt = sec->rawsize > sec->size ? sec->rawsize : sec->size;
+      data = (bfd_byte *) bfd_malloc (amt);
       if (data == NULL)
-       RETURN (NULL);
+       {
+         _bfd_generic_link_hash_table_free (abfd);
+         abfd->link.next = link_next;
+         return NULL;
+       }
       outbuf = data;
     }
 
-  /* The sections in ABFD may already have output sections and offsets set.
-     Because this function is primarily for debug sections, and GCC uses the
-     knowledge that debug sections will generally have VMA 0 when emiting
-     relocations between DWARF-2 sections (which are supposed to be
-     section-relative offsets anyway), we need to reset the output offsets
-     to zero.  We also need to arrange for section->output_section->vma plus
-     section->output_offset to equal section->vma, which we do by setting
-     section->output_section to point back to section.  Save the original
-     output offset and output section to restore later.  */
-  saved_offsets = malloc (sizeof (struct saved_output_info)
-                         * abfd->section_count);
-  if (saved_offsets == NULL)
+  saved_offsets.section_count = abfd->section_count;
+  saved_offsets.sections = malloc (sizeof (*saved_offsets.sections)
+                                  * saved_offsets.section_count);
+  if (saved_offsets.sections == NULL)
     {
-      if (data)
-       free (data);
-      RETURN (NULL);
+      free (data);
+      _bfd_generic_link_hash_table_free (abfd);
+      abfd->link.next = link_next;
+      return NULL;
     }
-  bfd_map_over_sections (abfd, simple_save_output_info, saved_offsets);
+  bfd_map_over_sections (abfd, simple_save_output_info, &saved_offsets);
 
   if (symbol_table == NULL)
     {
       _bfd_generic_link_add_symbols (abfd, &link_info);
 
       storage_needed = bfd_get_symtab_upper_bound (abfd);
-      symbol_table = bfd_malloc (storage_needed);
+      symbol_table = (asymbol **) bfd_malloc (storage_needed);
       bfd_canonicalize_symtab (abfd, symbol_table);
     }
   else
@@ -245,27 +266,13 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
                                                 outbuf,
                                                 0,
                                                 symbol_table);
-  if (contents == NULL && data != NULL)
+  if (contents == NULL)
     free (data);
 
-#if 0
-  /* NOTE: cagney/2003-04-05: This free, which was introduced on
-     2003-03-31 to stop a memory leak, caused a memory corruption
-     between GDB and BFD.  The problem, which is stabs specific, can
-     be identified by a bunch of failures in relocate.exp vis:
-
-       gdb.base/relocate.exp: get address of static_bar
-
-     Details of the problem can be found on the binutils@ mailing
-     list, see the discussion thread: "gdb.mi/mi-cli.exp failures".  */
-  if (storage_needed != 0)
-    free (symbol_table);
-#endif
-
-  bfd_map_over_sections (abfd, simple_restore_output_info, saved_offsets);
-  free (saved_offsets);
-
-  bfd_link_hash_table_free (abfd, link_info.hash);
+  bfd_map_over_sections (abfd, simple_restore_output_info, &saved_offsets);
+  free (saved_offsets.sections);
 
-  RETURN (contents);
+  _bfd_generic_link_hash_table_free (abfd);
+  abfd->link.next = link_next;
+  return contents;
 }
This page took 0.028424 seconds and 4 git commands to generate.