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