Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/bfd/simple.c
Line
Count
Source (jump to first uncovered line)
1
/* simple.c -- BFD simple client routines
2
   Copyright (C) 2002-2025 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
#include "genlink.h"
27
28
static void
29
simple_dummy_add_to_set (struct bfd_link_info * info ATTRIBUTE_UNUSED,
30
       struct bfd_link_hash_entry *entry ATTRIBUTE_UNUSED,
31
       bfd_reloc_code_real_type reloc ATTRIBUTE_UNUSED,
32
       bfd *abfd ATTRIBUTE_UNUSED,
33
       asection *sec ATTRIBUTE_UNUSED,
34
       bfd_vma value ATTRIBUTE_UNUSED)
35
0
{
36
0
}
37
38
static  void
39
simple_dummy_constructor (struct bfd_link_info * info ATTRIBUTE_UNUSED,
40
        bool constructor ATTRIBUTE_UNUSED,
41
        const char *name ATTRIBUTE_UNUSED,
42
        bfd *abfd ATTRIBUTE_UNUSED,
43
        asection *sec ATTRIBUTE_UNUSED,
44
        bfd_vma value ATTRIBUTE_UNUSED)
45
0
{
46
0
}
47
48
static void
49
simple_dummy_multiple_common (struct bfd_link_info * info ATTRIBUTE_UNUSED,
50
            struct bfd_link_hash_entry * entry ATTRIBUTE_UNUSED,
51
            bfd * abfd ATTRIBUTE_UNUSED,
52
            enum bfd_link_hash_type type ATTRIBUTE_UNUSED,
53
            bfd_vma size ATTRIBUTE_UNUSED)
54
0
{
55
0
}
56
57
static void
58
simple_dummy_warning (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
59
          const char *warning ATTRIBUTE_UNUSED,
60
          const char *symbol ATTRIBUTE_UNUSED,
61
          bfd *abfd ATTRIBUTE_UNUSED,
62
          asection *section ATTRIBUTE_UNUSED,
63
          bfd_vma address ATTRIBUTE_UNUSED)
64
0
{
65
0
}
66
67
static void
68
simple_dummy_undefined_symbol (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
69
             const char *name ATTRIBUTE_UNUSED,
70
             bfd *abfd ATTRIBUTE_UNUSED,
71
             asection *section ATTRIBUTE_UNUSED,
72
             bfd_vma address ATTRIBUTE_UNUSED,
73
             bool fatal ATTRIBUTE_UNUSED)
74
2.86k
{
75
2.86k
}
76
77
static void
78
simple_dummy_reloc_overflow (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
79
           struct bfd_link_hash_entry *entry ATTRIBUTE_UNUSED,
80
           const char *name ATTRIBUTE_UNUSED,
81
           const char *reloc_name ATTRIBUTE_UNUSED,
82
           bfd_vma addend ATTRIBUTE_UNUSED,
83
           bfd *abfd ATTRIBUTE_UNUSED,
84
           asection *section ATTRIBUTE_UNUSED,
85
           bfd_vma address ATTRIBUTE_UNUSED)
86
2.70k
{
87
2.70k
}
88
89
static void
90
simple_dummy_reloc_dangerous (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
91
            const char *message ATTRIBUTE_UNUSED,
92
            bfd *abfd ATTRIBUTE_UNUSED,
93
            asection *section ATTRIBUTE_UNUSED,
94
            bfd_vma address ATTRIBUTE_UNUSED)
95
1.75k
{
96
1.75k
}
97
98
static void
99
simple_dummy_unattached_reloc (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
100
             const char *name ATTRIBUTE_UNUSED,
101
             bfd *abfd ATTRIBUTE_UNUSED,
102
             asection *section ATTRIBUTE_UNUSED,
103
             bfd_vma address ATTRIBUTE_UNUSED)
104
0
{
105
0
}
106
107
static void
108
simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
109
          struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
110
          bfd *nbfd ATTRIBUTE_UNUSED,
111
          asection *nsec ATTRIBUTE_UNUSED,
112
          bfd_vma nval ATTRIBUTE_UNUSED)
113
0
{
114
0
}
115
116
static void
117
simple_dummy_einfo (const char *fmt ATTRIBUTE_UNUSED, ...)
118
1.36k
{
119
1.36k
}
120
121
struct saved_output_info
122
{
123
  bfd_vma offset;
124
  asection *section;
125
};
126
127
struct saved_offsets
128
{
129
  unsigned int section_count;
130
  struct saved_output_info *sections;
131
};
132
133
/* The sections in ABFD may already have output sections and offsets
134
   set if we are here during linking.
135
136
   DWARF-2 specifies offsets into debug sections in many cases and
137
   bfd_simple_get_relocated_section_contents is called to relocate
138
   debug info for a single relocatable object file.  So we want
139
   offsets relative to that object file's sections, not offsets in the
140
   output file.  For that reason, reset a debug section->output_offset
141
   to zero.
142
143
   If not called during linking then set section->output_section to
144
   point back to the input section, because output_section must not be
145
   NULL when calling the relocation routines.
146
147
   Save the original output offset and section to restore later.  */
148
149
static void
150
simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED,
151
       asection *section,
152
       void *ptr)
153
414k
{
154
414k
  struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
155
414k
  struct saved_output_info *output_info;
156
157
414k
  output_info = &saved_offsets->sections[section->index];
158
414k
  output_info->offset = section->output_offset;
159
414k
  output_info->section = section->output_section;
160
414k
  if ((section->flags & SEC_DEBUGGING) != 0
161
414k
      || section->output_section == NULL)
162
414k
    {
163
414k
      section->output_offset = 0;
164
414k
      section->output_section = section;
165
414k
    }
166
414k
}
167
168
static void
169
simple_restore_output_info (bfd *abfd ATTRIBUTE_UNUSED,
170
          asection *section,
171
          void *ptr)
