Back to index

cell-binutils  2.17cvs20070401
simple.c
Go to the documentation of this file.
00001 /* simple.c -- BFD simple client routines
00002    Copyright 2002, 2003, 2004, 2005
00003    Free Software Foundation, Inc.
00004    Contributed by MontaVista Software, Inc.
00005 
00006    This file is part of BFD, the Binary File Descriptor library.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 #include "bfd.h"
00023 #include "sysdep.h"
00024 #include "libbfd.h"
00025 #include "bfdlink.h"
00026 
00027 static bfd_boolean
00028 simple_dummy_warning (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
00029                     const char *warning ATTRIBUTE_UNUSED,
00030                     const char *symbol ATTRIBUTE_UNUSED,
00031                     bfd *abfd ATTRIBUTE_UNUSED,
00032                     asection *section ATTRIBUTE_UNUSED,
00033                     bfd_vma address ATTRIBUTE_UNUSED)
00034 {
00035   return TRUE;
00036 }
00037 
00038 static bfd_boolean
00039 simple_dummy_undefined_symbol (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
00040                             const char *name ATTRIBUTE_UNUSED,
00041                             bfd *abfd ATTRIBUTE_UNUSED,
00042                             asection *section ATTRIBUTE_UNUSED,
00043                             bfd_vma address ATTRIBUTE_UNUSED,
00044                             bfd_boolean fatal ATTRIBUTE_UNUSED)
00045 {
00046   return TRUE;
00047 }
00048 
00049 static bfd_boolean
00050 simple_dummy_reloc_overflow (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
00051                           struct bfd_link_hash_entry *entry ATTRIBUTE_UNUSED,
00052                           const char *name ATTRIBUTE_UNUSED,
00053                           const char *reloc_name ATTRIBUTE_UNUSED,
00054                           bfd_vma addend ATTRIBUTE_UNUSED,
00055                           bfd *abfd ATTRIBUTE_UNUSED,
00056                           asection *section ATTRIBUTE_UNUSED,
00057                           bfd_vma address ATTRIBUTE_UNUSED)
00058 {
00059   return TRUE;
00060 }
00061 
00062 static bfd_boolean
00063 simple_dummy_reloc_dangerous (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
00064                            const char *message ATTRIBUTE_UNUSED,
00065                            bfd *abfd ATTRIBUTE_UNUSED,
00066                            asection *section ATTRIBUTE_UNUSED,
00067                            bfd_vma address ATTRIBUTE_UNUSED)
00068 {
00069   return TRUE;
00070 }
00071 
00072 static bfd_boolean
00073 simple_dummy_unattached_reloc (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
00074                             const char *name ATTRIBUTE_UNUSED,
00075                             bfd *abfd ATTRIBUTE_UNUSED,
00076                             asection *section ATTRIBUTE_UNUSED,
00077                             bfd_vma address ATTRIBUTE_UNUSED)
00078 {
00079   return TRUE;
00080 }
00081 
00082 static bfd_boolean
00083 simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
00084                               const char *name ATTRIBUTE_UNUSED,
00085                               bfd *obfd ATTRIBUTE_UNUSED,
00086                               asection *osec ATTRIBUTE_UNUSED,
00087                               bfd_vma oval ATTRIBUTE_UNUSED,
00088                               bfd *nbfd ATTRIBUTE_UNUSED,
00089                               asection *nsec ATTRIBUTE_UNUSED,
00090                               bfd_vma nval ATTRIBUTE_UNUSED)
00091 {
00092   return TRUE;
00093 }
00094 
00095 static void
00096 simple_dummy_einfo (const char *fmt ATTRIBUTE_UNUSED, ...)
00097 {
00098 }
00099 
00100 struct saved_output_info
00101 {
00102   bfd_vma offset;
00103   asection *section;
00104 };
00105 
00106 static void
00107 simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED,
00108                       asection *section,
00109                       void *ptr)
00110 {
00111   struct saved_output_info *output_info = ptr;
00112   output_info[section->index].offset = section->output_offset;
00113   output_info[section->index].section = section->output_section;
00114   if ((section->flags & SEC_DEBUGGING) != 0
00115       || section->output_section == NULL)
00116     {
00117       section->output_offset = 0;
00118       section->output_section = section;
00119     }
00120 }
00121 
00122 static void
00123 simple_restore_output_info (bfd *abfd ATTRIBUTE_UNUSED,
00124                          asection *section,
00125                          void *ptr)
00126 {
00127   struct saved_output_info *output_info = ptr;
00128   section->output_offset = output_info[section->index].offset;
00129   section->output_section = output_info[section->index].section;
00130 }
00131 
00132 /*
00133 FUNCTION
00134        bfd_simple_relocate_secton
00135 
00136 SYNOPSIS
00137        bfd_byte *bfd_simple_get_relocated_section_contents
00138          (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
00139 
00140 DESCRIPTION
00141        Returns the relocated contents of section @var{sec}.  The symbols in
00142        @var{symbol_table} will be used, or the symbols from @var{abfd} if
00143        @var{symbol_table} is NULL.  The output offsets for debug sections will
00144        be temporarily reset to 0.  The result will be stored at @var{outbuf}
00145        or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}.
00146 
00147        Returns @code{NULL} on a fatal error; ignores errors applying
00148        particular relocations.
00149 */
00150 
00151 bfd_byte *
00152 bfd_simple_get_relocated_section_contents (bfd *abfd,
00153                                       asection *sec,
00154                                       bfd_byte *outbuf,
00155                                       asymbol **symbol_table)
00156 {
00157   struct bfd_link_info link_info;
00158   struct bfd_link_order link_order;
00159   struct bfd_link_callbacks callbacks;
00160   bfd_byte *contents, *data;
00161   int storage_needed;
00162   void *saved_offsets;
00163 
00164   if (! (sec->flags & SEC_RELOC))
00165     {
00166       bfd_size_type amt = sec->rawsize > sec->size ? sec->rawsize : sec->size;
00167       bfd_size_type size = sec->rawsize ? sec->rawsize : sec->size;
00168 
00169       if (outbuf == NULL)
00170        contents = bfd_malloc (amt);
00171       else
00172        contents = outbuf;
00173 
00174       if (contents)
00175        bfd_get_section_contents (abfd, sec, contents, 0, size);
00176 
00177       return contents;
00178     }
00179 
00180   /* In order to use bfd_get_relocated_section_contents, we need
00181      to forge some data structures that it expects.  */
00182 
00183   /* Fill in the bare minimum number of fields for our purposes.  */
00184   memset (&link_info, 0, sizeof (link_info));
00185   link_info.input_bfds = abfd;
00186 
00187   link_info.hash = _bfd_generic_link_hash_table_create (abfd);
00188   link_info.callbacks = &callbacks;
00189   callbacks.warning = simple_dummy_warning;
00190   callbacks.undefined_symbol = simple_dummy_undefined_symbol;
00191   callbacks.reloc_overflow = simple_dummy_reloc_overflow;
00192   callbacks.reloc_dangerous = simple_dummy_reloc_dangerous;
00193   callbacks.unattached_reloc = simple_dummy_unattached_reloc;
00194   callbacks.multiple_definition = simple_dummy_multiple_definition;
00195   callbacks.einfo = simple_dummy_einfo;
00196 
00197   memset (&link_order, 0, sizeof (link_order));
00198   link_order.next = NULL;
00199   link_order.type = bfd_indirect_link_order;
00200   link_order.offset = 0;
00201   link_order.size = sec->size;
00202   link_order.u.indirect.section = sec;
00203 
00204   data = NULL;
00205   if (outbuf == NULL)
00206     {
00207       data = bfd_malloc (sec->size);
00208       if (data == NULL)
00209        return NULL;
00210       outbuf = data;
00211     }
00212 
00213   /* The sections in ABFD may already have output sections and offsets set.
00214      Because this function is primarily for debug sections, and GCC uses the
00215      knowledge that debug sections will generally have VMA 0 when emitting
00216      relocations between DWARF-2 sections (which are supposed to be
00217      section-relative offsets anyway), we need to reset the output offsets
00218      to zero.  We also need to arrange for section->output_section->vma plus
00219      section->output_offset to equal section->vma, which we do by setting
00220      section->output_section to point back to section.  Save the original
00221      output offset and output section to restore later.  */
00222   saved_offsets = malloc (sizeof (struct saved_output_info)
00223                        * abfd->section_count);
00224   if (saved_offsets == NULL)
00225     {
00226       if (data)
00227        free (data);
00228       return NULL;
00229     }
00230   bfd_map_over_sections (abfd, simple_save_output_info, saved_offsets);
00231 
00232   if (symbol_table == NULL)
00233     {
00234       _bfd_generic_link_add_symbols (abfd, &link_info);
00235 
00236       storage_needed = bfd_get_symtab_upper_bound (abfd);
00237       symbol_table = bfd_malloc (storage_needed);
00238       bfd_canonicalize_symtab (abfd, symbol_table);
00239     }
00240   else
00241     storage_needed = 0;
00242 
00243   contents = bfd_get_relocated_section_contents (abfd,
00244                                            &link_info,
00245                                            &link_order,
00246                                            outbuf,
00247                                            0,
00248                                            symbol_table);
00249   if (contents == NULL && data != NULL)
00250     free (data);
00251 
00252   bfd_map_over_sections (abfd, simple_restore_output_info, saved_offsets);
00253   free (saved_offsets);
00254 
00255   _bfd_generic_link_hash_table_free (link_info.hash);
00256   return contents;
00257 }