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