Coverage Report

Created: 2024-05-21 06:29

/src/binutils-gdb/bfd/pef.c
Line
Count
Source (jump to first uncovered line)
1
/* PEF support for BFD.
2
   Copyright (C) 1999-2024 Free Software Foundation, Inc.
3
4
   This file is part of BFD, the Binary File Descriptor library.
5
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
21
/* PEF (Preferred Executable Format) is the binary file format for late
22
   classic Mac OS versions (before Darwin).  It is supported by both m68k
23
   and PowerPc.  It is also called CFM (Code Fragment Manager).  */
24
25
#include "sysdep.h"
26
#include "safe-ctype.h"
27
#include "pef.h"
28
#include "pef-traceback.h"
29
#include "bfd.h"
30
#include "libbfd.h"
31
#include "libiberty.h"
32
33
#ifndef BFD_IO_FUNCS
34
3.40k
#define BFD_IO_FUNCS 0
35
#endif
36
37
#define bfd_pef_close_and_cleanup       _bfd_generic_close_and_cleanup
38
#define bfd_pef_bfd_free_cached_info        _bfd_generic_bfd_free_cached_info
39
#define bfd_pef_new_section_hook        _bfd_generic_new_section_hook
40
#define bfd_pef_bfd_is_local_label_name       bfd_generic_is_local_label_name
41
#define bfd_pef_bfd_is_target_special_symbol        _bfd_bool_bfd_asymbol_false
42
#define bfd_pef_get_lineno          _bfd_nosymbols_get_lineno
43
#define bfd_pef_find_nearest_line       _bfd_nosymbols_find_nearest_line
44
#define bfd_pef_find_nearest_line_with_alt      _bfd_nosymbols_find_nearest_line_with_alt
45
#define bfd_pef_find_line         _bfd_nosymbols_find_line
46
#define bfd_pef_find_inliner_info       _bfd_nosymbols_find_inliner_info
47
#define bfd_pef_get_symbol_version_string     _bfd_nosymbols_get_symbol_version_string
48
#define bfd_pef_bfd_make_debug_symbol       _bfd_nosymbols_bfd_make_debug_symbol
49
#define bfd_pef_read_minisymbols        _bfd_generic_read_minisymbols
50
#define bfd_pef_minisymbol_to_symbol        _bfd_generic_minisymbol_to_symbol
51
#define bfd_pef_set_arch_mach         _bfd_generic_set_arch_mach
52
#define bfd_pef_get_section_contents        _bfd_generic_get_section_contents
53
#define bfd_pef_set_section_contents        _bfd_generic_set_section_contents
54
#define bfd_pef_bfd_get_relocated_section_contents  bfd_generic_get_relocated_section_contents
55
#define bfd_pef_bfd_relax_section       bfd_generic_relax_section
56
#define bfd_pef_bfd_gc_sections         bfd_generic_gc_sections
57
#define bfd_pef_bfd_lookup_section_flags      bfd_generic_lookup_section_flags
58
#define bfd_pef_bfd_merge_sections        bfd_generic_merge_sections
59
#define bfd_pef_bfd_is_group_section        bfd_generic_is_group_section
60
#define bfd_pef_bfd_group_name          bfd_generic_group_name
61
#define bfd_pef_bfd_discard_group       bfd_generic_discard_group
62
#define bfd_pef_section_already_linked        _bfd_generic_section_already_linked
63
#define bfd_pef_bfd_define_common_symbol      bfd_generic_define_common_symbol
64
#define bfd_pef_bfd_link_hide_symbol        _bfd_generic_link_hide_symbol
65
#define bfd_pef_bfd_define_start_stop       bfd_generic_define_start_stop
66
#define bfd_pef_bfd_link_hash_table_create      _bfd_generic_link_hash_table_create
67
#define bfd_pef_bfd_link_add_symbols        _bfd_generic_link_add_symbols
68
#define bfd_pef_bfd_link_just_syms        _bfd_generic_link_just_syms
69
#define bfd_pef_bfd_copy_link_hash_symbol_type \
70
  _bfd_generic_copy_link_hash_symbol_type
71
#define bfd_pef_bfd_final_link          _bfd_generic_final_link
72
#define bfd_pef_bfd_link_split_section        _bfd_generic_link_split_section
73
#define bfd_pef_bfd_link_check_relocs       _bfd_generic_link_check_relocs
74
75
static int
76
bfd_pef_parse_traceback_table (bfd *abfd,
77
             asection *section,
78
             unsigned char *buf,
79
             size_t len,
80
             size_t pos,
81
             asymbol *sym,
82
             FILE *file)