172
414k
{
173
414k
  struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
174
414k
  struct saved_output_info *output_info;
175
176
414k
  if (section->index >= saved_offsets->section_count)
177
0
    return;
178
179
414k
  output_info = &saved_offsets->sections[section->index];
180
414k
  section->output_offset = output_info->offset;
181
414k
  section->output_section = output_info->section;
182
414k
}
183
184
/*
185
FUNCTION
186
  bfd_simple_relocate_secton
187
188
SYNOPSIS
189
  bfd_byte *bfd_simple_get_relocated_section_contents
190
    (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
191
192
DESCRIPTION
193
  Returns the relocated contents of section @var{sec}.  The symbols in
194
  @var{symbol_table} will be used, or the symbols from @var{abfd} if
195
  @var{symbol_table} is NULL.  The output offsets for debug sections will
196
  be temporarily reset to 0.  The result will be stored at @var{outbuf}
197
  or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}.
198
199
  Returns @code{NULL} on a fatal error; ignores errors applying
200
  particular relocations.
201
*/
202
203
bfd_byte *
204
bfd_simple_get_relocated_section_contents (bfd *abfd,
205
             asection *sec,
206
             bfd_byte *outbuf,
207
             asymbol **symbol_table)
208
17.6k
{
209
17.6k
  struct bfd_link_info link_info;
210
17.6k
  struct bfd_link_order link_order;
211
17.6k
  struct bfd_link_callbacks callbacks;
212
17.6k
  bfd_byte *contents;
213
17.6k
  struct saved_offsets saved_offsets;
214
17.6k
  bfd *link_next;
215
216
  /* Don't apply relocation on executable and shared library.  See
217
     PR 4756.  */
218
17.6k
  if ((abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC)) != HAS_RELOC
219
17.6k
      || ! (sec->flags & SEC_RELOC))
220
12.0k
    {
221
12.0k
      if (!bfd_get_full_section_contents (abfd, sec, &outbuf))
222
169
  return NULL;
223
11.8k
      return outbuf;
224
12.0k
    }
225
226
  /* In order to use bfd_get_relocated_section_contents, we need
227
     to forge some data structures that it expects.  */
228
229
  /* Fill in the bare minimum number of fields for our purposes.  */
230
5.62k
  memset (&link_info, 0, sizeof (link_info));
231
5.62k
  link_info.output_bfd = abfd;
232
5.62k
  link_info.input_bfds = abfd;
233
5.62k
  link_info.input_bfds_tail = &abfd->link.next;
234
235
5.62k
  link_next = abfd->link.next;
236
5.62k
  abfd->link.next = NULL;
237
5.62k
  link_info.hash = _bfd_generic_link_hash_table_create (abfd);
238
5.62k
  link_info.callbacks = &callbacks;
239
  /* Make sure that any fields not initialised below do not
240
     result in a potential indirection via a random address.  */
241
5.62k
  memset (&callbacks, 0, sizeof callbacks);
242
5.62k
  callbacks.warning = simple_dummy_warning;
243
5.62k
  callbacks.undefined_symbol = simple_dummy_undefined_symbol;
244
5.62k
  callbacks.reloc_overflow = simple_dummy_reloc_overflow;
245
5.62k
  callbacks.reloc_dangerous = simple_dummy_reloc_dangerous;
246
5.62k
  callbacks.unattached_reloc = simple_dummy_unattached_reloc;
247
5.62k
  callbacks.multiple_definition = simple_dummy_multiple_definition;
248
5.62k
  callbacks.einfo = simple_dummy_einfo;
249
5.62k
  callbacks.multiple_common = simple_dummy_multiple_common;
250
5.62k
  callbacks.constructor = simple_dummy_constructor;
251
5.62k
  callbacks.add_to_set = simple_dummy_add_to_set;
252
253
5.62k
  memset (&link_order, 0, sizeof (link_order));
254
5.62k
  link_order.next = NULL;
255
5.62k
  link_order.type = bfd_indirect_link_order;
256
5.62k
  link_order.offset = 0;
257
5.62k
  link_order.size = sec->size;
258
5.62k
  link_order.u.indirect.section = sec;
259
260
5.62k
  contents = NULL;
261
262
5.62k
  saved_offsets.section_count = abfd->section_count;
263
5.62k
  saved_offsets.sections = malloc (sizeof (*saved_offsets.sections)
264
5.62k
           * saved_offsets.section_count);
265
5.62k
  if (saved_offsets.sections == NULL)
266
0
    goto out1;
267
5.62k
  bfd_map_over_sections (abfd, simple_save_output_info, &saved_offsets);
268
269
5.62k
  if (symbol_table == NULL)
270
1.81k
    {
271
1.81k
      if (!bfd_generic_link_read_symbols (abfd))
272
560
  goto out2;
273
1.25k
      symbol_table = _bfd_generic_link_get_symbols (abfd);
274
1.25k
    }
275
276
5.06k
  contents = bfd_get_relocated_section_contents (abfd,
277
5.06k
             &link_info,
278
5.06k
             &link_order,
279
5.06k
             outbuf,
280
5.06k
             false,
281
5.06k
             symbol_table);
282
5.62k
 out2:
283
5.62k
  bfd_map_over_sections (abfd, simple_restore_output_info, &saved_offsets);
284
5.62k
  free (saved_offsets.sections);
285
5.62k
 out1:
286
5.62k
  _bfd_generic_link_hash_table_free (abfd);
287
5.62k
  abfd->link.next = link_next;
288
5.62k
  return contents;
289
5.62k
}