1 |
/* Support for the generic parts of PE/PEI, for BFD. |
/* Support for the generic parts of PE/PEI, for BFD. |
2 |
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 |
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
3 |
Free Software Foundation, Inc. |
2005 Free Software Foundation, Inc. |
4 |
Written by Cygnus Solutions. |
Written by Cygnus Solutions. |
5 |
|
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
7 |
|
|
8 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
9 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
10 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
11 |
(at your option) any later version. |
(at your option) any later version. |
12 |
|
|
13 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
14 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
GNU General Public License for more details. |
GNU General Public License for more details. |
17 |
|
|
18 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
19 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
20 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
21 |
|
|
22 |
/* |
/* Most of this hacked by Steve Chamberlain, |
|
Most of this hacked by Steve Chamberlain, |
|
23 |
sac@cygnus.com |
sac@cygnus.com |
24 |
|
|
25 |
PE/PEI rearrangement (and code added): Donn Terry |
PE/PEI rearrangement (and code added): Donn Terry |
26 |
Softway Systems, Inc. |
Softway Systems, Inc. */ |
|
*/ |
|
27 |
|
|
28 |
/* Hey look, some documentation [and in a place you expect to find it]! |
/* Hey look, some documentation [and in a place you expect to find it]! |
29 |
|
|
51 |
|
|
52 |
FIXME: Please add more docs here so the next poor fool that has to hack |
FIXME: Please add more docs here so the next poor fool that has to hack |
53 |
on this code has a chance of getting something accomplished without |
on this code has a chance of getting something accomplished without |
54 |
wasting too much time. |
wasting too much time. */ |
|
*/ |
|
55 |
|
|
56 |
#include "libpei.h" |
#include "libpei.h" |
57 |
|
|
58 |
static boolean (*pe_saved_coff_bfd_print_private_bfd_data) |
static bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) |
59 |
PARAMS ((bfd *, PTR)) = |
PARAMS ((bfd *, PTR)) = |
60 |
#ifndef coff_bfd_print_private_bfd_data |
#ifndef coff_bfd_print_private_bfd_data |
61 |
NULL; |
NULL; |
64 |
#undef coff_bfd_print_private_bfd_data |
#undef coff_bfd_print_private_bfd_data |
65 |
#endif |
#endif |
66 |
|
|
67 |
static boolean pe_print_private_bfd_data PARAMS ((bfd *, PTR)); |
static bfd_boolean pe_print_private_bfd_data PARAMS ((bfd *, PTR)); |
68 |
#define coff_bfd_print_private_bfd_data pe_print_private_bfd_data |
#define coff_bfd_print_private_bfd_data pe_print_private_bfd_data |
69 |
|
|
70 |
static boolean (*pe_saved_coff_bfd_copy_private_bfd_data) |
static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) |
71 |
PARAMS ((bfd *, bfd *)) = |
PARAMS ((bfd *, bfd *)) = |
72 |
#ifndef coff_bfd_copy_private_bfd_data |
#ifndef coff_bfd_copy_private_bfd_data |
73 |
NULL; |
NULL; |
76 |
#undef coff_bfd_copy_private_bfd_data |
#undef coff_bfd_copy_private_bfd_data |
77 |
#endif |
#endif |
78 |
|
|
79 |
static boolean pe_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *)); |
static bfd_boolean pe_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *)); |
80 |
#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data |
#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data |
81 |
|
|
82 |
#define coff_mkobject pe_mkobject |
#define coff_mkobject pe_mkobject |
88 |
#endif |
#endif |
89 |
static void coff_swap_filehdr_in PARAMS ((bfd *, PTR, PTR)); |
static void coff_swap_filehdr_in PARAMS ((bfd *, PTR, PTR)); |
90 |
static void coff_swap_scnhdr_in PARAMS ((bfd *, PTR, PTR)); |
static void coff_swap_scnhdr_in PARAMS ((bfd *, PTR, PTR)); |
91 |
static boolean pe_mkobject PARAMS ((bfd *)); |
static bfd_boolean pe_mkobject PARAMS ((bfd *)); |
92 |
static PTR pe_mkobject_hook PARAMS ((bfd *, PTR, PTR)); |
static PTR pe_mkobject_hook PARAMS ((bfd *, PTR, PTR)); |
93 |
|
|
94 |
#ifdef COFF_IMAGE_WITH_PE |
#ifdef COFF_IMAGE_WITH_PE |
130 |
struct internal_reloc * int_reltab; |
struct internal_reloc * int_reltab; |
131 |
} |
} |
132 |
pe_ILF_vars; |
pe_ILF_vars; |
|
|
|
|
static asection_ptr pe_ILF_make_a_section PARAMS ((pe_ILF_vars *, const char *, unsigned int, flagword)); |
|
|
static void pe_ILF_make_a_reloc PARAMS ((pe_ILF_vars *, bfd_vma, bfd_reloc_code_real_type, asection_ptr)); |
|
|
static void pe_ILF_make_a_symbol PARAMS ((pe_ILF_vars *, const char *, const char *, asection_ptr, flagword)); |
|
|
static void pe_ILF_save_relocs PARAMS ((pe_ILF_vars *, asection_ptr)); |
|
|
static void pe_ILF_make_a_symbol_reloc PARAMS ((pe_ILF_vars *, bfd_vma, bfd_reloc_code_real_type, struct symbol_cache_entry **, unsigned int)); |
|
|
static boolean pe_ILF_build_a_bfd PARAMS ((bfd *, unsigned int, bfd_byte *, bfd_byte *, unsigned int, unsigned int)); |
|
|
static const bfd_target * pe_ILF_object_p PARAMS ((bfd *)); |
|
|
static const bfd_target * pe_bfd_object_p PARAMS ((bfd *)); |
|
133 |
#endif /* COFF_IMAGE_WITH_PE */ |
#endif /* COFF_IMAGE_WITH_PE */ |
134 |
|
|
135 |
/**********************************************************************/ |
/**********************************************************************/ |
247 |
} |
} |
248 |
|
|
249 |
#ifndef COFF_NO_HACK_SCNHDR_SIZE |
#ifndef COFF_NO_HACK_SCNHDR_SIZE |
250 |
/* If this section holds uninitialized data, use the virtual size |
/* If this section holds uninitialized data and is from an object file |
251 |
(stored in s_paddr) instead of the physical size. */ |
or from an executable image that has not initialized the field, |
252 |
if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0 |
or if the image is an executable file and the physical size is padded, |
253 |
&& (scnhdr_int->s_paddr > 0)) |
use the virtual size (stored in s_paddr) instead. */ |
254 |
|
if (scnhdr_int->s_paddr > 0 |
255 |
|
&& (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0 |
256 |
|
&& (! bfd_pe_executable_p (abfd) || scnhdr_int->s_size == 0)) |
257 |
|
|| (bfd_pe_executable_p (abfd) && scnhdr_int->s_size > scnhdr_int->s_paddr))) |
258 |
{ |
{ |
259 |
scnhdr_int->s_size = scnhdr_int->s_paddr; |
scnhdr_int->s_size = scnhdr_int->s_paddr; |
260 |
|
|
261 |
/* This code used to set scnhdr_int->s_paddr to 0. However, |
/* This code used to set scnhdr_int->s_paddr to 0. However, |
262 |
coff_set_alignment_hook stores s_paddr in virt_size, which |
coff_set_alignment_hook stores s_paddr in virt_size, which |
263 |
only works if it correctly holds the virtual size of the |
only works if it correctly holds the virtual size of the |
266 |
#endif |
#endif |
267 |
} |
} |
268 |
|
|
269 |
static boolean |
static bfd_boolean |
270 |
pe_mkobject (abfd) |
pe_mkobject (abfd) |
271 |
bfd * abfd; |
bfd * abfd; |
272 |
{ |
{ |
276 |
abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt); |
abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt); |
277 |
|
|
278 |
if (abfd->tdata.pe_obj_data == 0) |
if (abfd->tdata.pe_obj_data == 0) |
279 |
return false; |
return FALSE; |
280 |
|
|
281 |
pe = pe_data (abfd); |
pe = pe_data (abfd); |
282 |
|
|
292 |
pe->target_subsystem = PEI_TARGET_SUBSYSTEM; |
pe->target_subsystem = PEI_TARGET_SUBSYSTEM; |
293 |
#endif |
#endif |
294 |
|
|
295 |
return true; |
return TRUE; |
296 |
} |
} |
297 |
|
|
298 |
/* Create the COFF backend specific information. */ |
/* Create the COFF backend specific information. */ |
348 |
return (PTR) pe; |
return (PTR) pe; |
349 |
} |
} |
350 |
|
|
351 |
static boolean |
static bfd_boolean |
352 |
pe_print_private_bfd_data (abfd, vfile) |
pe_print_private_bfd_data (abfd, vfile) |
353 |
bfd *abfd; |
bfd *abfd; |
354 |
PTR vfile; |
PTR vfile; |
356 |
FILE *file = (FILE *) vfile; |
FILE *file = (FILE *) vfile; |
357 |
|
|
358 |
if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile)) |
if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile)) |
359 |
return false; |
return FALSE; |
360 |
|
|
361 |
if (pe_saved_coff_bfd_print_private_bfd_data != NULL) |
if (pe_saved_coff_bfd_print_private_bfd_data != NULL) |
362 |
{ |
{ |
365 |
return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile); |
return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile); |
366 |
} |
} |
367 |
|
|
368 |
return true; |
return TRUE; |
369 |
} |
} |
370 |
|
|
371 |
/* Copy any private info we understand from the input bfd |
/* Copy any private info we understand from the input bfd |
372 |
to the output bfd. */ |
to the output bfd. */ |
373 |
|
|
374 |
static boolean |
static bfd_boolean |
375 |
pe_bfd_copy_private_bfd_data (ibfd, obfd) |
pe_bfd_copy_private_bfd_data (ibfd, obfd) |
376 |
bfd *ibfd, *obfd; |
bfd *ibfd, *obfd; |
377 |
{ |
{ |
378 |
|
/* PR binutils/716: Copy the large address aware flag. |
379 |
|
XXX: Should we be copying other flags or other fields in the pe_data() |
380 |
|
structure ? */ |
381 |
|
if (pe_data (obfd) != NULL |
382 |
|
&& pe_data (ibfd) != NULL |
383 |
|
&& pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE) |
384 |
|
pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE; |
385 |
|
|
386 |
if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd)) |
if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd)) |
387 |
return false; |
return FALSE; |
388 |
|
|
389 |
if (pe_saved_coff_bfd_copy_private_bfd_data) |
if (pe_saved_coff_bfd_copy_private_bfd_data) |
390 |
return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd); |
return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd); |
391 |
|
|
392 |
return true; |
return TRUE; |
393 |
} |
} |
394 |
|
|
395 |
#define coff_bfd_copy_private_section_data \ |
#define coff_bfd_copy_private_section_data \ |
469 |
pe_ILF_make_a_symbol_reloc (pe_ILF_vars * vars, |
pe_ILF_make_a_symbol_reloc (pe_ILF_vars * vars, |
470 |
bfd_vma address, |
bfd_vma address, |
471 |
bfd_reloc_code_real_type reloc, |
bfd_reloc_code_real_type reloc, |
472 |
struct symbol_cache_entry ** sym, |
struct bfd_symbol ** sym, |
473 |
unsigned int sym_index) |
unsigned int sym_index) |
474 |
{ |
{ |
475 |
arelent * entry; |
arelent * entry; |
486 |
internal->r_vaddr = address; |
internal->r_vaddr = address; |
487 |
internal->r_symndx = sym_index; |
internal->r_symndx = sym_index; |
488 |
internal->r_type = entry->howto->type; |
internal->r_type = entry->howto->type; |
|
#if 0 /* These fields do not need to be initialised. */ |
|
|
internal->r_size = 0; |
|
|
internal->r_extern = 0; |
|
|
internal->r_offset = 0; |
|
|
#endif |
|
489 |
|
|
490 |
vars->relcount ++; |
vars->relcount ++; |
491 |
|
|
514 |
abort (); |
abort (); |
515 |
|
|
516 |
coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab; |
coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab; |
517 |
coff_section_data (vars->abfd, sec)->keep_relocs = true; |
coff_section_data (vars->abfd, sec)->keep_relocs = TRUE; |
518 |
|
|
519 |
sec->relocation = vars->reltab; |
sec->relocation = vars->reltab; |
520 |
sec->reloc_count = vars->relcount; |
sec->reloc_count = vars->relcount; |
577 |
|
|
578 |
/* The following initialisations are unnecessary - the memory is |
/* The following initialisations are unnecessary - the memory is |
579 |
zero initialised. They are just kept here as reminders. */ |
zero initialised. They are just kept here as reminders. */ |
|
#if 0 |
|
|
esym->e.e.e_zeroes = 0; |
|
|
esym->e_value = 0; |
|
|
esym->e_type = T_NULL; |
|
|
esym->e_numaux = 0; |
|
|
#endif |
|
580 |
|
|
581 |
/* Initialise the internal symbol structure. */ |
/* Initialise the internal symbol structure. */ |
582 |
ent->u.syment.n_sclass = sclass; |
ent->u.syment.n_sclass = sclass; |
583 |
ent->u.syment.n_scnum = section->target_index; |
ent->u.syment.n_scnum = section->target_index; |
584 |
ent->u.syment._n._n_n._n_offset = (long) sym; |
ent->u.syment._n._n_n._n_offset = (long) sym; |
585 |
|
|
|
#if 0 /* See comment above. */ |
|
|
ent->u.syment.n_value = 0; |
|
|
ent->u.syment.n_flags = 0; |
|
|
ent->u.syment.n_type = T_NULL; |
|
|
ent->u.syment.n_numaux = 0; |
|
|
ent->fix_value = 0; |
|
|
#endif |
|
|
|
|
586 |
sym->symbol.the_bfd = vars->abfd; |
sym->symbol.the_bfd = vars->abfd; |
587 |
sym->symbol.name = vars->string_ptr; |
sym->symbol.name = vars->string_ptr; |
588 |
sym->symbol.flags = BSF_EXPORT | BSF_GLOBAL | extra_flags; |
sym->symbol.flags = BSF_EXPORT | BSF_GLOBAL | extra_flags; |
589 |
sym->symbol.section = section; |
sym->symbol.section = section; |
590 |
sym->native = ent; |
sym->native = ent; |
591 |
|
|
|
#if 0 /* See comment above. */ |
|
|
sym->symbol.value = 0; |
|
|
sym->symbol.udata.i = 0; |
|
|
sym->done_lineno = false; |
|
|
sym->lineno = NULL; |
|
|
#endif |
|
|
|
|
592 |
* vars->table_ptr = vars->sym_index; |
* vars->table_ptr = vars->sym_index; |
593 |
* vars->sym_ptr_ptr = sym; |
* vars->sym_ptr_ptr = sym; |
594 |
|
|
728 |
#endif |
#endif |
729 |
|
|
730 |
/* Build a full BFD from the information supplied in a ILF object. */ |
/* Build a full BFD from the information supplied in a ILF object. */ |
731 |
static boolean |
static bfd_boolean |
732 |
pe_ILF_build_a_bfd (bfd * abfd, |
pe_ILF_build_a_bfd (bfd * abfd, |
733 |
unsigned int magic, |
unsigned int magic, |
734 |
bfd_byte * symbol_name, |
char * symbol_name, |
735 |
bfd_byte * source_dll, |
char * source_dll, |
736 |
unsigned int ordinal, |
unsigned int ordinal, |
737 |
unsigned int types) |
unsigned int types) |
738 |
{ |
{ |
757 |
|
|
758 |
case IMPORT_CONST: |
case IMPORT_CONST: |
759 |
/* XXX code yet to be written. */ |
/* XXX code yet to be written. */ |
760 |
_bfd_error_handler (_("%s: Unhandled import type; %x"), |
_bfd_error_handler (_("%B: Unhandled import type; %x"), |
761 |
bfd_archive_filename (abfd), import_type); |
abfd, import_type); |
762 |
return false; |
return FALSE; |
763 |
|
|
764 |
default: |
default: |
765 |
_bfd_error_handler (_("%s: Unrecognised import type; %x"), |
_bfd_error_handler (_("%B: Unrecognised import type; %x"), |
766 |
bfd_archive_filename (abfd), import_type); |
abfd, import_type); |
767 |
return false; |
return FALSE; |
768 |
} |
} |
769 |
|
|
770 |
switch (import_name_type) |
switch (import_name_type) |
776 |
break; |
break; |
777 |
|
|
778 |
default: |
default: |
779 |
_bfd_error_handler (_("%s: Unrecognised import name type; %x"), |
_bfd_error_handler (_("%B: Unrecognised import name type; %x"), |
780 |
bfd_archive_filename (abfd), import_name_type); |
abfd, import_name_type); |
781 |
return false; |
return FALSE; |
782 |
} |
} |
783 |
|
|
784 |
/* Initialise local variables. |
/* Initialise local variables. |
790 |
so allocate all the space that we will need right now. */ |
so allocate all the space that we will need right now. */ |
791 |
ptr = bfd_zalloc (abfd, (bfd_size_type) ILF_DATA_SIZE); |
ptr = bfd_zalloc (abfd, (bfd_size_type) ILF_DATA_SIZE); |
792 |
if (ptr == NULL) |
if (ptr == NULL) |
793 |
return false; |
return FALSE; |
794 |
|
|
795 |
/* Create a bfd_in_memory structure. */ |
/* Create a bfd_in_memory structure. */ |
796 |
vars.bim = (struct bfd_in_memory *) ptr; |
vars.bim = (struct bfd_in_memory *) ptr; |
828 |
vars.int_reltab = (struct internal_reloc *) ptr; |
vars.int_reltab = (struct internal_reloc *) ptr; |
829 |
ptr += SIZEOF_ILF_INT_RELOCS; |
ptr += SIZEOF_ILF_INT_RELOCS; |
830 |
|
|
831 |
vars.string_table = ptr; |
vars.string_table = (char *) ptr; |
832 |
vars.string_ptr = ptr + STRING_SIZE_SIZE; |
vars.string_ptr = (char *) ptr + STRING_SIZE_SIZE; |
833 |
ptr += SIZEOF_ILF_STRINGS; |
ptr += SIZEOF_ILF_STRINGS; |
834 |
vars.end_string_ptr = ptr; |
vars.end_string_ptr = (char *) ptr; |
835 |
|
|
836 |
/* The remaining space in bim->buffer is used |
/* The remaining space in bim->buffer is used |
837 |
by the pe_ILF_make_a_section() function. */ |
by the pe_ILF_make_a_section() function. */ |
850 |
id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0); |
id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0); |
851 |
id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0); |
id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0); |
852 |
if (id4 == NULL || id5 == NULL) |
if (id4 == NULL || id5 == NULL) |
853 |
return false; |
return FALSE; |
854 |
|
|
855 |
/* Fill in the contents of these sections. */ |
/* Fill in the contents of these sections. */ |
856 |
if (import_name_type == IMPORT_ORDINAL) |
if (import_name_type == IMPORT_ORDINAL) |
865 |
else |
else |
866 |
{ |
{ |
867 |
char * symbol; |
char * symbol; |
868 |
|
unsigned int len; |
869 |
|
|
870 |
/* Create .idata$6 - the Hint Name Table. */ |
/* Create .idata$6 - the Hint Name Table. */ |
871 |
id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0); |
id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0); |
872 |
if (id6 == NULL) |
if (id6 == NULL) |
873 |
return false; |
return FALSE; |
874 |
|
|
875 |
/* If necessary, trim the import symbol name. */ |
/* If necessary, trim the import symbol name. */ |
876 |
symbol = symbol_name; |
symbol = symbol_name; |
877 |
|
|
878 |
if (import_name_type != IMPORT_NAME) |
if (import_name_type != IMPORT_NAME) |
879 |
/* Skip any prefix in symbol_name. */ |
{ |
880 |
while (*symbol == '@' || * symbol == '?' || * symbol == '_') |
bfd_boolean skipped_leading_underscore = FALSE; |
881 |
++ symbol; |
bfd_boolean skipped_leading_at = FALSE; |
882 |
|
bfd_boolean skipped_leading_question_mark = FALSE; |
883 |
|
bfd_boolean check_again; |
884 |
|
|
885 |
|
/* Skip any prefix in symbol_name. */ |
886 |
|
-- symbol; |
887 |
|
do |
888 |
|
{ |
889 |
|
check_again = FALSE; |
890 |
|
++ symbol; |
891 |
|
|
892 |
|
switch (*symbol) |
893 |
|
{ |
894 |
|
case '@': |
895 |
|
if (! skipped_leading_at) |
896 |
|
check_again = skipped_leading_at = TRUE; |
897 |
|
break; |
898 |
|
case '?': |
899 |
|
if (! skipped_leading_question_mark) |
900 |
|
check_again = skipped_leading_question_mark = TRUE; |
901 |
|
break; |
902 |
|
case '_': |
903 |
|
if (! skipped_leading_underscore) |
904 |
|
check_again = skipped_leading_underscore = TRUE; |
905 |
|
break; |
906 |
|
default: |
907 |
|
break; |
908 |
|
} |
909 |
|
} |
910 |
|
while (check_again); |
911 |
|
} |
912 |
|
|
913 |
|
len = strlen (symbol); |
914 |
if (import_name_type == IMPORT_NAME_UNDECORATE) |
if (import_name_type == IMPORT_NAME_UNDECORATE) |
915 |
{ |
{ |
916 |
/* Truncate at the first '@' */ |
/* Truncate at the first '@'. */ |
917 |
while (* symbol != 0 && * symbol != '@') |
char *at = strchr (symbol, '@'); |
|
symbol ++; |
|
918 |
|
|
919 |
* symbol = 0; |
if (at != NULL) |
920 |
|
len = at - symbol; |
921 |
} |
} |
922 |
|
|
923 |
id6->contents[0] = ordinal & 0xff; |
id6->contents[0] = ordinal & 0xff; |
924 |
id6->contents[1] = ordinal >> 8; |
id6->contents[1] = ordinal >> 8; |
925 |
|
|
926 |
strcpy (id6->contents + 2, symbol); |
memcpy ((char *) id6->contents + 2, symbol, len); |
927 |
|
id6->contents[len + 2] = '\0'; |
928 |
} |
} |
929 |
|
|
930 |
if (import_name_type != IMPORT_ORDINAL) |
if (import_name_type != IMPORT_ORDINAL) |
958 |
/* Create the .text section. */ |
/* Create the .text section. */ |
959 |
text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE); |
text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE); |
960 |
if (text == NULL) |
if (text == NULL) |
961 |
return false; |
return FALSE; |
962 |
|
|
963 |
/* Copy in the jump code. */ |
/* Copy in the jump code. */ |
964 |
memcpy (text->contents, jtab[i].data, jtab[i].size); |
memcpy (text->contents, jtab[i].data, jtab[i].size); |
973 |
if (magic == MIPS_ARCH_MAGIC_WINCE) |
if (magic == MIPS_ARCH_MAGIC_WINCE) |
974 |
{ |
{ |
975 |
pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S, |
pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S, |
976 |
(struct symbol_cache_entry **) imp_sym, |
(struct bfd_symbol **) imp_sym, |
977 |
imp_index); |
imp_index); |
978 |
pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text); |
pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text); |
979 |
pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16, |
pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16, |
980 |
(struct symbol_cache_entry **) imp_sym, |
(struct bfd_symbol **) imp_sym, |
981 |
imp_index); |
imp_index); |
982 |
} |
} |
983 |
else |
else |
1007 |
|
|
1008 |
if ( ! bfd_set_start_address (abfd, (bfd_vma) 0) |
if ( ! bfd_set_start_address (abfd, (bfd_vma) 0) |
1009 |
|| ! bfd_coff_set_arch_mach_hook (abfd, & internal_f)) |
|| ! bfd_coff_set_arch_mach_hook (abfd, & internal_f)) |
1010 |
return false; |
return FALSE; |
1011 |
|
|
1012 |
if (bfd_coff_mkobject_hook (abfd, (PTR) & internal_f, NULL) == NULL) |
if (bfd_coff_mkobject_hook (abfd, (PTR) & internal_f, NULL) == NULL) |
1013 |
return false; |
return FALSE; |
1014 |
|
|
1015 |
coff_data (abfd)->pe = 1; |
coff_data (abfd)->pe = 1; |
1016 |
#ifdef THUMBPEMAGIC |
#ifdef THUMBPEMAGIC |
1036 |
|
|
1037 |
/* Create an import symbol for the DLL, without the |
/* Create an import symbol for the DLL, without the |
1038 |
.dll suffix. */ |
.dll suffix. */ |
1039 |
ptr = strrchr (source_dll, '.'); |
ptr = (bfd_byte *) strrchr (source_dll, '.'); |
1040 |
if (ptr) |
if (ptr) |
1041 |
* ptr = 0; |
* ptr = 0; |
1042 |
pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0); |
pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0); |
1061 |
obj_raw_syment_count (abfd) = vars.sym_index; |
obj_raw_syment_count (abfd) = vars.sym_index; |
1062 |
|
|
1063 |
obj_coff_external_syms (abfd) = (PTR) vars.esym_table; |
obj_coff_external_syms (abfd) = (PTR) vars.esym_table; |
1064 |
obj_coff_keep_syms (abfd) = true; |
obj_coff_keep_syms (abfd) = TRUE; |
1065 |
|
|
1066 |
obj_convert (abfd) = vars.sym_table; |
obj_convert (abfd) = vars.sym_table; |
1067 |
obj_conv_table_size (abfd) = vars.sym_index; |
obj_conv_table_size (abfd) = vars.sym_index; |
1068 |
|
|
1069 |
obj_coff_strings (abfd) = vars.string_table; |
obj_coff_strings (abfd) = vars.string_table; |
1070 |
obj_coff_keep_strings (abfd) = true; |
obj_coff_keep_strings (abfd) = TRUE; |
1071 |
|
|
1072 |
abfd->flags |= HAS_SYMS; |
abfd->flags |= HAS_SYMS; |
1073 |
|
|
1074 |
return true; |
return TRUE; |
1075 |
} |
} |
1076 |
|
|
1077 |
/* We have detected a Image Library Format archive element. |
/* We have detected a Image Library Format archive element. |
1081 |
{ |
{ |
1082 |
bfd_byte buffer[16]; |
bfd_byte buffer[16]; |
1083 |
bfd_byte * ptr; |
bfd_byte * ptr; |
1084 |
bfd_byte * symbol_name; |
char * symbol_name; |
1085 |
bfd_byte * source_dll; |
char * source_dll; |
1086 |
unsigned int machine; |
unsigned int machine; |
1087 |
bfd_size_type size; |
bfd_size_type size; |
1088 |
unsigned int ordinal; |
unsigned int ordinal; |
1166 |
/* We no longer support PowerPC. */ |
/* We no longer support PowerPC. */ |
1167 |
default: |
default: |
1168 |
_bfd_error_handler |
_bfd_error_handler |
1169 |
( |
(_("%B: Unrecognised machine type (0x%x)" |
1170 |
_("%s: Unrecognised machine type (0x%x) in Import Library Format archive"), |
" in Import Library Format archive"), |
1171 |
bfd_archive_filename (abfd), machine); |
abfd, machine); |
1172 |
bfd_set_error (bfd_error_malformed_archive); |
bfd_set_error (bfd_error_malformed_archive); |
1173 |
|
|
1174 |
return NULL; |
return NULL; |
1178 |
if (magic == 0) |
if (magic == 0) |
1179 |
{ |
{ |
1180 |
_bfd_error_handler |
_bfd_error_handler |
1181 |
( |
(_("%B: Recognised but unhandled machine type (0x%x)" |
1182 |
_("%s: Recognised but unhandled machine type (0x%x) in Import Library Format archive"), |
" in Import Library Format archive"), |
1183 |
bfd_archive_filename (abfd), machine); |
abfd, machine); |
1184 |
bfd_set_error (bfd_error_wrong_format); |
bfd_set_error (bfd_error_wrong_format); |
1185 |
|
|
1186 |
return NULL; |
return NULL; |
1196 |
if (size == 0) |
if (size == 0) |
1197 |
{ |
{ |
1198 |
_bfd_error_handler |
_bfd_error_handler |
1199 |
(_("%s: size field is zero in Import Library Format header"), |
(_("%B: size field is zero in Import Library Format header"), abfd); |
|
bfd_archive_filename (abfd)); |
|
1200 |
bfd_set_error (bfd_error_malformed_archive); |
bfd_set_error (bfd_error_malformed_archive); |
1201 |
|
|
1202 |
return NULL; |
return NULL; |
1214 |
return NULL; |
return NULL; |
1215 |
|
|
1216 |
if (bfd_bread (ptr, size, abfd) != size) |
if (bfd_bread (ptr, size, abfd) != size) |
1217 |
return NULL; |
{ |
1218 |
|
bfd_release (abfd, ptr); |
1219 |
|
return NULL; |
1220 |
|
} |
1221 |
|
|
1222 |
symbol_name = ptr; |
symbol_name = (char *) ptr; |
1223 |
source_dll = ptr + strlen (ptr) + 1; |
source_dll = symbol_name + strlen (symbol_name) + 1; |
1224 |
|
|
1225 |
/* Verify that the strings are null terminated. */ |
/* Verify that the strings are null terminated. */ |
1226 |
if (ptr[size - 1] != 0 || ((unsigned long) (source_dll - ptr) >= size)) |
if (ptr[size - 1] != 0 |
1227 |
|
|| (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size) |
1228 |
{ |
{ |
1229 |
_bfd_error_handler |
_bfd_error_handler |
1230 |
(_("%s: string not null terminated in ILF object file."), |
(_("%B: string not null terminated in ILF object file."), abfd); |
|
bfd_archive_filename (abfd)); |
|
1231 |
bfd_set_error (bfd_error_malformed_archive); |
bfd_set_error (bfd_error_malformed_archive); |
1232 |
|
bfd_release (abfd, ptr); |
1233 |
return NULL; |
return NULL; |
1234 |
} |
} |
1235 |
|
|
1236 |
/* Now construct the bfd. */ |
/* Now construct the bfd. */ |
1237 |
if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name, |
if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name, |
1238 |
source_dll, ordinal, types)) |
source_dll, ordinal, types)) |
1239 |
return NULL; |
{ |
1240 |
|
bfd_release (abfd, ptr); |
1241 |
|
return NULL; |
1242 |
|
} |
1243 |
|
|
1244 |
return abfd->xvec; |
return abfd->xvec; |
1245 |
} |
} |