Coverage Report

Created: 2023-06-29 07:13

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