83
359k
{
84
359k
  struct traceback_table table;
85
359k
  size_t offset;
86
359k
  const char *s;
87
359k
  asymbol tmpsymbol;
88
89
359k
  if (sym == NULL)
90
0
    sym = & tmpsymbol;
91
92
359k
  sym->name = NULL;
93
359k
  sym->value = 0;
94
359k
  sym->the_bfd = abfd;
95
359k
  sym->section = section;
96
359k
  sym->flags = 0;
97
359k
  sym->udata.i = 0;
98
99
  /* memcpy is fine since all fields are unsigned char.  */
100
359k
  if ((pos + 8) > len)
101
138
    return -1;
102
359k
  memcpy (&table, buf + pos, 8);
103
104
  /* Calling code relies on returned symbols having a name and
105
     correct offset.  */
106
359k
  if ((table.lang != TB_C) && (table.lang != TB_CPLUSPLUS))
107
98.3k
    return -1;
108
109
260k
  if (! (table.flags2 & TB_NAME_PRESENT))
110
233k
    return -1;
111
112
26.6k
  if (! (table.flags1 & TB_HAS_TBOFF))
113
10.1k
    return -1;
114
115
16.5k
  offset = 8;
116
117
16.5k
  if ((table.flags5 & TB_FLOATPARAMS) || (table.fixedparams))
118
14.8k
    offset += 4;
119
120
16.5k
  if (table.flags1 & TB_HAS_TBOFF)
121
16.5k
    {
122
16.5k
      struct traceback_table_tboff off;
123
124
16.5k
      if ((pos + offset + 4) > len)
125
6
  return -1;
126
16.4k
      off.tb_offset = bfd_getb32 (buf + pos + offset);
127
16.4k
      offset += 4;
128
129
      /* Need to subtract 4 because the offset includes the 0x0L
130
   preceding the table.  */
131
16.4k
      if (file != NULL)
132
0
  fprintf (file, " [offset = 0x%lx]", off.tb_offset);
133
134
16.4k
      if ((file == NULL) && ((off.tb_offset + 4) > (pos + offset)))
135
4.66k
  return -1;
136
137
11.8k
      sym->value = pos - off.tb_offset - 4;
138
11.8k
    }
139
140
11.8k
  if (table.flags2 & TB_INT_HNDL)
141
5.02k
    offset += 4;
142
143
11.8k
  if (table.flags1 & TB_HAS_CTL)
144
6.13k
    {
145
6.13k
      struct traceback_table_anchors anchors;
146
147
6.13k
      if ((pos + offset + 4) > len)
148
8
  return -1;
149
6.12k
      anchors.ctl_info = bfd_getb32 (buf + pos + offset);
150
6.12k
      offset += 4;
151
152
6.12k
      if (anchors.ctl_info > 1024)
153
2.64k
  return -1;
154
155
3.48k
      offset += anchors.ctl_info * 4;
156
3.48k
    }
157
158
9.17k
  if (table.flags2 & TB_NAME_PRESENT)
159
9.17k
    {
160
9.17k
      struct traceback_table_routine name;
161
9.17k
      char *namebuf;
162
163
9.17k
      if ((pos + offset + 2) > len)
164
34
  return -1;
165
9.14k
      name.name_len = bfd_getb16 (buf + pos + offset);
166
9.14k
      offset += 2;
167
168
9.14k
      if (name.name_len > 4096)
169
138
  return -1;
170
171
9.00k
      if ((pos + offset + name.name_len) > len)
172
66
  return -1;
173
174
8.93k
      namebuf = bfd_alloc (abfd, name.name_len + 1);
175
8.93k
      if (namebuf == NULL)
176
0
  return -1;
177
178
8.93k
      memcpy (namebuf, buf + pos + offset, name.name_len);
179
8.93k
      namebuf[name.name_len] = '\0';
180
181
      /* Strip leading period inserted by compiler.  */
182
8.93k
      if (namebuf[0] == '.')
183
97
  memmove (namebuf, namebuf + 1, name.name_len);
184
185
8.93k
      sym->name = namebuf;
186
187
9.81k
      for (s = sym->name; (*s != '\0'); s++)
188
4.03k
  if (! ISPRINT (*s))
189
3.16k
    return -1;
190
191
5.77k
      offset += name.name_len;
192
5.77k
    }
193
194
5.77k
  if (table.flags2 & TB_USES_ALLOCA)
195
3.71k
    offset += 4;
196
197
5.77k
  if (table.flags4 & TB_HAS_VEC_INFO)
198
1.42k
    offset += 4;
199
200
5.77k
  if (file != NULL)
201
0
    fprintf (file, " [length = 0x%lx]", (unsigned long) offset);
202
203
5.77k
  return offset;
204
9.17k
}
205
206
static void
207
bfd_pef_print_symbol (bfd *abfd,
208
          void * afile,
209
          asymbol *symbol,
210
          bfd_print_symbol_type how)
211
0
{
212
0
  FILE *file = (FILE *) afile;
213
214
0
  switch (how)
215
0
    {
216
0
    case bfd_print_symbol_name:
217
0
      fprintf (file, "%s", symbol->name);
218
0
      break;
219
0
    default:
220
0
      bfd_print_symbol_vandf (abfd, (void *) file, symbol);
221
0
      fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
222
0
      if (startswith (symbol->name, "__traceback_"))
223
0
  {
224
0
    unsigned char *buf;
225
0
    size_t offset = symbol->value + 4;
226
0
    size_t len = symbol->udata.i;
227
228
0
    buf = bfd_malloc (len);
229
0
    if (buf == NULL
230
0
        || !bfd_get_section_contents (abfd, symbol->section, buf,
231
0
              offset, len)
232
0
        || bfd_pef_parse_traceback_table (abfd, symbol->section, buf,
233
0
            len, 0, NULL, file) < 0)
234
0
      fprintf (file, " [ERROR]");
235
0
    free (buf);
236
0
  }
237
0
    }
238
0
}
239
240
static void
241
bfd_pef_convert_architecture (unsigned long architecture,
242
            enum bfd_architecture *type,
243
            unsigned long *subtype)
