Coverage Report

Created: 2025-07-08 11:15

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