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