244
3.89k
{
245
3.89k
  const unsigned long ARCH_POWERPC = 0x70777063; /* 'pwpc'.  */
246
3.89k
  const unsigned long ARCH_M68K = 0x6d36386b; /* 'm68k'.  */
247
248
3.89k
  *subtype = bfd_arch_unknown;
249
3.89k
  *type = bfd_arch_unknown;
250
251
3.89k
  if (architecture == ARCH_POWERPC)
252
1.49k
    *type = bfd_arch_powerpc;
253
2.40k
  else if (architecture == ARCH_M68K)
254
1.91k
    *type = bfd_arch_m68k;
255
3.89k
}
256
257
static bool
258
bfd_pef_mkobject (bfd *abfd ATTRIBUTE_UNUSED)
259
0
{
260
0
  return true;
261
0
}
262
263
static const char *bfd_pef_section_name (bfd_pef_section *section)
264
86.9k
{
265
86.9k
  switch (section->section_kind)
266
86.9k
    {
267
29.0k
    case BFD_PEF_SECTION_CODE: return "code";
268
1.57k
    case BFD_PEF_SECTION_UNPACKED_DATA: return "unpacked-data";
269
2.33k
    case BFD_PEF_SECTION_PACKED_DATA: return "packed-data";
270
170
    case BFD_PEF_SECTION_CONSTANT: return "constant";
271
1.11k
    case BFD_PEF_SECTION_LOADER: return "loader";
272
899
    case BFD_PEF_SECTION_DEBUG: return "debug";
273
186
    case BFD_PEF_SECTION_EXEC_DATA: return "exec-data";
274
123
    case BFD_PEF_SECTION_EXCEPTION: return "exception";
275
634
    case BFD_PEF_SECTION_TRACEBACK: return "traceback";
276
50.8k
    default: return "unknown";
277
86.9k
    }
278
86.9k
}
279
280
static unsigned long bfd_pef_section_flags (bfd_pef_section *section)
281
86.9k
{
282
86.9k
  switch (section->section_kind)
283
86.9k
    {
284
29.0k
    case BFD_PEF_SECTION_CODE:
285
29.0k
      return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
286
1.57k
    case BFD_PEF_SECTION_UNPACKED_DATA:
287
3.90k
    case BFD_PEF_SECTION_PACKED_DATA:
288
4.07k
    case BFD_PEF_SECTION_CONSTANT:
289
5.18k
    case BFD_PEF_SECTION_LOADER:
290
6.08k
    case BFD_PEF_SECTION_DEBUG:
291
6.27k
    case BFD_PEF_SECTION_EXEC_DATA:
292
6.39k
    case BFD_PEF_SECTION_EXCEPTION:
293
7.03k
    case BFD_PEF_SECTION_TRACEBACK:
294
57.9k
    default:
295
57.9k
      return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
296
86.9k
    }
297
86.9k
}
298
299
static asection *
300
bfd_pef_make_bfd_section (bfd *abfd, bfd_pef_section *section)
301
86.9k
{
302
86.9k
  asection *bfdsec;
303
86.9k
  const char *name = bfd_pef_section_name (section);
304
305
86.9k
  bfdsec = bfd_make_section_anyway (abfd, name);
306
86.9k
  if (bfdsec == NULL)
307
0
    return NULL;
308
309
86.9k
  bfdsec->vma = section->default_address + section->container_offset;
310
86.9k
  bfdsec->lma = section->default_address + section->container_offset;
311
86.9k
  bfdsec->size = section->container_length;
312
86.9k
  bfdsec->filepos = section->container_offset;
313
86.9k
  bfdsec->alignment_power = section->alignment;
314
315
86.9k
  bfdsec->flags = bfd_pef_section_flags (section);
316
317
86.9k
  return bfdsec;
318
86.9k
}
319
320
int
321
bfd_pef_parse_loader_header (bfd *abfd ATTRIBUTE_UNUSED,
322
           unsigned char *buf,
323
           size_t len,
324
           bfd_pef_loader_header *header)
325
395
{
326
395
  BFD_ASSERT (len == 56);
327
328
395
  header->main_section = bfd_getb32 (buf);
329
395
  header->main_offset = bfd_getb32 (buf + 4);
330
395
  header->init_section = bfd_getb32 (buf + 8);
331
395
  header->init_offset = bfd_getb32 (buf + 12);
332
395
  header->term_section = bfd_getb32 (buf + 16);
333
395
  header->term_offset = bfd_getb32 (buf + 20);
334
395
  header->imported_library_count = bfd_getb32 (buf + 24);
335
395
  header->total_imported_symbol_count = bfd_getb32 (buf + 28);
336
395
  header->reloc_section_count = bfd_getb32 (buf + 32);
337
395
  header->reloc_instr_offset = bfd_getb32 (buf + 36);
338
395
  header->loader_strings_offset = bfd_getb32 (buf + 40);
339
395
  header->export_hash_offset = bfd_getb32 (buf + 44);
340
395
  header->export_hash_table_power = bfd_getb32 (buf + 48);
341
395
  header->exported_symbol_count = bfd_getb32 (buf + 52);
342
343
395
  return 0;
344
395
}
345
346
int
347
bfd_pef_parse_imported_library (bfd *abfd ATTRIBUTE_UNUSED,
348
        unsigned char *buf,
349
        size_t len,
350
        bfd_pef_imported_library *header)
351
9
{
352
9
  BFD_ASSERT (len == 24);
353
354
9
  header->name_offset = bfd_getb32 (buf);
355
9
  header->old_implementation_version = bfd_getb32 (buf + 4);
356
9
  header->current_version = bfd_getb32 (buf + 8);
357
9
  header->imported_symbol_count = bfd_getb32 (buf + 12);
358
9
  header->first_imported_symbol = bfd_getb32 (buf + 16);
359
9
  header->options = buf[20];
360
9
  header->reserved_a = buf[21];
361
9
  header->reserved_b = bfd_getb16 (buf + 22);
362
363
9
  return 0;
364
9
}
365
366
int
367
bfd_pef_parse_imported_symbol (bfd *abfd ATTRIBUTE_UNUSED,
368
             unsigned char *buf,
369
             size_t len,
370
             bfd_pef_imported_symbol *symbol)
371
6
{
372
6
  unsigned long value;
373
374
6
  BFD_ASSERT (len == 4);
375
376
6
  value = bfd_getb32 (buf);
377
6
  symbol->symbol_class = value >> 24;
378
6
  symbol->name = value & 0x00ffffff;
379
380
6
  return 0;
381
6
}
382
383
int
384
bfd_pef_scan_section (bfd *abfd, bfd_pef_section *section)
385
87.7k
{
386
87.7k
  unsigned char buf[28];
387
388
87.7k
  if (bfd_seek (abfd, section->header_offset, SEEK_SET) != 0
389
87.7k
      || bfd_read (buf, 28, abfd) != 28)
390
752
    return -1;
391
392
86.9k
  section->name_offset = bfd_h_get_32 (abfd, buf);
393
86.9k
  section->default_address = bfd_h_get_32 (abfd, buf + 4);
394
86.9k
  section->total_length = bfd_h_get_32 (abfd, buf + 8);
395
86.9k
  section->unpacked_length = bfd_h_get_32 (abfd, buf + 12);
396
86.9k
  section->container_length = bfd_h_get_32 (abfd, buf + 16);
397
86.9k
  section->container_offset = bfd_h_get_32 (abfd, buf + 20);
398
86.9k
  section->section_kind = buf[24];
399
86.9k
  section->share_kind = buf[25];
400
86.9k
  section->alignment = buf[26];
401
86.9k
  section->reserved = buf[27];
402
403
86.9k
  section->bfd_section = bfd_pef_make_bfd_section (abfd, section);
404
86.9k
  if (section->bfd_section == NULL)
405
0
    return -1;
406
407
86.9k
  return 0;
408
86.9k
}
409
410
void
411
bfd_pef_print_loader_header (bfd *abfd ATTRIBUTE_UNUSED,
412
           bfd_pef_loader_header *header,
413
           FILE *file)
