Coverage Report

Created: 2023-08-28 06:31

/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
1.55k
#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
674k
{
85
674k
  struct traceback_table table;
86
674k
  size_t offset;
87
674k
  const char *s;
88
674k
  asymbol tmpsymbol;
89
90
674k
  if (sym == NULL)
91
0
    sym = & tmpsymbol;
92
93
674k
  sym->name = NULL;
94
674k
  sym->value = 0;
95
674k
  sym->the_bfd = abfd;
96
674k
  sym->section = section;
97
674k
  sym->flags = 0;
98
674k
  sym->udata.i = 0;
99
100
  /* memcpy is fine since all fields are unsigned char.  */
101
674k
  if ((pos + 8) > len)
102
266
    return -1;
103
674k
  memcpy (&table, buf + pos, 8);
104
105
  /* Calling code relies on returned symbols having a name and
106
     correct offset.  */
107
674k
  if ((table.lang != TB_C) && (table.lang != TB_CPLUSPLUS))
108
127k
    return -1;
109
110
547k
  if (! (table.flags2 & TB_NAME_PRESENT))
111
502k
    return -1;
112
113
45.0k
  if (! (table.flags1 & TB_HAS_TBOFF))
114
24.0k
    return -1;
115
116
21.0k
  offset = 8;
117
118
21.0k
  if ((table.flags5 & TB_FLOATPARAMS) || (table.fixedparams))
119
18.9k
    offset += 4;
120
121
21.0k
  if (table.flags1 & TB_HAS_TBOFF)
122
21.0k
    {
123
21.0k
      struct traceback_table_tboff off;
124
125
21.0k
      if ((pos + offset + 4) > len)
126
20
  return -1;
127
21.0k
      off.tb_offset = bfd_getb32 (buf + pos + offset);
128
21.0k
      offset += 4;
129
130
      /* Need to subtract 4 because the offset includes the 0x0L
131
   preceding the table.  */
132
21.0k
      if (file != NULL)
133
0
  fprintf (file, " [offset = 0x%lx]", off.tb_offset);
134
135
21.0k
      if ((file == NULL) && ((off.tb_offset + 4) > (pos + offset)))
136
7.16k
  return -1;
137
138
13.8k
      sym->value = pos - off.tb_offset - 4;
139
13.8k
    }
140
141
13.8k
  if (table.flags2 & TB_INT_HNDL)
142
6.14k
    offset += 4;
143
144
13.8k
  if (table.flags1 & TB_HAS_CTL)
145
8.37k
    {
146
8.37k
      struct traceback_table_anchors anchors;
147
148
8.37k
      if ((pos + offset + 4) > len)
149
12
  return -1;
150
8.36k
      anchors.ctl_info = bfd_getb32 (buf + pos + offset);
151
8.36k
      offset += 4;
152
153
8.36k
      if (anchors.ctl_info > 1024)
154
2.96k
  return -1;
155
156
5.39k
      offset += anchors.ctl_info * 4;
157
5.39k
    }
158
159
10.8k
  if (table.flags2 & TB_NAME_PRESENT)
160
10.8k
    {
161
10.8k
      struct traceback_table_routine name;
162
10.8k
      char *namebuf;
163
164
10.8k
      if ((pos + offset + 2) > len)
165
66
  return -1;
166
10.8k
      name.name_len = bfd_getb16 (buf + pos + offset);
167
10.8k
      offset += 2;
168
169
10.8k
      if (name.name_len > 4096)
170
490
  return -1;
171
172
10.3k
      if ((pos + offset + name.name_len) > len)
173
69
  return -1;
174
175
10.2k
      namebuf = bfd_alloc (abfd, name.name_len + 1);
176
10.2k
      if (namebuf == NULL)
177
0
  return -1;
178
179
10.2k
      memcpy (namebuf, buf + pos + offset, name.name_len);
180
10.2k
      namebuf[name.name_len] = '\0';
181
182
      /* Strip leading period inserted by compiler.  */
183
10.2k
      if (namebuf[0] == '.')
184
71
  memmove (namebuf, namebuf + 1, name.name_len);
185
186
10.2k
      sym->name = namebuf;
187
188
11.5k
      for (s = sym->name; (*s != '\0'); s++)
189
3.76k
  if (! ISPRINT (*s))
190
2.47k
    return -1;
191
192
7.79k
      offset += name.name_len;
193
7.79k
    }
194
195
7.79k
  if (table.flags2 & TB_USES_ALLOCA)
196
5.67k
    offset += 4;
197
198
7.79k
  if (table.flags4 & TB_HAS_VEC_INFO)
199
2.93k
    offset += 4;
200
201
7.79k
  if (file != NULL)
202
0
    fprintf (file, " [length = 0x%lx]", (unsigned long) offset);
203
204
7.79k
  return offset;
205
10.8k
}
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
1.67k
{
246
1.67k
  const unsigned long ARCH_POWERPC = 0x70777063; /* 'pwpc'.  */
247
1.67k
  const unsigned long ARCH_M68K = 0x6d36386b; /* 'm68k'.  */
248
249
1.67k
  *subtype = bfd_arch_unknown;
250
1.67k
  *type = bfd_arch_unknown;
251
252
1.67k
  if (architecture == ARCH_POWERPC)
253
335
    *type = bfd_arch_powerpc;
254
1.33k
  else if (architecture == ARCH_M68K)
255
1.21k
    *type = bfd_arch_m68k;
256
1.67k
}
257
258
static bool
259
bfd_pef_mkobject (bfd *abfd ATTRIBUTE_UNUSED)
260
7
{
261
7
  return true;
262
7
}
263
264
static const char *bfd_pef_section_name (bfd_pef_section *section)
265
117k
{
266
117k
  switch (section->section_kind)
267
117k
    {
268
59.3k
    case BFD_PEF_SECTION_CODE: return "code";
269
1.67k
    case BFD_PEF_SECTION_UNPACKED_DATA: return "unpacked-data";
270
1.31k
    case BFD_PEF_SECTION_PACKED_DATA: return "packed-data";
271
573
    case BFD_PEF_SECTION_CONSTANT: return "constant";
272
553
    case BFD_PEF_SECTION_LOADER: return "loader";
273
1.40k
    case BFD_PEF_SECTION_DEBUG: return "debug";
274
579
    case BFD_PEF_SECTION_EXEC_DATA: return "exec-data";
275
475
    case BFD_PEF_SECTION_EXCEPTION: return "exception";
276
742
    case BFD_PEF_SECTION_TRACEBACK: return "traceback";
277
50.5k
    default: return "unknown";
278
117k
    }
279
117k
}
280
281
static unsigned long bfd_pef_section_flags (bfd_pef_section *section)
282
117k
{
283
117k
  switch (section->section_kind)
284
117k
    {
285
59.3k
    case BFD_PEF_SECTION_CODE:
286
59.3k
      return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
287
1.67k
    case BFD_PEF_SECTION_UNPACKED_DATA:
288
2.98k
    case BFD_PEF_SECTION_PACKED_DATA:
289
3.56k
    case BFD_PEF_SECTION_CONSTANT:
290
4.11k
    case BFD_PEF_SECTION_LOADER:
291
5.51k
    case BFD_PEF_SECTION_DEBUG:
292
6.09k
    case BFD_PEF_SECTION_EXEC_DATA:
293
6.57k
    case BFD_PEF_SECTION_EXCEPTION:
294
7.31k
    case BFD_PEF_SECTION_TRACEBACK:
295
57.8k
    default:
296
57.8k
      return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
297
117k
    }
298
117k
}
299
300
static asection *
301
bfd_pef_make_bfd_section (bfd *abfd, bfd_pef_section *section)
302
117k
{
303
117k
  asection *bfdsec;
304
117k
  const char *name = bfd_pef_section_name (section);
305
306
117k
  bfdsec = bfd_make_section_anyway (abfd, name);
307
117k
  if (bfdsec == NULL)
308
0
    return NULL;
309
310
117k
  bfdsec->vma = section->default_address + section->container_offset;
311
117k
  bfdsec->lma = section->default_address + section->container_offset;
312
117k
  bfdsec->size = section->container_length;
313
117k
  bfdsec->filepos = section->container_offset;
314
117k
  bfdsec->alignment_power = section->alignment;
315
316
117k
  bfdsec->flags = bfd_pef_section_flags (section);
317
318
117k
  return bfdsec;
319
117k
}
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
245
{
327
245
  BFD_ASSERT (len == 56);
328
329
245
  header->main_section = bfd_getb32 (buf);
330
245
  header->main_offset = bfd_getb32 (buf + 4);
331
245
  header->init_section = bfd_getb32 (buf + 8);
332
245
  header->init_offset = bfd_getb32 (buf + 12);
333
245
  header->term_section = bfd_getb32 (buf + 16);
334
245
  header->term_offset = bfd_getb32 (buf + 20);
335
245
  header->imported_library_count = bfd_getb32 (buf + 24);
336
245
  header->total_imported_symbol_count = bfd_getb32 (buf + 28);
337
245
  header->reloc_section_count = bfd_getb32 (buf + 32);
338
245
  header->reloc_instr_offset = bfd_getb32 (buf + 36);
339
245
  header->loader_strings_offset = bfd_getb32 (buf + 40);
340
245
  header->export_hash_offset = bfd_getb32 (buf + 44);
341
245
  header->export_hash_table_power = bfd_getb32 (buf + 48);
342
245
  header->exported_symbol_count = bfd_getb32 (buf + 52);
343
344
245
  return 0;
345
245
}
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
27
{
353
27
  BFD_ASSERT (len == 24);
354
355
27
  header->name_offset = bfd_getb32 (buf);
356
27
  header->old_implementation_version = bfd_getb32 (buf + 4);
357
27
  header->current_version = bfd_getb32 (buf + 8);
358
27
  header->imported_symbol_count = bfd_getb32 (buf + 12);
359
27
  header->first_imported_symbol = bfd_getb32 (buf + 16);
360
27
  header->options = buf[20];
361
27
  header->reserved_a = buf[21];
362
27
  header->reserved_b = bfd_getb16 (buf + 22);
363
364
27
  return 0;
365
27
}
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
33
{
373
33
  unsigned long value;
374
375
33
  BFD_ASSERT (len == 4);
376
377
33
  value = bfd_getb32 (buf);
378
33
  symbol->symbol_class = value >> 24;
379
33
  symbol->name = value & 0x00ffffff;
380
381
33
  return 0;
382
33
}
383
384
int
385
bfd_pef_scan_section (bfd *abfd, bfd_pef_section *section)
386
117k
{
387
117k
  unsigned char buf[28];
388
389
117k
  if (bfd_seek (abfd, section->header_offset, SEEK_SET) != 0
390
117k
      || bfd_read (buf, 28, abfd) != 28)
391
355
    return -1;
392
393
117k
  section->name_offset = bfd_h_get_32 (abfd, buf);
394
117k
  section->default_address = bfd_h_get_32 (abfd, buf + 4);
395
117k
  section->total_length = bfd_h_get_32 (abfd, buf + 8);
396
117k
  section->unpacked_length = bfd_h_get_32 (abfd, buf + 12);
397
117k
  section->container_length = bfd_h_get_32 (abfd, buf + 16);
398
117k
  section->container_offset = bfd_h_get_32 (abfd, buf + 20);
399
117k
  section->section_kind = buf[24];
400
117k
  section->share_kind = buf[25];
401
117k
  section->alignment = buf[26];
402
117k
  section->reserved = buf[27];
403
404
117k
  section->bfd_section = bfd_pef_make_bfd_section (abfd, section);
405
117k
  if (section->bfd_section == NULL)
406
0
    return -1;
407
408
117k
  return 0;
409
117k
}
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
1.19k
{
471
1.19k
  bfd_pef_loader_header header;
472
1.19k
  asection *section;
473
474
1.19k
  asection *loadersec = NULL;
475
1.19k
  unsigned char *loaderbuf = NULL;
476
1.19k
  size_t loaderlen = 0;
477
1.19k
  int ret;
478
479
1.19k
  loadersec = bfd_get_section_by_name (abfd, "loader");
480
1.19k
  if (loadersec == NULL)
481
871
    goto end;
482
483
328
  loaderlen = loadersec->size;
484
328
  if (loaderlen < 56)
485
12
    goto error;
486
316
  if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) != 0)
