1 /* PEF support for BFD.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 2009, 2011 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
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
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
23 #include "safe-ctype.h"
25 #include "pef-traceback.h"
28 #include "libiberty.h"
31 #define BFD_IO_FUNCS 0
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
38 #define bfd_pef_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
39 #define bfd_pef_get_lineno _bfd_nosymbols_get_lineno
40 #define bfd_pef_find_nearest_line _bfd_nosymbols_find_nearest_line
41 #define bfd_pef_find_inliner_info _bfd_nosymbols_find_inliner_info
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
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
52 #define bfd_pef_bfd_is_group_section bfd_generic_is_group_section
53 #define bfd_pef_bfd_discard_group bfd_generic_discard_group
54 #define bfd_pef_section_already_linked _bfd_generic_section_already_linked
55 #define bfd_pef_bfd_define_common_symbol bfd_generic_define_common_symbol
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_copy_link_hash_symbol_type \
61 _bfd_generic_copy_link_hash_symbol_type
62 #define bfd_pef_bfd_final_link _bfd_generic_final_link
63 #define bfd_pef_bfd_link_split_section _bfd_generic_link_split_section
64 #define bfd_pef_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
67 bfd_pef_parse_traceback_table (bfd
*abfd
,
75 struct traceback_table table
;
86 sym
->section
= section
;
90 /* memcpy is fine since all fields are unsigned char. */
93 memcpy (&table
, buf
+ pos
, 8);
95 /* Calling code relies on returned symbols having a name and
97 if ((table
.lang
!= TB_C
) && (table
.lang
!= TB_CPLUSPLUS
))
100 if (! (table
.flags2
& TB_NAME_PRESENT
))
103 if (! (table
.flags1
& TB_HAS_TBOFF
))
108 if ((table
.flags5
& TB_FLOATPARAMS
) || (table
.fixedparams
))
111 if (table
.flags1
& TB_HAS_TBOFF
)
113 struct traceback_table_tboff off
;
115 if ((pos
+ offset
+ 4) > len
)
117 off
.tb_offset
= bfd_getb32 (buf
+ pos
+ offset
);
120 /* Need to subtract 4 because the offset includes the 0x0L
121 preceding the table. */
123 fprintf (file
, " [offset = 0x%lx]", off
.tb_offset
);
125 if ((file
== NULL
) && ((off
.tb_offset
+ 4) > (pos
+ offset
)))
128 sym
->value
= pos
- off
.tb_offset
- 4;
131 if (table
.flags2
& TB_INT_HNDL
)
134 if (table
.flags1
& TB_HAS_CTL
)
136 struct traceback_table_anchors anchors
;
138 if ((pos
+ offset
+ 4) > len
)
140 anchors
.ctl_info
= bfd_getb32 (buf
+ pos
+ offset
);
143 if (anchors
.ctl_info
> 1024)
146 offset
+= anchors
.ctl_info
* 4;
149 if (table
.flags2
& TB_NAME_PRESENT
)
151 struct traceback_table_routine name
;
154 if ((pos
+ offset
+ 2) > len
)
156 name
.name_len
= bfd_getb16 (buf
+ pos
+ offset
);
159 if (name
.name_len
> 4096)
162 if ((pos
+ offset
+ name
.name_len
) > len
)
165 namebuf
= bfd_alloc (abfd
, name
.name_len
+ 1);
169 memcpy (namebuf
, buf
+ pos
+ offset
, name
.name_len
);
170 namebuf
[name
.name_len
] = '\0';
172 /* Strip leading period inserted by compiler. */
173 if (namebuf
[0] == '.')
174 memmove (namebuf
, namebuf
+ 1, name
.name_len
+ 1);
178 for (s
= sym
->name
; (*s
!= '\0'); s
++)
182 offset
+= name
.name_len
;
185 if (table
.flags2
& TB_USES_ALLOCA
)
188 if (table
.flags4
& TB_HAS_VEC_INFO
)
192 fprintf (file
, " [length = 0x%lx]", (unsigned long) offset
);
198 bfd_pef_print_symbol (bfd
*abfd
,
201 bfd_print_symbol_type how
)
203 FILE *file
= (FILE *) afile
;
207 case bfd_print_symbol_name
:
208 fprintf (file
, "%s", symbol
->name
);
211 bfd_print_symbol_vandf (abfd
, (void *) file
, symbol
);
212 fprintf (file
, " %-5s %s", symbol
->section
->name
, symbol
->name
);
213 if (CONST_STRNEQ (symbol
->name
, "__traceback_"))
215 unsigned char *buf
= alloca (symbol
->udata
.i
);
216 size_t offset
= symbol
->value
+ 4;
217 size_t len
= symbol
->udata
.i
;
220 bfd_get_section_contents (abfd
, symbol
->section
, buf
, offset
, len
);
221 ret
= bfd_pef_parse_traceback_table (abfd
, symbol
->section
, buf
,
224 fprintf (file
, " [ERROR]");
230 bfd_pef_convert_architecture (unsigned long architecture
,
231 enum bfd_architecture
*type
,
232 unsigned long *subtype
)
234 const unsigned long ARCH_POWERPC
= 0x70777063; /* 'pwpc'. */
235 const unsigned long ARCH_M68K
= 0x6d36386b; /* 'm68k'. */
237 *subtype
= bfd_arch_unknown
;
238 *type
= bfd_arch_unknown
;
240 if (architecture
== ARCH_POWERPC
)
241 *type
= bfd_arch_powerpc
;
242 else if (architecture
== ARCH_M68K
)
243 *type
= bfd_arch_m68k
;
247 bfd_pef_mkobject (bfd
*abfd ATTRIBUTE_UNUSED
)
252 static const char *bfd_pef_section_name (bfd_pef_section
*section
)
254 switch (section
->section_kind
)
256 case BFD_PEF_SECTION_CODE
: return "code";
257 case BFD_PEF_SECTION_UNPACKED_DATA
: return "unpacked-data";
258 case BFD_PEF_SECTION_PACKED_DATA
: return "packed-data";
259 case BFD_PEF_SECTION_CONSTANT
: return "constant";
260 case BFD_PEF_SECTION_LOADER
: return "loader";
261 case BFD_PEF_SECTION_DEBUG
: return "debug";
262 case BFD_PEF_SECTION_EXEC_DATA
: return "exec-data";
263 case BFD_PEF_SECTION_EXCEPTION
: return "exception";
264 case BFD_PEF_SECTION_TRACEBACK
: return "traceback";
265 default: return "unknown";
269 static unsigned long bfd_pef_section_flags (bfd_pef_section
*section
)
271 switch (section
->section_kind
)
273 case BFD_PEF_SECTION_CODE
:
274 return SEC_HAS_CONTENTS
| SEC_LOAD
| SEC_ALLOC
| SEC_CODE
;
275 case BFD_PEF_SECTION_UNPACKED_DATA
:
276 case BFD_PEF_SECTION_PACKED_DATA
:
277 case BFD_PEF_SECTION_CONSTANT
:
278 case BFD_PEF_SECTION_LOADER
:
279 case BFD_PEF_SECTION_DEBUG
:
280 case BFD_PEF_SECTION_EXEC_DATA
:
281 case BFD_PEF_SECTION_EXCEPTION
:
282 case BFD_PEF_SECTION_TRACEBACK
:
284 return SEC_HAS_CONTENTS
| SEC_LOAD
| SEC_ALLOC
;
289 bfd_pef_make_bfd_section (bfd
*abfd
, bfd_pef_section
*section
)
292 const char *name
= bfd_pef_section_name (section
);
294 bfdsec
= bfd_make_section_anyway (abfd
, name
);
298 bfdsec
->vma
= section
->default_address
+ section
->container_offset
;
299 bfdsec
->lma
= section
->default_address
+ section
->container_offset
;
300 bfdsec
->size
= section
->container_length
;
301 bfdsec
->filepos
= section
->container_offset
;
302 bfdsec
->alignment_power
= section
->alignment
;
304 bfdsec
->flags
= bfd_pef_section_flags (section
);
310 bfd_pef_parse_loader_header (bfd
*abfd ATTRIBUTE_UNUSED
,
313 bfd_pef_loader_header
*header
)
315 BFD_ASSERT (len
== 56);
317 header
->main_section
= bfd_getb32 (buf
);
318 header
->main_offset
= bfd_getb32 (buf
+ 4);
319 header
->init_section
= bfd_getb32 (buf
+ 8);
320 header
->init_offset
= bfd_getb32 (buf
+ 12);
321 header
->term_section
= bfd_getb32 (buf
+ 16);
322 header
->term_offset
= bfd_getb32 (buf
+ 20);
323 header
->imported_library_count
= bfd_getb32 (buf
+ 24);
324 header
->total_imported_symbol_count
= bfd_getb32 (buf
+ 28);
325 header
->reloc_section_count
= bfd_getb32 (buf
+ 32);
326 header
->reloc_instr_offset
= bfd_getb32 (buf
+ 36);
327 header
->loader_strings_offset
= bfd_getb32 (buf
+ 40);
328 header
->export_hash_offset
= bfd_getb32 (buf
+ 44);
329 header
->export_hash_table_power
= bfd_getb32 (buf
+ 48);
330 header
->exported_symbol_count
= bfd_getb32 (buf
+ 52);
336 bfd_pef_parse_imported_library (bfd
*abfd ATTRIBUTE_UNUSED
,
339 bfd_pef_imported_library
*header
)
341 BFD_ASSERT (len
== 24);
343 header
->name_offset
= bfd_getb32 (buf
);
344 header
->old_implementation_version
= bfd_getb32 (buf
+ 4);
345 header
->current_version
= bfd_getb32 (buf
+ 8);
346 header
->imported_symbol_count
= bfd_getb32 (buf
+ 12);
347 header
->first_imported_symbol
= bfd_getb32 (buf
+ 16);
348 header
->options
= buf
[20];
349 header
->reserved_a
= buf
[21];
350 header
->reserved_b
= bfd_getb16 (buf
+ 22);
356 bfd_pef_parse_imported_symbol (bfd
*abfd ATTRIBUTE_UNUSED
,
359 bfd_pef_imported_symbol
*symbol
)
363 BFD_ASSERT (len
== 4);
365 value
= bfd_getb32 (buf
);
366 symbol
->symbol_class
= value
>> 24;
367 symbol
->name
= value
& 0x00ffffff;
373 bfd_pef_scan_section (bfd
*abfd
, bfd_pef_section
*section
)
375 unsigned char buf
[28];
377 bfd_seek (abfd
, section
->header_offset
, SEEK_SET
);
378 if (bfd_bread ((void *) buf
, 28, abfd
) != 28)
381 section
->name_offset
= bfd_h_get_32 (abfd
, buf
);
382 section
->default_address
= bfd_h_get_32 (abfd
, buf
+ 4);
383 section
->total_length
= bfd_h_get_32 (abfd
, buf
+ 8);
384 section
->unpacked_length
= bfd_h_get_32 (abfd
, buf
+ 12);
385 section
->container_length
= bfd_h_get_32 (abfd
, buf
+ 16);
386 section
->container_offset
= bfd_h_get_32 (abfd
, buf
+ 20);
387 section
->section_kind
= buf
[24];
388 section
->share_kind
= buf
[25];
389 section
->alignment
= buf
[26];
390 section
->reserved
= buf
[27];
392 section
->bfd_section
= bfd_pef_make_bfd_section (abfd
, section
);
393 if (section
->bfd_section
== NULL
)
400 bfd_pef_print_loader_header (bfd
*abfd ATTRIBUTE_UNUSED
,
401 bfd_pef_loader_header
*header
,
404 fprintf (file
, "main_section: %ld\n", header
->main_section
);
405 fprintf (file
, "main_offset: %lu\n", header
->main_offset
);
406 fprintf (file
, "init_section: %ld\n", header
->init_section
);
407 fprintf (file
, "init_offset: %lu\n", header
->init_offset
);
408 fprintf (file
, "term_section: %ld\n", header
->term_section
);
409 fprintf (file
, "term_offset: %lu\n", header
->term_offset
);
410 fprintf (file
, "imported_library_count: %lu\n",
411 header
->imported_library_count
);
412 fprintf (file
, "total_imported_symbol_count: %lu\n",
413 header
->total_imported_symbol_count
);
414 fprintf (file
, "reloc_section_count: %lu\n", header
->reloc_section_count
);
415 fprintf (file
, "reloc_instr_offset: %lu\n", header
->reloc_instr_offset
);
416 fprintf (file
, "loader_strings_offset: %lu\n",
417 header
->loader_strings_offset
);
418 fprintf (file
, "export_hash_offset: %lu\n", header
->export_hash_offset
);
419 fprintf (file
, "export_hash_table_power: %lu\n",
420 header
->export_hash_table_power
);
421 fprintf (file
, "exported_symbol_count: %lu\n",
422 header
->exported_symbol_count
);
426 bfd_pef_print_loader_section (bfd
*abfd
, FILE *file
)
428 bfd_pef_loader_header header
;
429 asection
*loadersec
= NULL
;
430 unsigned char *loaderbuf
= NULL
;
431 size_t loaderlen
= 0;
433 loadersec
= bfd_get_section_by_name (abfd
, "loader");
434 if (loadersec
== NULL
)
437 loaderlen
= loadersec
->size
;
438 loaderbuf
= bfd_malloc (loaderlen
);
440 if (bfd_seek (abfd
, loadersec
->filepos
, SEEK_SET
) < 0
441 || bfd_bread ((void *) loaderbuf
, loaderlen
, abfd
) != loaderlen
443 || bfd_pef_parse_loader_header (abfd
, loaderbuf
, 56, &header
) < 0)
449 bfd_pef_print_loader_header (abfd
, &header
, file
);
454 bfd_pef_scan_start_address (bfd
*abfd
)
456 bfd_pef_loader_header header
;
459 asection
*loadersec
= NULL
;
460 unsigned char *loaderbuf
= NULL
;
461 size_t loaderlen
= 0;
464 loadersec
= bfd_get_section_by_name (abfd
, "loader");
465 if (loadersec
== NULL
)
468 loaderlen
= loadersec
->size
;
469 loaderbuf
= bfd_malloc (loaderlen
);
470 if (bfd_seek (abfd
, loadersec
->filepos
, SEEK_SET
) < 0)
472 if (bfd_bread ((void *) loaderbuf
, loaderlen
, abfd
) != loaderlen
)
477 ret
= bfd_pef_parse_loader_header (abfd
, loaderbuf
, 56, &header
);
481 if (header
.main_section
< 0)
484 for (section
= abfd
->sections
; section
!= NULL
; section
= section
->next
)
485 if ((section
->index
+ 1) == header
.main_section
)
491 abfd
->start_address
= section
->vma
+ header
.main_offset
;
494 if (loaderbuf
!= NULL
)
499 if (loaderbuf
!= NULL
)
505 bfd_pef_scan (abfd
, header
, mdata
)
507 bfd_pef_header
*header
;
508 bfd_pef_data_struct
*mdata
;
511 enum bfd_architecture cputype
;
512 unsigned long cpusubtype
;
514 mdata
->header
= *header
;
516 bfd_pef_convert_architecture (header
->architecture
, &cputype
, &cpusubtype
);
517 if (cputype
== bfd_arch_unknown
)
519 (*_bfd_error_handler
) (_("bfd_pef_scan: unknown architecture 0x%lx"),
520 header
->architecture
);
523 bfd_set_arch_mach (abfd
, cputype
, cpusubtype
);
525 mdata
->header
= *header
;
527 abfd
->flags
= (abfd
->xvec
->object_flags
528 | (abfd
->flags
& (BFD_IN_MEMORY
| BFD_IO_FUNCS
)));
530 if (header
->section_count
!= 0)
532 mdata
->sections
= bfd_alloc (abfd
, header
->section_count
* sizeof (bfd_pef_section
));
534 if (mdata
->sections
== NULL
)
537 for (i
= 0; i
< header
->section_count
; i
++)
539 bfd_pef_section
*cur
= &mdata
->sections
[i
];
540 cur
->header_offset
= 40 + (i
* 28);
541 if (bfd_pef_scan_section (abfd
, cur
) < 0)
546 if (bfd_pef_scan_start_address (abfd
) < 0)
549 abfd
->tdata
.pef_data
= mdata
;
555 bfd_pef_read_header (bfd
*abfd
, bfd_pef_header
*header
)
557 unsigned char buf
[40];
559 bfd_seek (abfd
, 0, SEEK_SET
);
561 if (bfd_bread ((void *) buf
, 40, abfd
) != 40)
564 header
->tag1
= bfd_getb32 (buf
);
565 header
->tag2
= bfd_getb32 (buf
+ 4);
566 header
->architecture
= bfd_getb32 (buf
+ 8);
567 header
->format_version
= bfd_getb32 (buf
+ 12);
568 header
->timestamp
= bfd_getb32 (buf
+ 16);
569 header
->old_definition_version
= bfd_getb32 (buf
+ 20);
570 header
->old_implementation_version
= bfd_getb32 (buf
+ 24);
571 header
->current_version
= bfd_getb32 (buf
+ 28);
572 header
->section_count
= bfd_getb32 (buf
+ 32) + 1;
573 header
->instantiated_section_count
= bfd_getb32 (buf
+ 34);
574 header
->reserved
= bfd_getb32 (buf
+ 36);
579 static const bfd_target
*
580 bfd_pef_object_p (bfd
*abfd
)
582 struct bfd_preserve preserve
;
583 bfd_pef_header header
;
585 preserve
.marker
= NULL
;
586 if (bfd_pef_read_header (abfd
, &header
) != 0)
589 if (header
.tag1
!= BFD_PEF_TAG1
|| header
.tag2
!= BFD_PEF_TAG2
)
592 preserve
.marker
= bfd_zalloc (abfd
, sizeof (bfd_pef_data_struct
));
593 if (preserve
.marker
== NULL
594 || !bfd_preserve_save (abfd
, &preserve
))
597 if (bfd_pef_scan (abfd
, &header
,
598 (bfd_pef_data_struct
*) preserve
.marker
) != 0)
601 bfd_preserve_finish (abfd
, &preserve
);
605 bfd_set_error (bfd_error_wrong_format
);
608 if (preserve
.marker
!= NULL
)
609 bfd_preserve_restore (abfd
, &preserve
);
614 bfd_pef_parse_traceback_tables (bfd
*abfd
,
626 const char *const tbprefix
= "__traceback_";
630 unsigned long count
= 0;
635 /* We're reading symbols two at a time. */
636 if (csym
&& ((csym
[count
] == NULL
) || (csym
[count
+ 1] == NULL
)))
642 while ((pos
+ 4) <= len
)
644 if (bfd_getb32 (buf
+ pos
) == 0)
652 ret
= bfd_pef_parse_traceback_table (abfd
, sec
, buf
, len
, pos
+ 4,
656 /* Skip over 0x0L to advance to next possible traceback table. */
661 BFD_ASSERT (function
.name
!= NULL
);
663 /* Don't bother to compute the name if we are just
667 tbnamelen
= strlen (tbprefix
) + strlen (function
.name
);
668 name
= bfd_alloc (abfd
, tbnamelen
+ 1);
671 bfd_release (abfd
, (void *) function
.name
);
672 function
.name
= NULL
;
675 snprintf (name
, tbnamelen
+ 1, "%s%s", tbprefix
, function
.name
);
676 traceback
.name
= name
;
677 traceback
.value
= pos
;
678 traceback
.the_bfd
= abfd
;
679 traceback
.section
= sec
;
681 traceback
.udata
.i
= ret
;
683 *(csym
[count
]) = function
;
684 *(csym
[count
+ 1]) = traceback
;
696 bfd_pef_parse_function_stub (bfd
*abfd ATTRIBUTE_UNUSED
,
699 unsigned long *offset
)
701 BFD_ASSERT (len
== 24);
703 if ((bfd_getb32 (buf
) & 0xffff0000) != 0x81820000)
705 if (bfd_getb32 (buf
+ 4) != 0x90410014)
707 if (bfd_getb32 (buf
+ 8) != 0x800c0000)
709 if (bfd_getb32 (buf
+ 12) != 0x804c0004)
711 if (bfd_getb32 (buf
+ 16) != 0x7c0903a6)
713 if (bfd_getb32 (buf
+ 20) != 0x4e800420)
717 *offset
= (bfd_getb32 (buf
) & 0x0000ffff) / 4;
723 bfd_pef_parse_function_stubs (bfd
*abfd
,
725 unsigned char *codebuf
,
727 unsigned char *loaderbuf
,
732 const char *const sprefix
= "__stub_";
734 unsigned long count
= 0;
735 bfd_pef_loader_header header
;
736 bfd_pef_imported_library
*libraries
= NULL
;
737 bfd_pef_imported_symbol
*imports
= NULL
;
744 ret
= bfd_pef_parse_loader_header (abfd
, loaderbuf
, 56, &header
);
748 libraries
= bfd_malloc
749 (header
.imported_library_count
* sizeof (bfd_pef_imported_library
));
751 (header
.total_imported_symbol_count
* sizeof (bfd_pef_imported_symbol
));
753 if (loaderlen
< (56 + (header
.imported_library_count
* 24)))
755 for (i
= 0; i
< header
.imported_library_count
; i
++)
757 ret
= bfd_pef_parse_imported_library
758 (abfd
, loaderbuf
+ 56 + (i
* 24), 24, &libraries
[i
]);
763 if (loaderlen
< (56 + (header
.imported_library_count
* 24)
764 + (header
.total_imported_symbol_count
* 4)))
766 for (i
= 0; i
< header
.total_imported_symbol_count
; i
++)
768 ret
= (bfd_pef_parse_imported_symbol
770 loaderbuf
+ 56 + (header
.imported_library_count
* 24) + (i
* 4),
783 unsigned long sym_index
;
785 if (csym
&& (csym
[count
] == NULL
))
789 codepos
-= (codepos
% 4);
791 while ((codepos
+ 4) <= codelen
)
793 if ((bfd_getb32 (codebuf
+ codepos
) & 0xffff0000) == 0x81820000)
798 if ((codepos
+ 4) > codelen
)
801 ret
= bfd_pef_parse_function_stub (abfd
, codebuf
+ codepos
, 24, &sym_index
);
808 if (sym_index
>= header
.total_imported_symbol_count
)
818 if (loaderlen
< (header
.loader_strings_offset
+ imports
[sym_index
].name
))
821 max
= loaderlen
- (header
.loader_strings_offset
+ imports
[sym_index
].name
);
822 symname
= (char *) loaderbuf
;
823 symname
+= header
.loader_strings_offset
+ imports
[sym_index
].name
;
825 for (s
= symname
; s
< (symname
+ max
); s
++)
836 name
= bfd_alloc (abfd
, strlen (sprefix
) + namelen
+ 1);
840 snprintf (name
, strlen (sprefix
) + namelen
+ 1, "%s%s",
847 sym
.section
= codesec
;
854 *(csym
[count
]) = sym
;
862 if (libraries
!= NULL
)
870 if (libraries
!= NULL
)
879 bfd_pef_parse_symbols (bfd
*abfd
, asymbol
**csym
)
881 unsigned long count
= 0;
883 asection
*codesec
= NULL
;
884 unsigned char *codebuf
= NULL
;
887 asection
*loadersec
= NULL
;
888 unsigned char *loaderbuf
= NULL
;
889 size_t loaderlen
= 0;
891 codesec
= bfd_get_section_by_name (abfd
, "code");
894 codelen
= codesec
->size
;
895 codebuf
= bfd_malloc (codelen
);
896 if (bfd_seek (abfd
, codesec
->filepos
, SEEK_SET
) < 0)
898 if (bfd_bread ((void *) codebuf
, codelen
, abfd
) != codelen
)
902 loadersec
= bfd_get_section_by_name (abfd
, "loader");
903 if (loadersec
!= NULL
)
905 loaderlen
= loadersec
->size
;
906 loaderbuf
= bfd_malloc (loaderlen
);
907 if (bfd_seek (abfd
, loadersec
->filepos
, SEEK_SET
) < 0)
909 if (bfd_bread ((void *) loaderbuf
, loaderlen
, abfd
) != loaderlen
)
917 bfd_pef_parse_traceback_tables (abfd
, codesec
, codebuf
, codelen
,
922 if ((codesec
!= NULL
) && (loadersec
!= NULL
))
924 unsigned long ncount
= 0;
925 bfd_pef_parse_function_stubs
926 (abfd
, codesec
, codebuf
, codelen
, loaderbuf
, loaderlen
, &ncount
,
927 (csym
!= NULL
) ? (csym
+ count
) : NULL
);
938 if (loaderbuf
!= NULL
)
945 bfd_pef_count_symbols (bfd
*abfd
)
947 return bfd_pef_parse_symbols (abfd
, NULL
);
951 bfd_pef_get_symtab_upper_bound (bfd
*abfd
)
953 long nsyms
= bfd_pef_count_symbols (abfd
);
957 return ((nsyms
+ 1) * sizeof (asymbol
*));
961 bfd_pef_canonicalize_symtab (bfd
*abfd
, asymbol
**alocation
)
966 long nsyms
= bfd_pef_count_symbols (abfd
);
971 syms
= bfd_alloc (abfd
, nsyms
* sizeof (asymbol
));
975 for (i
= 0; i
< nsyms
; i
++)
976 alocation
[i
] = &syms
[i
];
978 alocation
[nsyms
] = NULL
;
980 ret
= bfd_pef_parse_symbols (abfd
, alocation
);
987 #define bfd_pef_make_empty_symbol _bfd_generic_make_empty_symbol
990 bfd_pef_get_symbol_info (bfd
*abfd ATTRIBUTE_UNUSED
,
994 bfd_symbol_info (symbol
, ret
);
998 bfd_pef_sizeof_headers (bfd
*abfd ATTRIBUTE_UNUSED
,
999 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1004 const bfd_target pef_vec
=
1007 bfd_target_pef_flavour
, /* Flavour. */
1008 BFD_ENDIAN_BIG
, /* Byteorder. */
1009 BFD_ENDIAN_BIG
, /* Header_byteorder. */
1010 (HAS_RELOC
| EXEC_P
| /* Object flags. */
1011 HAS_LINENO
| HAS_DEBUG
|
1012 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
1013 (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_CODE
| SEC_DATA
1014 | SEC_ROM
| SEC_HAS_CONTENTS
), /* Section_flags. */
1015 0, /* Symbol_leading_char. */
1016 ' ', /* AR_pad_char. */
1017 16, /* AR_max_namelen. */
1018 0, /* match priority. */
1019 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1020 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1021 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* Data. */
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
, /* Headers. */
1025 { /* bfd_check_format. */
1027 bfd_pef_object_p
, /* bfd_check_format. */
1031 { /* bfd_set_format. */
1037 { /* bfd_write_contents. */
1044 BFD_JUMP_TABLE_GENERIC (bfd_pef
),
1045 BFD_JUMP_TABLE_COPY (_bfd_generic
),
1046 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
1047 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive
),
1048 BFD_JUMP_TABLE_SYMBOLS (bfd_pef
),
1049 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs
),
1050 BFD_JUMP_TABLE_WRITE (bfd_pef
),
1051 BFD_JUMP_TABLE_LINK (bfd_pef
),
1052 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),
1059 #define bfd_pef_xlib_close_and_cleanup _bfd_generic_close_and_cleanup
1060 #define bfd_pef_xlib_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1061 #define bfd_pef_xlib_new_section_hook _bfd_generic_new_section_hook
1062 #define bfd_pef_xlib_get_section_contents _bfd_generic_get_section_contents
1063 #define bfd_pef_xlib_set_section_contents _bfd_generic_set_section_contents
1064 #define bfd_pef_xlib_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
1065 #define bfd_pef_xlib_set_section_contents_in_window _bfd_generic_set_section_contents_in_window
1068 bfd_pef_xlib_read_header (bfd
*abfd
, bfd_pef_xlib_header
*header
)
1070 unsigned char buf
[76];
1072 bfd_seek (abfd
, 0, SEEK_SET
);
1074 if (bfd_bread ((void *) buf
, 76, abfd
) != 76)
1077 header
->tag1
= bfd_getb32 (buf
);
1078 header
->tag2
= bfd_getb32 (buf
+ 4);
1079 header
->current_format
= bfd_getb32 (buf
+ 8);
1080 header
->container_strings_offset
= bfd_getb32 (buf
+ 12);
1081 header
->export_hash_offset
= bfd_getb32 (buf
+ 16);
1082 header
->export_key_offset
= bfd_getb32 (buf
+ 20);
1083 header
->export_symbol_offset
= bfd_getb32 (buf
+ 24);
1084 header
->export_names_offset
= bfd_getb32 (buf
+ 28);
1085 header
->export_hash_table_power
= bfd_getb32 (buf
+ 32);
1086 header
->exported_symbol_count
= bfd_getb32 (buf
+ 36);
1087 header
->frag_name_offset
= bfd_getb32 (buf
+ 40);
1088 header
->frag_name_length
= bfd_getb32 (buf
+ 44);
1089 header
->dylib_path_offset
= bfd_getb32 (buf
+ 48);
1090 header
->dylib_path_length
= bfd_getb32 (buf
+ 52);
1091 header
->cpu_family
= bfd_getb32 (buf
+ 56);
1092 header
->cpu_model
= bfd_getb32 (buf
+ 60);
1093 header
->date_time_stamp
= bfd_getb32 (buf
+ 64);
1094 header
->current_version
= bfd_getb32 (buf
+ 68);
1095 header
->old_definition_version
= bfd_getb32 (buf
+ 72);
1096 header
->old_implementation_version
= bfd_getb32 (buf
+ 76);
1102 bfd_pef_xlib_scan (bfd
*abfd
, bfd_pef_xlib_header
*header
)
1104 bfd_pef_xlib_data_struct
*mdata
= NULL
;
1106 mdata
= bfd_alloc (abfd
, sizeof (* mdata
));
1110 mdata
->header
= *header
;
1112 abfd
->flags
= (abfd
->xvec
->object_flags
1113 | (abfd
->flags
& (BFD_IN_MEMORY
| BFD_IO_FUNCS
)));
1115 abfd
->tdata
.pef_xlib_data
= mdata
;
1120 static const bfd_target
*
1121 bfd_pef_xlib_object_p (bfd
*abfd
)
1123 struct bfd_preserve preserve
;
1124 bfd_pef_xlib_header header
;
1126 if (bfd_pef_xlib_read_header (abfd
, &header
) != 0)
1128 bfd_set_error (bfd_error_wrong_format
);
1132 if ((header
.tag1
!= BFD_PEF_XLIB_TAG1
)
1133 || ((header
.tag2
!= BFD_PEF_VLIB_TAG2
)
1134 && (header
.tag2
!= BFD_PEF_BLIB_TAG2
)))
1136 bfd_set_error (bfd_error_wrong_format
);
1140 if (! bfd_preserve_save (abfd
, &preserve
))
1142 bfd_set_error (bfd_error_wrong_format
);
1146 if (bfd_pef_xlib_scan (abfd
, &header
) != 0)
1148 bfd_preserve_restore (abfd
, &preserve
);
1149 bfd_set_error (bfd_error_wrong_format
);
1153 bfd_preserve_finish (abfd
, &preserve
);
1157 const bfd_target pef_xlib_vec
=
1159 "pef-xlib", /* Name. */
1160 bfd_target_pef_xlib_flavour
, /* Flavour. */
1161 BFD_ENDIAN_BIG
, /* Byteorder */
1162 BFD_ENDIAN_BIG
, /* Header_byteorder. */
1163 (HAS_RELOC
| EXEC_P
| /* Object flags. */
1164 HAS_LINENO
| HAS_DEBUG
|
1165 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
1166 (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_CODE
| SEC_DATA
1167 | SEC_ROM
| SEC_HAS_CONTENTS
),/* Section_flags. */
1168 0, /* Symbol_leading_char. */
1169 ' ', /* AR_pad_char. */
1170 16, /* AR_max_namelen. */
1171 0, /* match priority. */
1172 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1173 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1174 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* Data. */
1175 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1176 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1177 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* Headers. */
1178 { /* bfd_check_format. */
1180 bfd_pef_xlib_object_p
, /* bfd_check_format. */
1184 { /* bfd_set_format. */
1190 { /* bfd_write_contents. */
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
),