414
0
{
415
0
  fprintf (file, "main_section: %ld\n", header->main_section);
416
0
  fprintf (file, "main_offset: %lu\n", header->main_offset);
417
0
  fprintf (file, "init_section: %ld\n", header->init_section);
418
0
  fprintf (file, "init_offset: %lu\n", header->init_offset);
419
0
  fprintf (file, "term_section: %ld\n", header->term_section);
420
0
  fprintf (file, "term_offset: %lu\n", header->term_offset);
421
0
  fprintf (file, "imported_library_count: %lu\n",
422
0
     header->imported_library_count);
423
0
  fprintf (file, "total_imported_symbol_count: %lu\n",
424
0
     header->total_imported_symbol_count);
425
0
  fprintf (file, "reloc_section_count: %lu\n", header->reloc_section_count);
426
0
  fprintf (file, "reloc_instr_offset: %lu\n", header->reloc_instr_offset);
427
0
  fprintf (file, "loader_strings_offset: %lu\n",
428
0
     header->loader_strings_offset);
429
0
  fprintf (file, "export_hash_offset: %lu\n", header->export_hash_offset);
430
0
  fprintf (file, "export_hash_table_power: %lu\n",
431
0
     header->export_hash_table_power);
432
0
  fprintf (file, "exported_symbol_count: %lu\n",
433
0
     header->exported_symbol_count);
434
0
}
435
436
int
437
bfd_pef_print_loader_section (bfd *abfd, FILE *file)
438
0
{
439
0
  bfd_pef_loader_header header;
440
0
  asection *loadersec = NULL;
441
0
  unsigned char *loaderbuf = NULL;
442
0
  size_t loaderlen = 0;
443
444
0
  loadersec = bfd_get_section_by_name (abfd, "loader");
445
0
  if (loadersec == NULL)
446
0
    return -1;
447
448
0
  loaderlen = loadersec->size;
449
0
  if (loaderlen < 56)
450
0
    return -1;
451
0
  if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) != 0)
452
0
    return -1;
453
0
  loaderbuf = _bfd_malloc_and_read (abfd, loaderlen, loaderlen);
454
0
  if (loaderbuf == NULL)
455
0
    return -1;
456
457
0
  if (bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header) < 0)
458
0
    {
459
0
      free (loaderbuf);
460
0
      return -1;
461
0
    }
462
463
0
  bfd_pef_print_loader_header (abfd, &header, file);
464
0
  return 0;
465
0
}
466
467
int
468
bfd_pef_scan_start_address (bfd *abfd)
469
2.65k
{
470
2.65k
  bfd_pef_loader_header header;
471
2.65k
  asection *section;
472
473
2.65k
  asection *loadersec = NULL;
474
2.65k
  unsigned char *loaderbuf = NULL;
475
2.65k
  size_t loaderlen = 0;
476
2.65k
  int ret;
477
478
2.65k
  loadersec = bfd_get_section_by_name (abfd, "loader");
479
2.65k
  if (loadersec == NULL)
480
2.07k
    goto end;
481
482
580
  loaderlen = loadersec->size;
483
580
  if (loaderlen < 56)
484
12
    goto error;
485
568
  if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) != 0)
486
0
    goto error;
487
568
  loaderbuf = _bfd_malloc_and_read (abfd, loaderlen, loaderlen);
488
568
  if (loaderbuf == NULL)
489
191
    goto error;
490
491
377
  ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
492
377
  if (ret < 0)
493
0
    goto error;
494
495
377
  if (header.main_section < 0)
496
0
    goto end;
497
498
27.9k
  for (section = abfd->sections; section != NULL; section = section->next)
499
27.8k
    if ((long) (section->index + 1) == header.main_section)
500
279
      break;
501
502
377
  if (section == NULL)
503
98
    goto error;
504
505
279
  abfd->start_address = section->vma + header.main_offset;
506
507
2.35k
 end:
508
2.35k
  free (loaderbuf);
509
2.35k
  return 0;
510
511
301
 error:
512
301
  free (loaderbuf);
513
301
  return -1;
514
279
}
515
516
int
517
bfd_pef_scan (bfd *abfd,
518
        bfd_pef_header *header,
519
        bfd_pef_data_struct *mdata)
