Coverage Report

Created: 2026-10-02 09:53

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