Coverage Report

Created: 2023-08-28 06:30

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