520
3.89k
{
521
3.89k
  unsigned int i;
522
3.89k
  enum bfd_architecture cputype;
523
3.89k
  unsigned long cpusubtype;
524
525
3.89k
  mdata->header = *header;
526
527
3.89k
  bfd_pef_convert_architecture (header->architecture, &cputype, &cpusubtype);
528
3.89k
  if (cputype == bfd_arch_unknown)
529
491
    {
530
491
      _bfd_error_handler (_("bfd_pef_scan: unknown architecture 0x%lx"),
531
491
        header->architecture);
532
491
      return -1;
533
491
    }
534
3.40k
  bfd_set_arch_mach (abfd, cputype, cpusubtype);
535
536
3.40k
  mdata->header = *header;
537
538
3.40k
  abfd->flags = (abfd->xvec->object_flags
539
3.40k
     | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
540
541
3.40k
  if (header->section_count != 0)
542
2.81k
    {
543
2.81k
      mdata->sections = bfd_alloc (abfd, header->section_count * sizeof (bfd_pef_section));
544
545
2.81k
      if (mdata->sections == NULL)
546
0
  return -1;
547
548
89.8k
      for (i = 0; i < header->section_count; i++)
549
87.7k
  {
550
87.7k
    bfd_pef_section *cur = &mdata->sections[i];
551
87.7k
    cur->header_offset = 40 + (i * 28);
552
87.7k
    if (bfd_pef_scan_section (abfd, cur) < 0)
553
752
      return -1;
554
87.7k
  }
555
2.81k
    }
556
557
2.65k
  if (bfd_pef_scan_start_address (abfd) < 0)
558
301
    return -1;
559
560
2.35k
  abfd->tdata.pef_data = mdata;
561
562
2.35k
  return 0;
563
2.65k
}
564
565
static int
566
bfd_pef_read_header (bfd *abfd, bfd_pef_header *header)
567
1.70M
{
568
1.70M
  unsigned char buf[40];
569
570
1.70M
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
571
1.70M
      || bfd_read (buf, 40, abfd) != 40)
572
86.9k
    return -1;
573
574
1.61M
  header->tag1 = bfd_getb32 (buf);
575
1.61M
  header->tag2 = bfd_getb32 (buf + 4);
576
1.61M
  header->architecture = bfd_getb32 (buf + 8);
577
1.61M
  header->format_version = bfd_getb32 (buf + 12);
578
1.61M
  header->timestamp = bfd_getb32 (buf + 16);
579
1.61M
  header->old_definition_version = bfd_getb32 (buf + 20);
580
1.61M
  header->old_implementation_version = bfd_getb32 (buf + 24);
581
1.61M
  header->current_version = bfd_getb32 (buf + 28);
582
1.61M
  header->section_count = bfd_getb32 (buf + 32) + 1;
583
1.61M
  header->instantiated_section_count = bfd_getb32 (buf + 34);
584
1.61M
  header->reserved = bfd_getb32 (buf + 36);
585
586
1.61M
  return 0;
587
1.70M
}
588
589
static bfd_cleanup
590
bfd_pef_object_p (bfd *abfd)
591
1.70M
{
592
1.70M
  bfd_pef_header header;
593
1.70M
  bfd_pef_data_struct *mdata;
594
595
1.70M
  if (bfd_pef_read_header (abfd, &header) != 0)
596
86.9k
    goto wrong;
597
598
1.61M
  if (header.tag1 != BFD_PEF_TAG1 || header.tag2 != BFD_PEF_TAG2)
599
1.61M
    goto wrong;
600
601
3.89k
  mdata = (bfd_pef_data_struct *) bfd_zalloc (abfd, sizeof (*mdata));
602
3.89k
  if (mdata == NULL)
603
0
    goto fail;
604
605
3.89k
  if (bfd_pef_scan (abfd, &header, mdata))
606
1.54k
    goto wrong;
607
608
2.35k
  return _bfd_no_cleanup;
609
610
1.69M
 wrong:
611
1.69M
  bfd_set_error (bfd_error_wrong_format);
612
613
1.69M
 fail:
614
1.69M
  return NULL;
615
1.69M
}
616
617
static int
618
bfd_pef_parse_traceback_tables (bfd *abfd,
619
        asection *sec,
620
        unsigned char *buf,
621
        size_t len,
622
        long *nsym,
623
        asymbol **csym)
624
531
{
625
531
  char *name;
626
627
531
  asymbol function;
628
531
  asymbol traceback;
629
630
531
  const char *const tbprefix = "__traceback_";
631
531
  size_t tbnamelen;
632
633
531
  size_t pos = 0;
634
531
  unsigned long count = 0;
635
531
  int ret;
636
637
531
  for (;;)
638
359k
    {
639
      /* We're reading symbols two at a time.  */
640
359k
      if (csym && ((csym[count] == NULL) || (csym[count + 1] == NULL)))
641
177
  break;
642
643
359k
      pos += 3;
644
359k
      pos -= (pos % 4);
645
646
1.23M
      while ((pos + 4) <= len)
647
1.23M
  {
648
1.23M
    if (bfd_getb32 (buf + pos) == 0)
649
359k
      break;
650
872k
    pos += 4;
651
872k
  }
652
653
359k
      if ((pos + 4) > len)
654
354
  break;
655
656
359k
      ret = bfd_pef_parse_traceback_table (abfd, sec, buf, len, pos + 4,
657
359k
             &function, 0);
658
359k
      if (ret < 0)
659
353k
  {
660
    /* Skip over 0x0L to advance to next possible traceback table.  */
661
353k
    pos += 4;
662
353k
    continue;
663
353k
  }
664
665
5.77k
      BFD_ASSERT (function.name != NULL);
666
667
      /* Don't bother to compute the name if we are just
668
   counting symbols.  */
669
5.77k
      if (csym)
670
1.92k
  {
671
1.92k
    tbnamelen = strlen (tbprefix) + strlen (function.name);
672
1.92k
    name = bfd_alloc (abfd, tbnamelen + 1);
673
1.92k
    if (name == NULL)
674
0
      {
675
0
        bfd_release (abfd, (void *) function.name);
676
0
        function.name = NULL;
677
0
        break;
678
0
      }
679
1.92k
    snprintf (name, tbnamelen + 1, "%s%s", tbprefix, function.name);
680
1.92k
    traceback.name = name;
681
1.92k
    traceback.value = pos;
682
1.92k
    traceback.the_bfd = abfd;
683
1.92k
    traceback.section = sec;
684
1.92k
    traceback.flags = 0;
685
1.92k
    traceback.udata.i = ret;
686
687
1.92k
    *(csym[count]) = function;
688
1.92k
    *(csym[count + 1]) = traceback;
689
1.92k
  }
690
691
5.77k
      pos += ret;
692
5.77k
      count += 2;
693
5.77k
    }
694
695
531
  *nsym = count;
696
531
  return 0;
697
531
}
698
699
static int
700
bfd_pef_parse_function_stub (bfd *abfd ATTRIBUTE_UNUSED,
701
           unsigned char *buf,
702
           size_t len,
703
           unsigned long *offset)
704
0
{
705
0
  BFD_ASSERT (len == 24);
706
707
0
  if ((bfd_getb32 (buf) & 0xffff0000) != 0x81820000)
708
0
    return -1;
709
0
  if (bfd_getb32 (buf + 4) != 0x90410014)
710
0
    return -1;
711
0
  if (bfd_getb32 (buf + 8) != 0x800c0000)
712
0
    return -1;
713
0
  if (bfd_getb32 (buf + 12) != 0x804c0004)
714
0
    return -1;
715
0
  if (bfd_getb32 (buf + 16) != 0x7c0903a6)
716
0
    return -1;
717
0
  if (bfd_getb32 (buf + 20) != 0x4e800420)
718
0
    return -1;
719
720
0
  if (offset != NULL)
721
0
    *offset = (bfd_getb32 (buf) & 0x0000ffff) / 4;
722
723
0
  return 0;
724
0
}
725
726
static int
727
bfd_pef_parse_function_stubs (bfd *abfd,
728
            asection *codesec,
729
            unsigned char *codebuf,
730
            size_t codelen,
731
            unsigned char *loaderbuf,
732
            size_t loaderlen,
733
            unsigned long *nsym,
734
            asymbol **csym)
