Coverage Report

Created: 2025-06-24 06:45

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