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