735
18
{
736
18
  const char *const sprefix = "__stub_";
737
18
  size_t codepos = 0;
738
18
  unsigned long count = 0;
739
18
  bfd_pef_loader_header header;
740
18
  bfd_pef_imported_library *libraries = NULL;
741
18
  bfd_pef_imported_symbol *imports = NULL;
742
18
  unsigned long i;
743
18
  int ret;
744
745
18
  if (loaderlen < 56)
746
0
    goto error;
747
748
18
  ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
749
18
  if (ret < 0)
750
0
    goto error;
751
752
18
  if ((loaderlen - 56) / 24 < header.imported_library_count)
753
9
    goto error;
754
755
9
  if ((loaderlen - 56 - header.imported_library_count * 24) / 4
756
9
      < header.total_imported_symbol_count)
757
3
    goto error;
758
759
6
  libraries = bfd_malloc
760
6
    (header.imported_library_count * sizeof (bfd_pef_imported_library));
761
6
  imports = bfd_malloc
762
6
    (header.total_imported_symbol_count * sizeof (bfd_pef_imported_symbol));
763
6
  if (libraries == NULL || imports == NULL)
764
0
    goto error;
765
766
15
  for (i = 0; i < header.imported_library_count; i++)
767
9
    {
768
9
      ret = bfd_pef_parse_imported_library
769
9
  (abfd, loaderbuf + 56 + (i * 24), 24, &libraries[i]);
770
9
      if (ret < 0)
771
0
  goto error;
772
9
    }
773
774
12
  for (i = 0; i < header.total_imported_symbol_count; i++)
775
6
    {
776
6
      ret = (bfd_pef_parse_imported_symbol
777
6
       (abfd,
778
6
        loaderbuf + 56 + (header.imported_library_count * 24) + (i * 4),
779
6
        4, &imports[i]));
780
6
      if (ret < 0)
781
0
  goto error;
782
6
    }
783
784
6
  codepos = 0;
785
786
6
  for (;;)
787
6
    {
788
6
      asymbol sym;
789
6
      const char *symname;
790
6
      char *name;
791
6
      unsigned long sym_index;
792
793
6
      if (csym && (csym[count] == NULL))
794
2
  break;
795
796
4
      codepos += 3;
797
4
      codepos -= (codepos % 4);
798
799
4
      while ((codepos + 4) <= codelen)
800
0
  {
801
0
    if ((bfd_getb32 (codebuf + codepos) & 0xffff0000) == 0x81820000)
802
0
      break;
803
0
    codepos += 4;
804
0
  }
805
806
4
      if ((codepos + 24) > codelen)
807
4
  break;
808
809
0
      ret = bfd_pef_parse_function_stub (abfd, codebuf + codepos, 24, &sym_index);
810
0
      if (ret < 0)
811
0
  {
812
0
    codepos += 24;
813
0
    continue;
814
0
  }
815
816
0
      if (sym_index >= header.total_imported_symbol_count)
817
0
  {
818
0
    codepos += 24;
819
0
    continue;
820
0
  }
821
822
0
      {
823
0
  size_t max, namelen;
824
0
  const char *s;
825
826
0
  if (loaderlen < (header.loader_strings_offset + imports[sym_index].name))
827
0
    goto error;
828
829
0
  max = loaderlen - (header.loader_strings_offset + imports[sym_index].name);
830
0
  symname = (char *) loaderbuf;
831
0
  symname += header.loader_strings_offset + imports[sym_index].name;
832
0
  namelen = 0;
833
0
  for (s = symname; s < (symname + max); s++)
834
0
    {
835
0
      if (*s == '\0')
836
0
        break;
837
0
      if (! ISPRINT (*s))
838
0
        goto error;
839
0
      namelen++;
840
0
    }
841
0
  if (*s != '\0')
842
0
    goto error;
843
844
0
  name = bfd_alloc (abfd, strlen (sprefix) + namelen + 1);
845
0
  if (name == NULL)
846
0
    break;
847
848
0
  snprintf (name, strlen (sprefix) + namelen + 1, "%s%s",
849
0
      sprefix, symname);
850
0
  sym.name = name;
851
0
      }
852
853
0
      sym.value = codepos;
854
0
      sym.the_bfd = abfd;
855
0
      sym.section = codesec;
856
0
      sym.flags = 0;
857
0
      sym.udata.i = 0;
858
859
0
      codepos += 24;
860
861
0
      if (csym != NULL)
862
0
  *(csym[count]) = sym;
863
864
0
      count++;
865
0
    }
866
867
6
  goto end;
868
869
6
 end:
870
6
  free (libraries);
871
6
  free (imports);
872
6
  *nsym = count;
873
6
  return 0;
874
875
12
 error:
876
12
  free (libraries);
877
12
  free (imports);
878
12
  *nsym = count;
879
12
  return -1;
880
6
}
881
882
static long
883
bfd_pef_parse_symbols (bfd *abfd, asymbol **csym)
884
657
{
885
657
  unsigned long count = 0;
886
887
657
  asection *codesec = NULL;
888
657
  unsigned char *codebuf = NULL;
889
657
  size_t codelen = 0;
890
891
657
  asection *loadersec = NULL;
892
657
  unsigned char *loaderbuf = NULL;
893
657
  size_t loaderlen = 0;
894
895
657
  codesec = bfd_get_section_by_name (abfd, "code");
896
657
  if (codesec != NULL)
897
615
    {
898
615
      codelen = codesec->size;
899
615
      if (bfd_seek (abfd, codesec->filepos, SEEK_SET) != 0)
900
0
  goto end;
901
615
      codebuf = _bfd_malloc_and_read (abfd, codelen, codelen);
902
615
      if (codebuf == NULL)
903
84
  goto end;
904
615
    }
905
906
573
  loadersec = bfd_get_section_by_name (abfd, "loader");
907
573
  if (loadersec != NULL)
908
24
    {
909
24
      loaderlen = loadersec->size;
910
24
      if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) != 0)