487
0
    goto error;
488
316
  loaderbuf = _bfd_malloc_and_read (abfd, loaderlen, loaderlen);
489
316
  if (loaderbuf == NULL)
490
113
    goto error;
491
492
203
  ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
493
203
  if (ret < 0)
494
0
    goto error;
495
496
203
  if (header.main_section < 0)
497
0
    goto end;
498
499
3.29k
  for (section = abfd->sections; section != NULL; section = section->next)
500
3.15k
    if ((long) (section->index + 1) == header.main_section)
501
62
      break;
502
503
203
  if (section == NULL)
504
141
    goto error;
505
506
62
  abfd->start_address = section->vma + header.main_offset;
507
508
933
 end:
509
933
  free (loaderbuf);
510
933
  return 0;
511
512
266
 error:
513
266
  free (loaderbuf);
514
266
  return -1;
515
62
}
516
517
int
518
bfd_pef_scan (bfd *abfd,
519
        bfd_pef_header *header,
520
        bfd_pef_data_struct *mdata)
521
1.67k
{
522
1.67k
  unsigned int i;
523
1.67k
  enum bfd_architecture cputype;
524
1.67k
  unsigned long cpusubtype;
525
526
1.67k
  mdata->header = *header;
527
528
1.67k
  bfd_pef_convert_architecture (header->architecture, &cputype, &cpusubtype);
529
1.67k
  if (cputype == bfd_arch_unknown)
530
119
    {
531
119
      _bfd_error_handler (_("bfd_pef_scan: unknown architecture 0x%lx"),
532
119
        header->architecture);
533
119
      return -1;
534
119
    }
535
1.55k
  bfd_set_arch_mach (abfd, cputype, cpusubtype);
536
537
1.55k
  mdata->header = *header;
538
539
1.55k
  abfd->flags = (abfd->xvec->object_flags
540
1.55k
     | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
541
542
1.55k
  if (header->section_count != 0)
543
1.54k
    {
544
1.54k
      mdata->sections = bfd_alloc (abfd, header->section_count * sizeof (bfd_pef_section));
545
546
1.54k
      if (mdata->sections == NULL)
547
0
  return -1;
548
549
118k
      for (i = 0; i < header->section_count; i++)
550
117k
  {
551
117k
    bfd_pef_section *cur = &mdata->sections[i];
552
117k
    cur->header_offset = 40 + (i * 28);
553
117k
    if (bfd_pef_scan_section (abfd, cur) < 0)
554
355
      return -1;
555
117k
  }
556
1.54k
    }
557
558
1.19k
  if (bfd_pef_scan_start_address (abfd) < 0)
559
266
    return -1;
560
561
933
  abfd->tdata.pef_data = mdata;
562
563
933
  return 0;
564
1.19k
}
565
566
static int
567
bfd_pef_read_header (bfd *abfd, bfd_pef_header *header)
568
1.65M
{
569
1.65M
  unsigned char buf[40];
570
571
1.65M
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
572
1.65M
      || bfd_read (buf, 40, abfd) != 40)
573
83.3k
    return -1;
574
575
1.57M
  header->tag1 = bfd_getb32 (buf);
576
1.57M
  header->tag2 = bfd_getb32 (buf + 4);
577
1.57M
  header->architecture = bfd_getb32 (buf + 8);
578
1.57M
  header->format_version = bfd_getb32 (buf + 12);
579
1.57M
  header->timestamp = bfd_getb32 (buf + 16);
580
1.57M
  header->old_definition_version = bfd_getb32 (buf + 20);
581
1.57M
  header->old_implementation_version = bfd_getb32 (buf + 24);
582
1.57M
  header->current_version = bfd_getb32 (buf + 28);
583
1.57M
  header->section_count = bfd_getb32 (buf + 32) + 1;
584
1.57M
  header->instantiated_section_count = bfd_getb32 (buf + 34);
585
1.57M
  header->reserved = bfd_getb32 (buf + 36);
586
587
1.57M
  return 0;
588
1.65M
}
589
590
static bfd_cleanup
591
bfd_pef_object_p (bfd *abfd)
592
1.65M
{
593
1.65M
  bfd_pef_header header;
594
1.65M
  bfd_pef_data_struct *mdata;
595
596
1.65M
  if (bfd_pef_read_header (abfd, &header) != 0)
597
83.3k
    goto wrong;
598
599
1.57M
  if (header.tag1 != BFD_PEF_TAG1 || header.tag2 != BFD_PEF_TAG2)
600
1.57M
    goto wrong;
601
602
1.67k
  mdata = (bfd_pef_data_struct *) bfd_zalloc (abfd, sizeof (*mdata));
603
1.67k
  if (mdata == NULL)
604
0
    goto fail;
605
606
1.67k
  if (bfd_pef_scan (abfd, &header, mdata))
607
740
    goto wrong;
608
609
933
  return _bfd_no_cleanup;
610
611
1.65M
 wrong:
612
1.65M
  bfd_set_error (bfd_error_wrong_format);
613
614
1.65M
 fail:
615
1.65M
  return NULL;
616
1.65M
}
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
1.19k
{
626
1.19k
  char *name;
627
628
1.19k
  asymbol function;
629
1.19k
  asymbol traceback;
630
631
1.19k
  const char *const tbprefix = "__traceback_";
632
1.19k
  size_t tbnamelen;
633
634
1.19k
  size_t pos = 0;
635
1.19k
  unsigned long count = 0;
636
1.19k
  int ret;
637
638
1.19k
  for (;;)
639
676k
    {
640
      /* We're reading symbols two at a time.  */
641
676k
      if (csym && ((csym[count] == NULL) || (csym[count + 1] == NULL)))
642
398
  break;
643
644
675k
      pos += 3;
645
675k
      pos -= (pos % 4);
646
647
2.08M
      while ((pos + 4) <= len)
648
2.08M
  {
649
2.08M
    if (bfd_getb32 (buf + pos) == 0)
650
674k
      break;
651
1.40M
    pos += 4;
652
1.40M
  }
653
654
675k
      if ((pos + 4) > len)
655
796
  break;
656
657
674k
      ret = bfd_pef_parse_traceback_table (abfd, sec, buf, len, pos + 4,
658
674k
             &function, 0);
659
674k
      if (ret < 0)
660
667k
  {
661
    /* Skip over 0x0L to advance to next possible traceback table.  */
662
667k
    pos += 4;
663
667k
    continue;
664
667k
  }
665
666
7.79k
      BFD_ASSERT (function.name != NULL);
667
668
      /* Don't bother to compute the name if we are just
669
   counting symbols.  */
670
7.79k
      if (csym)
671
2.59k
  {
672
2.59k
    tbnamelen = strlen (tbprefix) + strlen (function.name);
673
2.59k
    name = bfd_alloc (abfd, tbnamelen + 1);
674
2.59k
    if (name == NULL)
675
0
      {
676
0
        bfd_release (abfd, (void *) function.name);
677
0
        function.name = NULL;
678
0
        break;
679
0
      }
680
2.59k
    snprintf (name, tbnamelen + 1, "%s%s", tbprefix, function.name);
681
2.59k
    traceback.name = name;
682
2.59k
    traceback.value = pos;
683
2.59k
    traceback.the_bfd = abfd;
684
2.59k
    traceback.section = sec;
685
2.59k
    traceback.flags = 0;
686
2.59k
    traceback.udata.i = ret;
687
688
2.59k
    *(csym[count]) = function;
689
2.59k
    *(csym[count + 1]) = traceback;
690
2.59k
  }
691
692
7.79k
      pos += ret;
693
7.79k
      count += 2;
694
7.79k
    }
695
696
1.19k
  *nsym = count;
697
1.19k
  return 0;
698
1.19k
}
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
42
{
737
42
  const char *const sprefix = "__stub_";
738
42
  size_t codepos = 0;
739
42
  unsigned long count = 0;
740
42
  bfd_pef_loader_header header;
741
42
  bfd_pef_imported_library *libraries = NULL;
742
42
  bfd_pef_imported_symbol *imports = NULL;
743
42
  unsigned long i;
744
42
  int ret;
745
746
42
  if (loaderlen < 56)
747
0
    goto error;
748
749
42
  ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
750
42
  if (ret < 0)
751
0
    goto error;
752
753
42
  if ((loaderlen - 56) / 24 < header.imported_library_count)
754
6
    goto error;
755
756
36
  if ((loaderlen - 56 - header.imported_library_count * 24) / 4
757
36
      < header.total_imported_symbol_count)
758
6
    goto error;
759
760
30
  libraries = bfd_malloc
761
30
    (header.imported_library_count * sizeof (bfd_pef_imported_library));
762
30
  imports = bfd_malloc
763
30
    (header.total_imported_symbol_count * sizeof (bfd_pef_imported_symbol));
764
30
  if (libraries == NULL || imports == NULL)
765
0
    goto error;
766
767
57
  for (i = 0; i < header.imported_library_count; i++)
768
27
    {
769
27
      ret = bfd_pef_parse_imported_library
770
27
  (abfd, loaderbuf + 56 + (i * 24), 24, &libraries[i]);
771
27
      if (ret < 0)
772
0
  goto error;
773
27
    }
774
775
63
  for (i = 0; i < header.total_imported_symbol_count; i++)
776
33
    {
777
33
      ret = (bfd_pef_parse_imported_symbol
778
33
       (abfd,
779
33
        loaderbuf + 56 + (header.imported_library_count * 24) + (i * 4),
780
33
        4, &imports[i]));
781
33
      if (ret < 0)
782
0
  goto error;
783
33
    }
784
785
30
  codepos = 0;
786
787
30
  for (;;)
788
30
    {
789
30
      asymbol sym;
790
30
      const char *symname;
791
30
      char *name;
792
30
      unsigned long sym_index;
793
794
30
      if (csym && (csym[count] == NULL))
795
10
  break;
796
797
20
      codepos += 3;
798
20
      codepos -= (codepos % 4);
799
800
74
      while ((codepos + 4) <= codelen)
801
54
  {
802
54
    if ((bfd_getb32 (codebuf + codepos) & 0xffff0000) == 0x81820000)
803
0
      break;
804
54
    codepos += 4;
805
54
  }
806
807
20
      if ((codepos + 24) > codelen)
808
20
  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
30
  goto end;
869
870
30
 end:
871
30
  free (libraries);
872
30
  free (imports);
873
30
  *nsym = count;
874
30
  return 0;
875
876
12
 error:
877
12
  free (libraries);
878
12
  free (imports);
879
12
  *nsym = count;
880
12
  return -1;
881
30
}
882
883
static long
884
bfd_pef_parse_symbols (bfd *abfd, asymbol **csym)
885
1.64k
{
886
1.64k
  unsigned long count = 0;
887
888
1.64k
  asection *codesec = NULL;
889
1.64k
  unsigned char *codebuf = NULL;
890
1.64k
  size_t codelen = 0;
891
892
1.64k
  asection *loadersec = NULL;
893
1.64k
  unsigned char *loaderbuf = NULL;
894
1.64k
  size_t loaderlen = 0;
895
896
1.64k
  codesec = bfd_get_section_by_name (abfd, "code");
897
1.64k
  if (codesec != NULL)
898
1.53k
    {
899
1.53k
      codelen = codesec->size;
900
1.53k
      if (bfd_seek (abfd, codesec->filepos, SEEK_SET) != 0)
901
0
  goto end;
902
1.53k
      codebuf = _bfd_malloc_and_read (abfd, codelen, codelen);
903
1.53k
      if (codebuf == NULL)
904
336
  goto end;
905
1.53k
    }
906
907
1.30k
  loadersec = bfd_get_section_by_name (abfd, "loader");
908
1.30k
  if (loadersec != NULL)
909
72
    {
910
72
      loaderlen = loadersec->size;
911
72
      if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) != 0)
912
0
  goto end;
913
72
      loaderbuf = _bfd_malloc_and_read (abfd, loaderlen, loaderlen);
914
72
      if (loaderbuf == NULL)
915
0
  goto end;
916
72
    }
