Subversion Repositories Kolibri OS

Rev

Rev 5197 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* simple.c -- BFD simple client routines
  2.    Copyright (C) 2002-2015 Free Software Foundation, Inc.
  3.    Contributed by MontaVista Software, Inc.
  4.  
  5.    This file is part of BFD, the Binary File Descriptor library.
  6.  
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 3 of the License, or
  10.    (at your option) any later version.
  11.  
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  20.    MA 02110-1301, USA.  */
  21.  
  22. #include "sysdep.h"
  23. #include "bfd.h"
  24. #include "libbfd.h"
  25. #include "bfdlink.h"
  26.  
  27. static bfd_boolean
  28. simple_dummy_warning (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  29.                       const char *warning ATTRIBUTE_UNUSED,
  30.                       const char *symbol ATTRIBUTE_UNUSED,
  31.                       bfd *abfd ATTRIBUTE_UNUSED,
  32.                       asection *section ATTRIBUTE_UNUSED,
  33.                       bfd_vma address ATTRIBUTE_UNUSED)
  34. {
  35.   return TRUE;
  36. }
  37.  
  38. static bfd_boolean
  39. simple_dummy_undefined_symbol (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  40.                                const char *name ATTRIBUTE_UNUSED,
  41.                                bfd *abfd ATTRIBUTE_UNUSED,
  42.                                asection *section ATTRIBUTE_UNUSED,
  43.                                bfd_vma address ATTRIBUTE_UNUSED,
  44.                                bfd_boolean fatal ATTRIBUTE_UNUSED)
  45. {
  46.   return TRUE;
  47. }
  48.  
  49. static bfd_boolean
  50. simple_dummy_reloc_overflow (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  51.                              struct bfd_link_hash_entry *entry ATTRIBUTE_UNUSED,
  52.                              const char *name ATTRIBUTE_UNUSED,
  53.                              const char *reloc_name ATTRIBUTE_UNUSED,
  54.                              bfd_vma addend ATTRIBUTE_UNUSED,
  55.                              bfd *abfd ATTRIBUTE_UNUSED,
  56.                              asection *section ATTRIBUTE_UNUSED,
  57.                              bfd_vma address ATTRIBUTE_UNUSED)
  58. {
  59.   return TRUE;
  60. }
  61.  
  62. static bfd_boolean
  63. simple_dummy_reloc_dangerous (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  64.                               const char *message ATTRIBUTE_UNUSED,
  65.                               bfd *abfd ATTRIBUTE_UNUSED,
  66.                               asection *section ATTRIBUTE_UNUSED,
  67.                               bfd_vma address ATTRIBUTE_UNUSED)
  68. {
  69.   return TRUE;
  70. }
  71.  
  72. static bfd_boolean
  73. simple_dummy_unattached_reloc (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  74.                                const char *name ATTRIBUTE_UNUSED,
  75.                                bfd *abfd ATTRIBUTE_UNUSED,
  76.                                asection *section ATTRIBUTE_UNUSED,
  77.                                bfd_vma address ATTRIBUTE_UNUSED)
  78. {
  79.   return TRUE;
  80. }
  81.  
  82. static bfd_boolean
  83. simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
  84.                                   struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
  85.                                   bfd *nbfd ATTRIBUTE_UNUSED,
  86.                                   asection *nsec ATTRIBUTE_UNUSED,
  87.                                   bfd_vma nval ATTRIBUTE_UNUSED)
  88. {
  89.   return TRUE;
  90. }
  91.  
  92. static void
  93. simple_dummy_einfo (const char *fmt ATTRIBUTE_UNUSED, ...)
  94. {
  95. }
  96.  
  97. struct saved_output_info
  98. {
  99.   bfd_vma offset;
  100.   asection *section;
  101. };
  102.  
  103. struct saved_offsets
  104. {
  105.   unsigned int section_count;
  106.   struct saved_output_info *sections;
  107. };
  108.  
  109. /* The sections in ABFD may already have output sections and offsets
  110.    set if we are here during linking.
  111.  
  112.    DWARF-2 specifies offsets into debug sections in many cases and
  113.    bfd_simple_get_relocated_section_contents is called to relocate
  114.    debug info for a single relocatable object file.  So we want
  115.    offsets relative to that object file's sections, not offsets in the
  116.    output file.  For that reason, reset a debug section->output_offset
  117.    to zero.
  118.  
  119.    If not called during linking then set section->output_section to
  120.    point back to the input section, because output_section must not be
  121.    NULL when calling the relocation routines.
  122.  
  123.    Save the original output offset and section to restore later.  */
  124.  
  125. static void
  126. simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED,
  127.                          asection *section,
  128.                          void *ptr)
  129. {
  130.   struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
  131.   struct saved_output_info *output_info;
  132.  
  133.   output_info = &saved_offsets->sections[section->index];
  134.   output_info->offset = section->output_offset;
  135.   output_info->section = section->output_section;
  136.   if ((section->flags & SEC_DEBUGGING) != 0
  137.       || section->output_section == NULL)
  138.     {
  139.       section->output_offset = 0;
  140.       section->output_section = section;
  141.     }
  142. }
  143.  
  144. static void
  145. simple_restore_output_info (bfd *abfd ATTRIBUTE_UNUSED,
  146.                             asection *section,
  147.                             void *ptr)
  148. {
  149.   struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
  150.   struct saved_output_info *output_info;
  151.  
  152.   if (section->index >= saved_offsets->section_count)
  153.     return;
  154.  
  155.   output_info = &saved_offsets->sections[section->index];
  156.   section->output_offset = output_info->offset;
  157.   section->output_section = output_info->section;
  158. }
  159.  
  160. /*
  161. FUNCTION
  162.         bfd_simple_relocate_secton
  163.  
  164. SYNOPSIS
  165.         bfd_byte *bfd_simple_get_relocated_section_contents
  166.           (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
  167.  
  168. DESCRIPTION
  169.         Returns the relocated contents of section @var{sec}.  The symbols in
  170.         @var{symbol_table} will be used, or the symbols from @var{abfd} if
  171.         @var{symbol_table} is NULL.  The output offsets for debug sections will
  172.         be temporarily reset to 0.  The result will be stored at @var{outbuf}
  173.         or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}.
  174.  
  175.         Returns @code{NULL} on a fatal error; ignores errors applying
  176.         particular relocations.
  177. */
  178.  
  179. bfd_byte *
  180. bfd_simple_get_relocated_section_contents (bfd *abfd,
  181.                                            asection *sec,
  182.                                            bfd_byte *outbuf,
  183.                                            asymbol **symbol_table)
  184. {
  185.   struct bfd_link_info link_info;
  186.   struct bfd_link_order link_order;
  187.   struct bfd_link_callbacks callbacks;
  188.   bfd_byte *contents, *data;
  189.   int storage_needed;
  190.   struct saved_offsets saved_offsets;
  191.   bfd *link_next;
  192.  
  193.   /* Don't apply relocation on executable and shared library.  See
  194.      PR 4756.  */
  195.   if ((abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC)) != HAS_RELOC
  196.       || ! (sec->flags & SEC_RELOC))
  197.     {
  198.       contents = outbuf;
  199.       if (!bfd_get_full_section_contents (abfd, sec, &contents))
  200.         return NULL;
  201.       return contents;
  202.     }
  203.  
  204.   /* In order to use bfd_get_relocated_section_contents, we need
  205.      to forge some data structures that it expects.  */
  206.  
  207.   /* Fill in the bare minimum number of fields for our purposes.  */
  208.   memset (&link_info, 0, sizeof (link_info));
  209.   link_info.output_bfd = abfd;
  210.   link_info.input_bfds = abfd;
  211.   link_info.input_bfds_tail = &abfd->link.next;
  212.  
  213.   link_next = abfd->link.next;
  214.   abfd->link.next = NULL;
  215.   link_info.hash = _bfd_generic_link_hash_table_create (abfd);
  216.   link_info.callbacks = &callbacks;
  217.   callbacks.warning = simple_dummy_warning;
  218.   callbacks.undefined_symbol = simple_dummy_undefined_symbol;
  219.   callbacks.reloc_overflow = simple_dummy_reloc_overflow;
  220.   callbacks.reloc_dangerous = simple_dummy_reloc_dangerous;
  221.   callbacks.unattached_reloc = simple_dummy_unattached_reloc;
  222.   callbacks.multiple_definition = simple_dummy_multiple_definition;
  223.   callbacks.einfo = simple_dummy_einfo;
  224.  
  225.   memset (&link_order, 0, sizeof (link_order));
  226.   link_order.next = NULL;
  227.   link_order.type = bfd_indirect_link_order;
  228.   link_order.offset = 0;
  229.   link_order.size = sec->size;
  230.   link_order.u.indirect.section = sec;
  231.  
  232.   data = NULL;
  233.   if (outbuf == NULL)
  234.     {
  235.       bfd_size_type amt = sec->rawsize > sec->size ? sec->rawsize : sec->size;
  236.       data = (bfd_byte *) bfd_malloc (amt);
  237.       if (data == NULL)
  238.         {
  239.           _bfd_generic_link_hash_table_free (abfd);
  240.           abfd->link.next = link_next;
  241.         return NULL;
  242.         }
  243.       outbuf = data;
  244.     }
  245.  
  246.   saved_offsets.section_count = abfd->section_count;
  247.   saved_offsets.sections = malloc (sizeof (*saved_offsets.sections)
  248.                                    * saved_offsets.section_count);
  249.   if (saved_offsets.sections == NULL)
  250.     {
  251.       if (data)
  252.         free (data);
  253.       _bfd_generic_link_hash_table_free (abfd);
  254.       abfd->link.next = link_next;
  255.       return NULL;
  256.     }
  257.   bfd_map_over_sections (abfd, simple_save_output_info, &saved_offsets);
  258.  
  259.   if (symbol_table == NULL)
  260.     {
  261.       _bfd_generic_link_add_symbols (abfd, &link_info);
  262.  
  263.       storage_needed = bfd_get_symtab_upper_bound (abfd);
  264.       symbol_table = (asymbol **) bfd_malloc (storage_needed);
  265.       bfd_canonicalize_symtab (abfd, symbol_table);
  266.     }
  267.   else
  268.     storage_needed = 0;
  269.  
  270.   contents = bfd_get_relocated_section_contents (abfd,
  271.                                                  &link_info,
  272.                                                  &link_order,
  273.                                                  outbuf,
  274.                                                  0,
  275.                                                  symbol_table);
  276.   if (contents == NULL && data != NULL)
  277.     free (data);
  278.  
  279.   bfd_map_over_sections (abfd, simple_restore_output_info, &saved_offsets);
  280.   free (saved_offsets.sections);
  281.  
  282.   _bfd_generic_link_hash_table_free (abfd);
  283.   abfd->link.next = link_next;
  284.   return contents;
  285. }
  286.