911
0
  goto end;
912
24
      loaderbuf = _bfd_malloc_and_read (abfd, loaderlen, loaderlen);
913
24
      if (loaderbuf == NULL)
914
0
  goto end;
915
24
    }
916
917
573
  count = 0;
918
573
  if (codesec != NULL)
919
531
    {
920
531
      long ncount = 0;
921
531
      bfd_pef_parse_traceback_tables (abfd, codesec, codebuf, codelen,
922
531
              &ncount, csym);
923
531
      count += ncount;
924
531
    }
925
926
573
  if ((codesec != NULL) && (loadersec != NULL))
927
18
    {
928
18
      unsigned long ncount = 0;
929
18
      bfd_pef_parse_function_stubs
930
18
  (abfd, codesec, codebuf, codelen, loaderbuf, loaderlen, &ncount,
931
18
   (csym != NULL) ? (csym + count) : NULL);
932
18
      count += ncount;
933
18
    }
934
935
573
  if (csym != NULL)
936
191
    csym[count] = NULL;
937
938
657
 end:
939
657
  free (codebuf);
940
657
  free (loaderbuf);
941
657
  return count;
942
573
}
943
944
static long
945
bfd_pef_count_symbols (bfd *abfd)
946
438
{
947
438
  return bfd_pef_parse_symbols (abfd, NULL);
948
438
}
949
950
static long
951
bfd_pef_get_symtab_upper_bound (bfd *abfd)
952
219
{
953
219
  long nsyms = bfd_pef_count_symbols (abfd);
954
955
219
  if (nsyms < 0)
956
0
    return nsyms;
957
219
  return ((nsyms + 1) * sizeof (asymbol *));
958
219
}
959
960
static long
961
bfd_pef_canonicalize_symtab (bfd *abfd, asymbol **alocation)
962
219
{
963
219
  long i;
964
219
  asymbol *syms;
965
219
  long ret;
966
219
  long nsyms = bfd_pef_count_symbols (abfd);
967
968
219
  if (nsyms < 0)
969
0
    return nsyms;
970
971
219
  syms = bfd_alloc (abfd, nsyms * sizeof (asymbol));
972
219
  if (syms == NULL)
973
0
    return -1;
974
975
4.07k
  for (i = 0; i < nsyms; i++)
976
3.85k
    alocation[i] = &syms[i];
977
978
219
  alocation[nsyms] = NULL;
979
980
219
  ret = bfd_pef_parse_symbols (abfd, alocation);
981
219
  if (ret != nsyms)
982
0
    return 0;
983
984
219
  return ret;
985
219
}
986
987
#define bfd_pef_make_empty_symbol _bfd_generic_make_empty_symbol
988
989
static void
990
bfd_pef_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
991
       asymbol *symbol,
992
       symbol_info *ret)
993
0
{
994
0
  bfd_symbol_info (symbol, ret);
995
0
}
996
997
static int
998
bfd_pef_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
999
      struct bfd_link_info *info ATTRIBUTE_UNUSED)