917
918
1.30k
  count = 0;
919
1.30k
  if (codesec != NULL)
920
1.19k
    {
921
1.19k
      long ncount = 0;
922
1.19k
      bfd_pef_parse_traceback_tables (abfd, codesec, codebuf, codelen,
923
1.19k
              &ncount, csym);
924
1.19k
      count += ncount;
925
1.19k
    }
926
927
1.30k
  if ((codesec != NULL) && (loadersec != NULL))
928
42
    {
929
42
      unsigned long ncount = 0;
930
42
      bfd_pef_parse_function_stubs
931
42
  (abfd, codesec, codebuf, codelen, loaderbuf, loaderlen, &ncount,
932
42
   (csym != NULL) ? (csym + count) : NULL);
933
42
      count += ncount;
934
42
    }
935
936
1.30k
  if (csym != NULL)
937
436
    csym[count] = NULL;
938
939
1.64k
 end:
940
1.64k
  free (codebuf);
941
1.64k
  free (loaderbuf);
942
1.64k
  return count;
943
1.30k
}
944
945
static long
946
bfd_pef_count_symbols (bfd *abfd)
947
1.09k
{
948
1.09k
  return bfd_pef_parse_symbols (abfd, NULL);
949
1.09k
}
950
951
static long
952
bfd_pef_get_symtab_upper_bound (bfd *abfd)
953
548
{
954
548
  long nsyms = bfd_pef_count_symbols (abfd);
955
956
548
  if (nsyms < 0)
957
0
    return nsyms;
958
548
  return ((nsyms + 1) * sizeof (asymbol *));
959
548
}
960
961
static long
962
bfd_pef_canonicalize_symtab (bfd *abfd, asymbol **alocation)
963
548
{
964
548
  long i;
965
548
  asymbol *syms;
966
548
  long ret;
967
548
  long nsyms = bfd_pef_count_symbols (abfd);
968
969
548
  if (nsyms < 0)
970
0
    return nsyms;
971
972
548
  syms = bfd_alloc (abfd, nsyms * sizeof (asymbol));
973
548
  if (syms == NULL)
974
0
    return -1;
975
976
5.74k
  for (i = 0; i < nsyms; i++)
977
5.19k
    alocation[i] = &syms[i];
978
979
548
  alocation[nsyms] = NULL;
980
981
548
  ret = bfd_pef_parse_symbols (abfd, alocation);
982
548
  if (ret != nsyms)
983
0
    return 0;
984
985
548
  return ret;
986
548
}
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
1.65M
{
1072
1.65M
  unsigned char buf[80];
1073
1074
1.65M
  if (bfd_seek (abfd, 0, SEEK_SET) != 0
1075
1.65M
      || bfd_read (buf, sizeof buf, abfd) != sizeof buf)
1076
247k
    return -1;
1077
1078
1.41M
  header->tag1 = bfd_getb32 (buf);
1079
1.41M
  header->tag2 = bfd_getb32 (buf + 4);
1080
1.41M
  header->current_format = bfd_getb32 (buf + 8);
1081
1.41M
  header->container_strings_offset = bfd_getb32 (buf + 12);
1082
1.41M
  header->export_hash_offset = bfd_getb32 (buf + 16);
1083
1.41M
  header->export_key_offset = bfd_getb32 (buf + 20);
1084
1.41M
  header->export_symbol_offset = bfd_getb32 (buf + 24);
1085
1.41M
  header->export_names_offset = bfd_getb32 (buf + 28);
1086
1.41M
  header->export_hash_table_power = bfd_getb32 (buf + 32);
1087
1.41M
  header->exported_symbol_count = bfd_getb32 (buf + 36);
1088
1.41M
  header->frag_name_offset = bfd_getb32 (buf + 40);
1089
1.41M
  header->frag_name_length = bfd_getb32 (buf + 44);
1090
1.41M
  header->dylib_path_offset = bfd_getb32 (buf + 48);
1091
1.41M
  header->dylib_path_length = bfd_getb32 (buf + 52);
1092
1.41M
  header->cpu_family = bfd_getb32 (buf + 56);
1093
1.41M
  header->cpu_model = bfd_getb32 (buf + 60);
1094
1.41M
  header->date_time_stamp = bfd_getb32 (buf + 64);
1095
1.41M
  header->current_version = bfd_getb32 (buf + 68);
1096
1.41M
  header->old_definition_version = bfd_getb32 (buf + 72);
1097
1.41M
  header->old_implementation_version = bfd_getb32 (buf + 76);
1098
1099
1.41M
  return 0;
1100
1.65M
}
1101
1102
static int
1103
bfd_pef_xlib_scan (bfd *abfd, bfd_pef_xlib_header *header)
1104
2
{
1105
2
  bfd_pef_xlib_data_struct *mdata = NULL;
1106
1107
2
  mdata = bfd_alloc (abfd, sizeof (* mdata));
1108
2
  if (mdata == NULL)
1109
0
    return -1;
1110
1111
2
  mdata->header = *header;
1112
1113
2
  abfd->flags = (abfd->xvec->object_flags
1114
2
     | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1115
1116
2
  abfd->tdata.pef_xlib_data = mdata;
1117
1118
2
  return 0;
1119
2
}
1120
1121
static bfd_cleanup
1122
bfd_pef_xlib_object_p (bfd *abfd)
1123
1.65M
{
1124
1.65M
  bfd_pef_xlib_header header;
1125
1126
1.65M
  if (bfd_pef_xlib_read_header (abfd, &header) != 0)
1127
247k
    {
1128
247k
      bfd_set_error (bfd_error_wrong_format);
1129
247k
      return NULL;
1130
247k
    }
1131
1132
1.41M
  if ((header.tag1 != BFD_PEF_XLIB_TAG1)
1133
1.41M
      || ((header.tag2 != BFD_PEF_VLIB_TAG2)
1134
10
    && (header.tag2 != BFD_PEF_BLIB_TAG2)))
1135
1.41M
    {
1136
1.41M
      bfd_set_error (bfd_error_wrong_format);
1137
1.41M
      return NULL;
1138
1.41M
    }
1139
1140
2
  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
2
  return _bfd_no_cleanup;
1147
2
}
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
};