1000
0
{
1001
0
  return 0;
1002
0
}
1003
1004
const bfd_target pef_vec =
1005
{
1006
  "pef",      /* Name.  */
1007
  bfd_target_pef_flavour, /* Flavour.  */
1008
  BFD_ENDIAN_BIG,   /* Byteorder.  */
1009
  BFD_ENDIAN_BIG,   /* Header_byteorder.  */
1010
  (HAS_RELOC | EXEC_P |   /* Object flags.  */
1011
   HAS_LINENO | HAS_DEBUG |
1012
   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1013
  (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
1014
   | SEC_ROM | SEC_HAS_CONTENTS), /* Section_flags.  */
1015
  0,        /* Symbol_leading_char.  */
1016
  ' ',        /* AR_pad_char.  */
1017
  16,       /* AR_max_namelen.  */
1018
  0,        /* match priority.  */
1019
  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
1020
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1021
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1022
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data.  */
1023
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1024
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1025
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers.  */
1026
  {       /* bfd_check_format.  */
1027
    _bfd_dummy_target,
1028
    bfd_pef_object_p,   /* bfd_check_format.  */
1029
    _bfd_dummy_target,
1030
    _bfd_dummy_target,
1031
  },
1032
  {       /* bfd_set_format.  */
1033
    _bfd_bool_bfd_false_error,
1034
    bfd_pef_mkobject,
1035
    _bfd_bool_bfd_false_error,
1036
    _bfd_bool_bfd_false_error,
1037
  },
1038
  {       /* bfd_write_contents.  */
1039
    _bfd_bool_bfd_false_error,
1040
    _bfd_bool_bfd_true,
1041
    _bfd_bool_bfd_false_error,
1042
    _bfd_bool_bfd_false_error,
1043
  },
1044
1045
  BFD_JUMP_TABLE_GENERIC (bfd_pef),
1046
  BFD_JUMP_TABLE_COPY (_bfd_generic),
1047
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
1048
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1049
  BFD_JUMP_TABLE_SYMBOLS (bfd_pef),
1050
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
1051
  BFD_JUMP_TABLE_WRITE (bfd_pef),
1052
  BFD_JUMP_TABLE_LINK (bfd_pef),
1053
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1054
1055
  NULL,
1056
1057
  NULL
1058
};
1059
1060
#define bfd_pef_xlib_close_and_cleanup        _bfd_generic_close_and_cleanup
1061
#define bfd_pef_xlib_bfd_free_cached_info     _bfd_generic_bfd_free_cached_info
1062
#define bfd_pef_xlib_new_section_hook       _bfd_generic_new_section_hook
1063
#define bfd_pef_xlib_get_section_contents     _bfd_generic_get_section_contents
1064
#define bfd_pef_xlib_set_section_contents     _bfd_generic_set_section_contents
1065
#define bfd_pef_xlib_set_section_contents_in_window _bfd_generic_set_section_contents_in_window
1066
1067
static int
1068
bfd_pef_xlib_read_header (bfd *abfd, bfd_pef_xlib_header *header)
1069
1.70M
{
1070
1.70M
  unsigned char buf[80];
1071
1072
1.70M
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
1073
1.70M
      || bfd_read (buf, sizeof buf, abfd) != sizeof buf)
1074
261k
    return -1;
1075
1076
1.43M
  header->tag1 = bfd_getb32 (buf);
1077
1.43M
  header->tag2 = bfd_getb32 (buf + 4);
1078
1.43M
  header->current_format = bfd_getb32 (buf + 8);
1079
1.43M
  header->container_strings_offset = bfd_getb32 (buf + 12);
1080
1.43M
  header->export_hash_offset = bfd_getb32 (buf + 16);
1081
1.43M
  header->export_key_offset = bfd_getb32 (buf + 20);
1082
1.43M
  header->export_symbol_offset = bfd_getb32 (buf + 24);
1083
1.43M
  header->export_names_offset = bfd_getb32 (buf + 28);
1084
1.43M
  header->export_hash_table_power = bfd_getb32 (buf + 32);
1085
1.43M
  header->exported_symbol_count = bfd_getb32 (buf + 36);
1086
1.43M
  header->frag_name_offset = bfd_getb32 (buf + 40);
1087
1.43M
  header->frag_name_length = bfd_getb32 (buf + 44);
1088
1.43M
  header->dylib_path_offset = bfd_getb32 (buf + 48);
1089
1.43M
  header->dylib_path_length = bfd_getb32 (buf + 52);
1090
1.43M
  header->cpu_family = bfd_getb32 (buf + 56);
1091
1.43M
  header->cpu_model = bfd_getb32 (buf + 60);
1092
1.43M
  header->date_time_stamp = bfd_getb32 (buf + 64);
1093
1.43M
  header->current_version = bfd_getb32 (buf + 68);
1094
1.43M
  header->old_definition_version = bfd_getb32 (buf + 72);
1095
1.43M
  header->old_implementation_version = bfd_getb32 (buf + 76);
1096
1097
1.43M
  return 0;
1098
1.70M
}
1099
1100
static int
1101
bfd_pef_xlib_scan (bfd *abfd, bfd_pef_xlib_header *header)
1102
2
{
1103
2
  bfd_pef_xlib_data_struct *mdata = NULL;
1104
1105
2
  mdata = bfd_alloc (abfd, sizeof (* mdata));
1106
2
  if (mdata == NULL)
1107
0
    return -1;
1108
1109
2
  mdata->header = *header;
1110
1111
2
  abfd->flags = (abfd->xvec->object_flags
1112
2
     | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1113
1114
2
  abfd->tdata.pef_xlib_data = mdata;
1115
1116
2
  return 0;
1117
2
}
1118
1119
static bfd_cleanup
1120
bfd_pef_xlib_object_p (bfd *abfd)
1121
1.70M
{
1122
1.70M
  bfd_pef_xlib_header header;
1123
1124
1.70M
  if (bfd_pef_xlib_read_header (abfd, &header) != 0)
1125
261k
    {
1126
261k
      bfd_set_error (bfd_error_wrong_format);
1127
261k
      return NULL;
1128
261k
    }
1129
1130
1.43M
  if ((header.tag1 != BFD_PEF_XLIB_TAG1)
1131
1.43M
      || ((header.tag2 != BFD_PEF_VLIB_TAG2)
1132
7
    && (header.tag2 != BFD_PEF_BLIB_TAG2)))
1133
1.43M
    {
1134
1.43M
      bfd_set_error (bfd_error_wrong_format);
1135
1.43M
      return NULL;
1136
1.43M
    }
1137
1138
2
  if (bfd_pef_xlib_scan (abfd, &header) != 0)
1139
0
    {
1140
0
      bfd_set_error (bfd_error_wrong_format);
1141
0
      return NULL;
1142
0
    }
1143
1144
2
  return _bfd_no_cleanup;
1145
2
}
1146
1147
const bfd_target pef_xlib_vec =
1148
{
1149
  "pef-xlib",     /* Name.  */
1150
  bfd_target_pef_xlib_flavour,  /* Flavour.  */
1151
  BFD_ENDIAN_BIG,   /* Byteorder */
1152
  BFD_ENDIAN_BIG,   /* Header_byteorder.  */
1153
  (HAS_RELOC | EXEC_P |   /* Object flags.  */
1154
   HAS_LINENO | HAS_DEBUG |
1155
   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1156
  (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
1157
   | SEC_ROM | SEC_HAS_CONTENTS),/* Section_flags.  */
1158
  0,        /* Symbol_leading_char.  */
1159
  ' ',        /* AR_pad_char.  */
1160
  16,       /* AR_max_namelen.  */
1161
  0,        /* match priority.  */
1162
  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
1163
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1164
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1165
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data.  */
1166
  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1167
  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1168
  bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers.  */
1169
  {       /* bfd_check_format.  */
1170
    _bfd_dummy_target,
1171
    bfd_pef_xlib_object_p,  /* bfd_check_format.  */
1172
    _bfd_dummy_target,
1173
    _bfd_dummy_target,
1174
  },
1175
  {       /* bfd_set_format.  */
1176
    _bfd_bool_bfd_false_error,
1177
    bfd_pef_mkobject,
1178
    _bfd_bool_bfd_false_error,
1179
    _bfd_bool_bfd_false_error,
1180
  },
1181
  {       /* bfd_write_contents.  */
1182
    _bfd_bool_bfd_false_error,
1183
    _bfd_bool_bfd_true,
1184
    _bfd_bool_bfd_false_error,
1185
    _bfd_bool_bfd_false_error,
1186
  },
1187
1188
  BFD_JUMP_TABLE_GENERIC (bfd_pef_xlib),
1189
  BFD_JUMP_TABLE_COPY (_bfd_generic),
1190
  BFD_JUMP_TABLE_CORE (_bfd_nocore),
1191
  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1192
  BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
1193
  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
1194
  BFD_JUMP_TABLE_WRITE (_bfd_nowrite),
1195
  BFD_JUMP_TABLE_LINK (_bfd_nolink),
1196
  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1197
1198
  NULL,
1199
1200
  NULL
1201
};