184865Sobrien/* Support for the generic parts of PE/PEI, for BFD. 2218822Sdim Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 3218822Sdim 2005, 2006 Free Software Foundation, Inc. 484865Sobrien Written by Cygnus Solutions. 584865Sobrien 6130561Sobrien This file is part of BFD, the Binary File Descriptor library. 784865Sobrien 8130561Sobrien This program is free software; you can redistribute it and/or modify 9130561Sobrien it under the terms of the GNU General Public License as published by 10130561Sobrien the Free Software Foundation; either version 2 of the License, or 11130561Sobrien (at your option) any later version. 1284865Sobrien 13130561Sobrien This program is distributed in the hope that it will be useful, 14130561Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 15130561Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16130561Sobrien GNU General Public License for more details. 1784865Sobrien 18130561Sobrien You should have received a copy of the GNU General Public License 19130561Sobrien along with this program; if not, write to the Free Software 20218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2184865Sobrien 22130561Sobrien/* Most of this hacked by Steve Chamberlain, 2384865Sobrien sac@cygnus.com 2484865Sobrien 25130561Sobrien PE/PEI rearrangement (and code added): Donn Terry 26130561Sobrien Softway Systems, Inc. */ 2784865Sobrien 2884865Sobrien/* Hey look, some documentation [and in a place you expect to find it]! 2984865Sobrien 3084865Sobrien The main reference for the pei format is "Microsoft Portable Executable 3184865Sobrien and Common Object File Format Specification 4.1". Get it if you need to 3284865Sobrien do some serious hacking on this code. 3384865Sobrien 3484865Sobrien Another reference: 3584865Sobrien "Peering Inside the PE: A Tour of the Win32 Portable Executable 3684865Sobrien File Format", MSJ 1994, Volume 9. 3784865Sobrien 3884865Sobrien The *sole* difference between the pe format and the pei format is that the 3984865Sobrien latter has an MSDOS 2.0 .exe header on the front that prints the message 4084865Sobrien "This app must be run under Windows." (or some such). 4184865Sobrien (FIXME: Whether that statement is *really* true or not is unknown. 4284865Sobrien Are there more subtle differences between pe and pei formats? 4384865Sobrien For now assume there aren't. If you find one, then for God sakes 4484865Sobrien document it here!) 4584865Sobrien 4684865Sobrien The Microsoft docs use the word "image" instead of "executable" because 4784865Sobrien the former can also refer to a DLL (shared library). Confusion can arise 4884865Sobrien because the `i' in `pei' also refers to "image". The `pe' format can 4984865Sobrien also create images (i.e. executables), it's just that to run on a win32 5084865Sobrien system you need to use the pei format. 5184865Sobrien 5284865Sobrien FIXME: Please add more docs here so the next poor fool that has to hack 5384865Sobrien on this code has a chance of getting something accomplished without 54130561Sobrien wasting too much time. */ 5584865Sobrien 5684865Sobrien#include "libpei.h" 5784865Sobrien 58218822Sdimstatic bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) = 5984865Sobrien#ifndef coff_bfd_print_private_bfd_data 6084865Sobrien NULL; 6184865Sobrien#else 6284865Sobrien coff_bfd_print_private_bfd_data; 6384865Sobrien#undef coff_bfd_print_private_bfd_data 6484865Sobrien#endif 6584865Sobrien 66218822Sdimstatic bfd_boolean pe_print_private_bfd_data (bfd *, void *); 6784865Sobrien#define coff_bfd_print_private_bfd_data pe_print_private_bfd_data 6884865Sobrien 69218822Sdimstatic bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) = 7084865Sobrien#ifndef coff_bfd_copy_private_bfd_data 7184865Sobrien NULL; 7284865Sobrien#else 7384865Sobrien coff_bfd_copy_private_bfd_data; 7484865Sobrien#undef coff_bfd_copy_private_bfd_data 7584865Sobrien#endif 7684865Sobrien 77218822Sdimstatic bfd_boolean pe_bfd_copy_private_bfd_data (bfd *, bfd *); 7884865Sobrien#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data 7984865Sobrien 8084865Sobrien#define coff_mkobject pe_mkobject 8184865Sobrien#define coff_mkobject_hook pe_mkobject_hook 8284865Sobrien 8384865Sobrien#ifdef COFF_IMAGE_WITH_PE 8484865Sobrien/* This structure contains static variables used by the ILF code. */ 8584865Sobrientypedef asection * asection_ptr; 8684865Sobrien 8784865Sobrientypedef struct 8884865Sobrien{ 8984865Sobrien bfd * abfd; 9084865Sobrien bfd_byte * data; 9184865Sobrien struct bfd_in_memory * bim; 9284865Sobrien unsigned short magic; 9384865Sobrien 9484865Sobrien arelent * reltab; 9584865Sobrien unsigned int relcount; 9684865Sobrien 9784865Sobrien coff_symbol_type * sym_cache; 9884865Sobrien coff_symbol_type * sym_ptr; 9984865Sobrien unsigned int sym_index; 10084865Sobrien 10184865Sobrien unsigned int * sym_table; 10284865Sobrien unsigned int * table_ptr; 10384865Sobrien 10484865Sobrien combined_entry_type * native_syms; 10584865Sobrien combined_entry_type * native_ptr; 10684865Sobrien 10784865Sobrien coff_symbol_type ** sym_ptr_table; 10884865Sobrien coff_symbol_type ** sym_ptr_ptr; 10984865Sobrien 11084865Sobrien unsigned int sec_index; 11184865Sobrien 11284865Sobrien char * string_table; 11384865Sobrien char * string_ptr; 11484865Sobrien char * end_string_ptr; 11584865Sobrien 11684865Sobrien SYMENT * esym_table; 11784865Sobrien SYMENT * esym_ptr; 11884865Sobrien 11984865Sobrien struct internal_reloc * int_reltab; 12084865Sobrien} 12184865Sobrienpe_ILF_vars; 12284865Sobrien#endif /* COFF_IMAGE_WITH_PE */ 123218822Sdim 12484865Sobrien#ifndef NO_COFF_RELOCS 12584865Sobrienstatic void 126218822Sdimcoff_swap_reloc_in (bfd * abfd, void * src, void * dst) 12784865Sobrien{ 12884865Sobrien RELOC *reloc_src = (RELOC *) src; 12984865Sobrien struct internal_reloc *reloc_dst = (struct internal_reloc *) dst; 13084865Sobrien 131218822Sdim reloc_dst->r_vaddr = H_GET_32 (abfd, reloc_src->r_vaddr); 13294536Sobrien reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx); 133218822Sdim reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type); 13484865Sobrien#ifdef SWAP_IN_RELOC_OFFSET 13594536Sobrien reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset); 13684865Sobrien#endif 13784865Sobrien} 13884865Sobrien 13984865Sobrienstatic unsigned int 140218822Sdimcoff_swap_reloc_out (bfd * abfd, void * src, void * dst) 14184865Sobrien{ 142218822Sdim struct internal_reloc *reloc_src = (struct internal_reloc *) src; 143218822Sdim struct external_reloc *reloc_dst = (struct external_reloc *) dst; 144218822Sdim 14594536Sobrien H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr); 14694536Sobrien H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx); 14794536Sobrien H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type); 14884865Sobrien 149218822Sdim#ifdef SWAP_OUT_RELOC_OFFSET 15094536Sobrien SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset); 15184865Sobrien#endif 15284865Sobrien#ifdef SWAP_OUT_RELOC_EXTRA 153218822Sdim SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst); 15484865Sobrien#endif 15584865Sobrien return RELSZ; 15684865Sobrien} 15784865Sobrien#endif /* not NO_COFF_RELOCS */ 15884865Sobrien 15984865Sobrienstatic void 160218822Sdimcoff_swap_filehdr_in (bfd * abfd, void * src, void * dst) 16184865Sobrien{ 16284865Sobrien FILHDR *filehdr_src = (FILHDR *) src; 16384865Sobrien struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst; 16484865Sobrien 165218822Sdim filehdr_dst->f_magic = H_GET_16 (abfd, filehdr_src->f_magic); 166218822Sdim filehdr_dst->f_nscns = H_GET_16 (abfd, filehdr_src->f_nscns); 167218822Sdim filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat); 168218822Sdim filehdr_dst->f_nsyms = H_GET_32 (abfd, filehdr_src->f_nsyms); 169218822Sdim filehdr_dst->f_flags = H_GET_16 (abfd, filehdr_src->f_flags); 17094536Sobrien filehdr_dst->f_symptr = H_GET_32 (abfd, filehdr_src->f_symptr); 17184865Sobrien 17284865Sobrien /* Other people's tools sometimes generate headers with an nsyms but 17384865Sobrien a zero symptr. */ 17484865Sobrien if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0) 17584865Sobrien { 17684865Sobrien filehdr_dst->f_nsyms = 0; 17784865Sobrien filehdr_dst->f_flags |= F_LSYMS; 17884865Sobrien } 17984865Sobrien 18094536Sobrien filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src-> f_opthdr); 18184865Sobrien} 18284865Sobrien 18384865Sobrien#ifdef COFF_IMAGE_WITH_PE 18484865Sobrien# define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out 185218822Sdim#elif defined COFF_WITH_pex64 186218822Sdim# define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out 187218822Sdim#elif defined COFF_WITH_pep 188218822Sdim# define coff_swap_filehdr_out _bfd_pep_only_swap_filehdr_out 18984865Sobrien#else 19084865Sobrien# define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out 19184865Sobrien#endif 19284865Sobrien 19384865Sobrienstatic void 194218822Sdimcoff_swap_scnhdr_in (bfd * abfd, void * ext, void * in) 19584865Sobrien{ 19684865Sobrien SCNHDR *scnhdr_ext = (SCNHDR *) ext; 19784865Sobrien struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in; 19884865Sobrien 199218822Sdim memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name)); 200218822Sdim 201218822Sdim scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr); 202218822Sdim scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr); 203218822Sdim scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size); 204218822Sdim scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr); 205218822Sdim scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr); 20694536Sobrien scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr); 207218822Sdim scnhdr_int->s_flags = H_GET_32 (abfd, scnhdr_ext->s_flags); 20884865Sobrien 20984865Sobrien /* MS handles overflow of line numbers by carrying into the reloc 21084865Sobrien field (it appears). Since it's supposed to be zero for PE 21184865Sobrien *IMAGE* format, that's safe. This is still a bit iffy. */ 21284865Sobrien#ifdef COFF_IMAGE_WITH_PE 21394536Sobrien scnhdr_int->s_nlnno = (H_GET_16 (abfd, scnhdr_ext->s_nlnno) 21494536Sobrien + (H_GET_16 (abfd, scnhdr_ext->s_nreloc) << 16)); 21584865Sobrien scnhdr_int->s_nreloc = 0; 21684865Sobrien#else 21794536Sobrien scnhdr_int->s_nreloc = H_GET_16 (abfd, scnhdr_ext->s_nreloc); 21894536Sobrien scnhdr_int->s_nlnno = H_GET_16 (abfd, scnhdr_ext->s_nlnno); 21984865Sobrien#endif 22084865Sobrien 22184865Sobrien if (scnhdr_int->s_vaddr != 0) 22284865Sobrien { 22384865Sobrien scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase; 224218822Sdim /* Do not cut upper 32-bits for 64-bit vma. */ 225218822Sdim#ifndef COFF_WITH_pex64 22684865Sobrien scnhdr_int->s_vaddr &= 0xffffffff; 227218822Sdim#endif 22884865Sobrien } 22984865Sobrien 23084865Sobrien#ifndef COFF_NO_HACK_SCNHDR_SIZE 231130561Sobrien /* If this section holds uninitialized data and is from an object file 232130561Sobrien or from an executable image that has not initialized the field, 233130561Sobrien or if the image is an executable file and the physical size is padded, 234130561Sobrien use the virtual size (stored in s_paddr) instead. */ 235130561Sobrien if (scnhdr_int->s_paddr > 0 236130561Sobrien && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0 237130561Sobrien && (! bfd_pe_executable_p (abfd) || scnhdr_int->s_size == 0)) 238130561Sobrien || (bfd_pe_executable_p (abfd) && scnhdr_int->s_size > scnhdr_int->s_paddr))) 239218822Sdim /* This code used to set scnhdr_int->s_paddr to 0. However, 240218822Sdim coff_set_alignment_hook stores s_paddr in virt_size, which 241218822Sdim only works if it correctly holds the virtual size of the 242218822Sdim section. */ 243218822Sdim scnhdr_int->s_size = scnhdr_int->s_paddr; 24484865Sobrien#endif 24584865Sobrien} 24684865Sobrien 247130561Sobrienstatic bfd_boolean 248218822Sdimpe_mkobject (bfd * abfd) 24984865Sobrien{ 25084865Sobrien pe_data_type *pe; 25194536Sobrien bfd_size_type amt = sizeof (pe_data_type); 25284865Sobrien 25394536Sobrien abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt); 25494536Sobrien 25584865Sobrien if (abfd->tdata.pe_obj_data == 0) 256130561Sobrien return FALSE; 25784865Sobrien 25884865Sobrien pe = pe_data (abfd); 25984865Sobrien 26084865Sobrien pe->coff.pe = 1; 26184865Sobrien 26284865Sobrien /* in_reloc_p is architecture dependent. */ 26384865Sobrien pe->in_reloc_p = in_reloc_p; 26484865Sobrien 26584865Sobrien#ifdef PEI_FORCE_MINIMUM_ALIGNMENT 26684865Sobrien pe->force_minimum_alignment = 1; 26784865Sobrien#endif 26884865Sobrien#ifdef PEI_TARGET_SUBSYSTEM 26984865Sobrien pe->target_subsystem = PEI_TARGET_SUBSYSTEM; 27084865Sobrien#endif 27184865Sobrien 272130561Sobrien return TRUE; 27384865Sobrien} 27484865Sobrien 27584865Sobrien/* Create the COFF backend specific information. */ 276218822Sdim 277218822Sdimstatic void * 278218822Sdimpe_mkobject_hook (bfd * abfd, 279218822Sdim void * filehdr, 280218822Sdim void * aouthdr ATTRIBUTE_UNUSED) 28184865Sobrien{ 28284865Sobrien struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; 28384865Sobrien pe_data_type *pe; 28484865Sobrien 285107492Sobrien if (! pe_mkobject (abfd)) 28684865Sobrien return NULL; 28784865Sobrien 28884865Sobrien pe = pe_data (abfd); 28984865Sobrien pe->coff.sym_filepos = internal_f->f_symptr; 29084865Sobrien /* These members communicate important constants about the symbol 29184865Sobrien table to GDB's symbol-reading code. These `constants' 29284865Sobrien unfortunately vary among coff implementations... */ 29384865Sobrien pe->coff.local_n_btmask = N_BTMASK; 29484865Sobrien pe->coff.local_n_btshft = N_BTSHFT; 29584865Sobrien pe->coff.local_n_tmask = N_TMASK; 29684865Sobrien pe->coff.local_n_tshift = N_TSHIFT; 29784865Sobrien pe->coff.local_symesz = SYMESZ; 29884865Sobrien pe->coff.local_auxesz = AUXESZ; 29984865Sobrien pe->coff.local_linesz = LINESZ; 30084865Sobrien 30184865Sobrien pe->coff.timestamp = internal_f->f_timdat; 30284865Sobrien 30384865Sobrien obj_raw_syment_count (abfd) = 30484865Sobrien obj_conv_table_size (abfd) = 30584865Sobrien internal_f->f_nsyms; 30684865Sobrien 30784865Sobrien pe->real_flags = internal_f->f_flags; 30884865Sobrien 30984865Sobrien if ((internal_f->f_flags & F_DLL) != 0) 31084865Sobrien pe->dll = 1; 31184865Sobrien 31284865Sobrien if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0) 31384865Sobrien abfd->flags |= HAS_DEBUG; 31484865Sobrien 31584865Sobrien#ifdef COFF_IMAGE_WITH_PE 31684865Sobrien if (aouthdr) 317218822Sdim pe->pe_opthdr = ((struct internal_aouthdr *) aouthdr)->pe; 31884865Sobrien#endif 31984865Sobrien 32084865Sobrien#ifdef ARM 32184865Sobrien if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags)) 32284865Sobrien coff_data (abfd) ->flags = 0; 32384865Sobrien#endif 32484865Sobrien 325218822Sdim return (void *) pe; 32684865Sobrien} 32784865Sobrien 328130561Sobrienstatic bfd_boolean 329218822Sdimpe_print_private_bfd_data (bfd *abfd, void * vfile) 33084865Sobrien{ 33184865Sobrien FILE *file = (FILE *) vfile; 33284865Sobrien 33384865Sobrien if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile)) 334130561Sobrien return FALSE; 33584865Sobrien 336218822Sdim if (pe_saved_coff_bfd_print_private_bfd_data == NULL) 337218822Sdim return TRUE; 33884865Sobrien 339218822Sdim fputc ('\n', file); 34084865Sobrien 341218822Sdim return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile); 34284865Sobrien} 34384865Sobrien 34484865Sobrien/* Copy any private info we understand from the input bfd 34584865Sobrien to the output bfd. */ 34684865Sobrien 347130561Sobrienstatic bfd_boolean 348218822Sdimpe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd) 34984865Sobrien{ 350218822Sdim /* PR binutils/716: Copy the large address aware flag. 351218822Sdim XXX: Should we be copying other flags or other fields in the pe_data() 352218822Sdim structure ? */ 353218822Sdim if (pe_data (obfd) != NULL 354218822Sdim && pe_data (ibfd) != NULL 355218822Sdim && pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE) 356218822Sdim pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE; 357218822Sdim 35884865Sobrien if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd)) 359130561Sobrien return FALSE; 36084865Sobrien 36184865Sobrien if (pe_saved_coff_bfd_copy_private_bfd_data) 36284865Sobrien return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd); 36384865Sobrien 364130561Sobrien return TRUE; 36584865Sobrien} 36684865Sobrien 36784865Sobrien#define coff_bfd_copy_private_section_data \ 36884865Sobrien _bfd_XX_bfd_copy_private_section_data 36984865Sobrien 37084865Sobrien#define coff_get_symbol_info _bfd_XX_get_symbol_info 37184865Sobrien 37284865Sobrien#ifdef COFF_IMAGE_WITH_PE 37384865Sobrien 37484865Sobrien/* Code to handle Microsoft's Image Library Format. 37584865Sobrien Also known as LINK6 format. 37684865Sobrien Documentation about this format can be found at: 37784865Sobrien 37884865Sobrien http://msdn.microsoft.com/library/specs/pecoff_section8.htm */ 37984865Sobrien 38084865Sobrien/* The following constants specify the sizes of the various data 38184865Sobrien structures that we have to create in order to build a bfd describing 38284865Sobrien an ILF object file. The final "+ 1" in the definitions of SIZEOF_IDATA6 38384865Sobrien and SIZEOF_IDATA7 below is to allow for the possibility that we might 38484865Sobrien need a padding byte in order to ensure 16 bit alignment for the section's 38584865Sobrien contents. 38684865Sobrien 38784865Sobrien The value for SIZEOF_ILF_STRINGS is computed as follows: 38884865Sobrien 38984865Sobrien There will be NUM_ILF_SECTIONS section symbols. Allow 9 characters 39084865Sobrien per symbol for their names (longest section name is .idata$x). 39184865Sobrien 39284865Sobrien There will be two symbols for the imported value, one the symbol name 39384865Sobrien and one with _imp__ prefixed. Allowing for the terminating nul's this 39484865Sobrien is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll). 39584865Sobrien 39684865Sobrien The strings in the string table must start STRING__SIZE_SIZE bytes into 39784865Sobrien the table in order to for the string lookup code in coffgen/coffcode to 39884865Sobrien work. */ 39984865Sobrien#define NUM_ILF_RELOCS 8 40084865Sobrien#define NUM_ILF_SECTIONS 6 40184865Sobrien#define NUM_ILF_SYMS (2 + NUM_ILF_SECTIONS) 40284865Sobrien 403218822Sdim#define SIZEOF_ILF_SYMS (NUM_ILF_SYMS * sizeof (* vars.sym_cache)) 404218822Sdim#define SIZEOF_ILF_SYM_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_table)) 405218822Sdim#define SIZEOF_ILF_NATIVE_SYMS (NUM_ILF_SYMS * sizeof (* vars.native_syms)) 40684865Sobrien#define SIZEOF_ILF_SYM_PTR_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_ptr_table)) 407218822Sdim#define SIZEOF_ILF_EXT_SYMS (NUM_ILF_SYMS * sizeof (* vars.esym_table)) 408218822Sdim#define SIZEOF_ILF_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.reltab)) 409218822Sdim#define SIZEOF_ILF_INT_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.int_reltab)) 410218822Sdim#define SIZEOF_ILF_STRINGS (strlen (symbol_name) * 2 + 8 \ 41184865Sobrien + 21 + strlen (source_dll) \ 41284865Sobrien + NUM_ILF_SECTIONS * 9 \ 41384865Sobrien + STRING_SIZE_SIZE) 41484865Sobrien#define SIZEOF_IDATA2 (5 * 4) 415218822Sdim 416218822Sdim/* For PEx64 idata4 & 5 have thumb size of 8 bytes. */ 417218822Sdim#ifdef COFF_WITH_pex64 418218822Sdim#define SIZEOF_IDATA4 (2 * 4) 419218822Sdim#define SIZEOF_IDATA5 (2 * 4) 420218822Sdim#else 42184865Sobrien#define SIZEOF_IDATA4 (1 * 4) 42284865Sobrien#define SIZEOF_IDATA5 (1 * 4) 423218822Sdim#endif 424218822Sdim 42584865Sobrien#define SIZEOF_IDATA6 (2 + strlen (symbol_name) + 1 + 1) 42684865Sobrien#define SIZEOF_IDATA7 (strlen (source_dll) + 1 + 1) 42784865Sobrien#define SIZEOF_ILF_SECTIONS (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata)) 42884865Sobrien 42984865Sobrien#define ILF_DATA_SIZE \ 43084865Sobrien sizeof (* vars.bim) \ 43184865Sobrien + SIZEOF_ILF_SYMS \ 43284865Sobrien + SIZEOF_ILF_SYM_TABLE \ 43384865Sobrien + SIZEOF_ILF_NATIVE_SYMS \ 43484865Sobrien + SIZEOF_ILF_SYM_PTR_TABLE \ 43584865Sobrien + SIZEOF_ILF_EXT_SYMS \ 43684865Sobrien + SIZEOF_ILF_RELOCS \ 43784865Sobrien + SIZEOF_ILF_INT_RELOCS \ 43884865Sobrien + SIZEOF_ILF_STRINGS \ 43984865Sobrien + SIZEOF_IDATA2 \ 44084865Sobrien + SIZEOF_IDATA4 \ 44184865Sobrien + SIZEOF_IDATA5 \ 44284865Sobrien + SIZEOF_IDATA6 \ 44384865Sobrien + SIZEOF_IDATA7 \ 44484865Sobrien + SIZEOF_ILF_SECTIONS \ 44584865Sobrien + MAX_TEXT_SECTION_SIZE 44684865Sobrien 44784865Sobrien/* Create an empty relocation against the given symbol. */ 448218822Sdim 44984865Sobrienstatic void 450218822Sdimpe_ILF_make_a_symbol_reloc (pe_ILF_vars * vars, 451218822Sdim bfd_vma address, 452218822Sdim bfd_reloc_code_real_type reloc, 453218822Sdim struct bfd_symbol ** sym, 454218822Sdim unsigned int sym_index) 45584865Sobrien{ 45684865Sobrien arelent * entry; 45784865Sobrien struct internal_reloc * internal; 45884865Sobrien 45984865Sobrien entry = vars->reltab + vars->relcount; 46084865Sobrien internal = vars->int_reltab + vars->relcount; 46184865Sobrien 46284865Sobrien entry->address = address; 46384865Sobrien entry->addend = 0; 46484865Sobrien entry->howto = bfd_reloc_type_lookup (vars->abfd, reloc); 46584865Sobrien entry->sym_ptr_ptr = sym; 46684865Sobrien 46784865Sobrien internal->r_vaddr = address; 46884865Sobrien internal->r_symndx = sym_index; 46984865Sobrien internal->r_type = entry->howto->type; 47084865Sobrien 47184865Sobrien vars->relcount ++; 47284865Sobrien 47384865Sobrien BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS); 47484865Sobrien} 47584865Sobrien 47684865Sobrien/* Create an empty relocation against the given section. */ 477218822Sdim 47884865Sobrienstatic void 47984865Sobrienpe_ILF_make_a_reloc (pe_ILF_vars * vars, 48084865Sobrien bfd_vma address, 48184865Sobrien bfd_reloc_code_real_type reloc, 48284865Sobrien asection_ptr sec) 48384865Sobrien{ 48484865Sobrien pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr, 48584865Sobrien coff_section_data (vars->abfd, sec)->i); 48684865Sobrien} 48784865Sobrien 48884865Sobrien/* Move the queued relocs into the given section. */ 489218822Sdim 49084865Sobrienstatic void 49184865Sobrienpe_ILF_save_relocs (pe_ILF_vars * vars, 49284865Sobrien asection_ptr sec) 49384865Sobrien{ 49484865Sobrien /* Make sure that there is somewhere to store the internal relocs. */ 49584865Sobrien if (coff_section_data (vars->abfd, sec) == NULL) 49684865Sobrien /* We should probably return an error indication here. */ 49784865Sobrien abort (); 49884865Sobrien 49984865Sobrien coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab; 500130561Sobrien coff_section_data (vars->abfd, sec)->keep_relocs = TRUE; 50184865Sobrien 50284865Sobrien sec->relocation = vars->reltab; 50384865Sobrien sec->reloc_count = vars->relcount; 50484865Sobrien sec->flags |= SEC_RELOC; 50584865Sobrien 50684865Sobrien vars->reltab += vars->relcount; 50784865Sobrien vars->int_reltab += vars->relcount; 50884865Sobrien vars->relcount = 0; 50984865Sobrien 51094536Sobrien BFD_ASSERT ((bfd_byte *) vars->int_reltab < (bfd_byte *) vars->string_table); 51184865Sobrien} 51284865Sobrien 51384865Sobrien/* Create a global symbol and add it to the relevant tables. */ 514218822Sdim 51584865Sobrienstatic void 51684865Sobrienpe_ILF_make_a_symbol (pe_ILF_vars * vars, 51784865Sobrien const char * prefix, 51884865Sobrien const char * symbol_name, 51984865Sobrien asection_ptr section, 52084865Sobrien flagword extra_flags) 52184865Sobrien{ 52284865Sobrien coff_symbol_type * sym; 52384865Sobrien combined_entry_type * ent; 52484865Sobrien SYMENT * esym; 52584865Sobrien unsigned short sclass; 52684865Sobrien 52784865Sobrien if (extra_flags & BSF_LOCAL) 52884865Sobrien sclass = C_STAT; 52984865Sobrien else 53084865Sobrien sclass = C_EXT; 53184865Sobrien 53284865Sobrien#ifdef THUMBPEMAGIC 53384865Sobrien if (vars->magic == THUMBPEMAGIC) 53484865Sobrien { 53584865Sobrien if (extra_flags & BSF_FUNCTION) 53684865Sobrien sclass = C_THUMBEXTFUNC; 53784865Sobrien else if (extra_flags & BSF_LOCAL) 53884865Sobrien sclass = C_THUMBSTAT; 53984865Sobrien else 54084865Sobrien sclass = C_THUMBEXT; 54184865Sobrien } 54284865Sobrien#endif 54384865Sobrien 54484865Sobrien BFD_ASSERT (vars->sym_index < NUM_ILF_SYMS); 54584865Sobrien 54684865Sobrien sym = vars->sym_ptr; 54784865Sobrien ent = vars->native_ptr; 54884865Sobrien esym = vars->esym_ptr; 54984865Sobrien 55084865Sobrien /* Copy the symbol's name into the string table. */ 55184865Sobrien sprintf (vars->string_ptr, "%s%s", prefix, symbol_name); 55284865Sobrien 55384865Sobrien if (section == NULL) 55484865Sobrien section = (asection_ptr) & bfd_und_section; 55584865Sobrien 55684865Sobrien /* Initialise the external symbol. */ 55794536Sobrien H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table, 55894536Sobrien esym->e.e.e_offset); 55994536Sobrien H_PUT_16 (vars->abfd, section->target_index, esym->e_scnum); 56084865Sobrien esym->e_sclass[0] = sclass; 56184865Sobrien 56284865Sobrien /* The following initialisations are unnecessary - the memory is 56384865Sobrien zero initialised. They are just kept here as reminders. */ 56484865Sobrien 56584865Sobrien /* Initialise the internal symbol structure. */ 56684865Sobrien ent->u.syment.n_sclass = sclass; 56784865Sobrien ent->u.syment.n_scnum = section->target_index; 56884865Sobrien ent->u.syment._n._n_n._n_offset = (long) sym; 56984865Sobrien 57084865Sobrien sym->symbol.the_bfd = vars->abfd; 57184865Sobrien sym->symbol.name = vars->string_ptr; 57284865Sobrien sym->symbol.flags = BSF_EXPORT | BSF_GLOBAL | extra_flags; 57384865Sobrien sym->symbol.section = section; 57484865Sobrien sym->native = ent; 57584865Sobrien 57684865Sobrien * vars->table_ptr = vars->sym_index; 57784865Sobrien * vars->sym_ptr_ptr = sym; 57884865Sobrien 57984865Sobrien /* Adjust pointers for the next symbol. */ 58084865Sobrien vars->sym_index ++; 58184865Sobrien vars->sym_ptr ++; 58284865Sobrien vars->sym_ptr_ptr ++; 58384865Sobrien vars->table_ptr ++; 58484865Sobrien vars->native_ptr ++; 58584865Sobrien vars->esym_ptr ++; 58684865Sobrien vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1; 58784865Sobrien 58884865Sobrien BFD_ASSERT (vars->string_ptr < vars->end_string_ptr); 58984865Sobrien} 59084865Sobrien 59184865Sobrien/* Create a section. */ 592218822Sdim 59384865Sobrienstatic asection_ptr 59484865Sobrienpe_ILF_make_a_section (pe_ILF_vars * vars, 59584865Sobrien const char * name, 59684865Sobrien unsigned int size, 59784865Sobrien flagword extra_flags) 59884865Sobrien{ 59984865Sobrien asection_ptr sec; 60084865Sobrien flagword flags; 60184865Sobrien 60284865Sobrien sec = bfd_make_section_old_way (vars->abfd, name); 60384865Sobrien if (sec == NULL) 60484865Sobrien return NULL; 60584865Sobrien 60684865Sobrien flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY; 60784865Sobrien 60884865Sobrien bfd_set_section_flags (vars->abfd, sec, flags | extra_flags); 60984865Sobrien 610223262Sbenl (void) bfd_set_section_alignment (vars->abfd, sec, 2); 61184865Sobrien 61284865Sobrien /* Check that we will not run out of space. */ 61384865Sobrien BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size); 61484865Sobrien 61584865Sobrien /* Set the section size and contents. The actual 61684865Sobrien contents are filled in by our parent. */ 61794536Sobrien bfd_set_section_size (vars->abfd, sec, (bfd_size_type) size); 61884865Sobrien sec->contents = vars->data; 61984865Sobrien sec->target_index = vars->sec_index ++; 62084865Sobrien 62184865Sobrien /* Advance data pointer in the vars structure. */ 62284865Sobrien vars->data += size; 62384865Sobrien 62484865Sobrien /* Skip the padding byte if it was not needed. 62584865Sobrien The logic here is that if the string length is odd, 62684865Sobrien then the entire string length, including the null byte, 62784865Sobrien is even and so the extra, padding byte, is not needed. */ 62884865Sobrien if (size & 1) 62984865Sobrien vars->data --; 63084865Sobrien 63184865Sobrien /* Create a coff_section_tdata structure for our use. */ 63284865Sobrien sec->used_by_bfd = (struct coff_section_tdata *) vars->data; 63384865Sobrien vars->data += sizeof (struct coff_section_tdata); 63484865Sobrien 63584865Sobrien BFD_ASSERT (vars->data <= vars->bim->buffer + vars->bim->size); 63684865Sobrien 63784865Sobrien /* Create a symbol to refer to this section. */ 63884865Sobrien pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL); 63984865Sobrien 64084865Sobrien /* Cache the index to the symbol in the coff_section_data structure. */ 64184865Sobrien coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1; 64284865Sobrien 64384865Sobrien return sec; 64484865Sobrien} 64584865Sobrien 64684865Sobrien/* This structure contains the code that goes into the .text section 64784865Sobrien in order to perform a jump into the DLL lookup table. The entries 64884865Sobrien in the table are index by the magic number used to represent the 64984865Sobrien machine type in the PE file. The contents of the data[] arrays in 65084865Sobrien these entries are stolen from the jtab[] arrays in ld/pe-dll.c. 65184865Sobrien The SIZE field says how many bytes in the DATA array are actually 65284865Sobrien used. The OFFSET field says where in the data array the address 65384865Sobrien of the .idata$5 section should be placed. */ 65484865Sobrien#define MAX_TEXT_SECTION_SIZE 32 65584865Sobrien 65684865Sobrientypedef struct 65784865Sobrien{ 65884865Sobrien unsigned short magic; 65984865Sobrien unsigned char data[MAX_TEXT_SECTION_SIZE]; 66084865Sobrien unsigned int size; 66184865Sobrien unsigned int offset; 66284865Sobrien} 66384865Sobrienjump_table; 66484865Sobrien 66584865Sobrienstatic jump_table jtab[] = 66684865Sobrien{ 66784865Sobrien#ifdef I386MAGIC 66884865Sobrien { I386MAGIC, 66984865Sobrien { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 }, 67084865Sobrien 8, 2 67184865Sobrien }, 67284865Sobrien#endif 67384865Sobrien 674218822Sdim#ifdef AMD64MAGIC 675218822Sdim { AMD64MAGIC, 676218822Sdim { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 }, 677218822Sdim 8, 2 678218822Sdim }, 679218822Sdim#endif 680218822Sdim 68184865Sobrien#ifdef MC68MAGIC 682218822Sdim { MC68MAGIC, 683218822Sdim { /* XXX fill me in */ }, 684218822Sdim 0, 0 685218822Sdim }, 68684865Sobrien#endif 687218822Sdim 68884865Sobrien#ifdef MIPS_ARCH_MAGIC_WINCE 68984865Sobrien { MIPS_ARCH_MAGIC_WINCE, 69084865Sobrien { 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d, 69184865Sobrien 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }, 69284865Sobrien 16, 0 69384865Sobrien }, 69484865Sobrien#endif 69584865Sobrien 69684865Sobrien#ifdef SH_ARCH_MAGIC_WINCE 69784865Sobrien { SH_ARCH_MAGIC_WINCE, 69884865Sobrien { 0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40, 69984865Sobrien 0x09, 0x00, 0x00, 0x00, 0x00, 0x00 }, 70084865Sobrien 12, 8 70184865Sobrien }, 70284865Sobrien#endif 70384865Sobrien 70484865Sobrien#ifdef ARMPEMAGIC 70584865Sobrien { ARMPEMAGIC, 70684865Sobrien { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0, 70784865Sobrien 0x9c, 0xe5, 0x00, 0x00, 0x00, 0x00}, 70884865Sobrien 12, 8 70984865Sobrien }, 71084865Sobrien#endif 71184865Sobrien 71284865Sobrien#ifdef THUMBPEMAGIC 71384865Sobrien { THUMBPEMAGIC, 71484865Sobrien { 0x40, 0xb4, 0x02, 0x4e, 0x36, 0x68, 0xb4, 0x46, 71584865Sobrien 0x40, 0xbc, 0x60, 0x47, 0x00, 0x00, 0x00, 0x00 }, 71684865Sobrien 16, 12 71784865Sobrien }, 71884865Sobrien#endif 71984865Sobrien { 0, { 0 }, 0, 0 } 72084865Sobrien}; 72184865Sobrien 72284865Sobrien#ifndef NUM_ENTRIES 72384865Sobrien#define NUM_ENTRIES(a) (sizeof (a) / sizeof (a)[0]) 72484865Sobrien#endif 72584865Sobrien 72684865Sobrien/* Build a full BFD from the information supplied in a ILF object. */ 727218822Sdim 728130561Sobrienstatic bfd_boolean 72984865Sobrienpe_ILF_build_a_bfd (bfd * abfd, 73094536Sobrien unsigned int magic, 731218822Sdim char * symbol_name, 732218822Sdim char * source_dll, 73384865Sobrien unsigned int ordinal, 73484865Sobrien unsigned int types) 73584865Sobrien{ 73684865Sobrien bfd_byte * ptr; 73784865Sobrien pe_ILF_vars vars; 73884865Sobrien struct internal_filehdr internal_f; 73984865Sobrien unsigned int import_type; 74084865Sobrien unsigned int import_name_type; 74184865Sobrien asection_ptr id4, id5, id6 = NULL, text = NULL; 74284865Sobrien coff_symbol_type ** imp_sym; 74384865Sobrien unsigned int imp_index; 74484865Sobrien 74584865Sobrien /* Decode and verify the types field of the ILF structure. */ 74684865Sobrien import_type = types & 0x3; 74784865Sobrien import_name_type = (types & 0x1c) >> 2; 74884865Sobrien 74984865Sobrien switch (import_type) 75084865Sobrien { 75184865Sobrien case IMPORT_CODE: 75284865Sobrien case IMPORT_DATA: 75384865Sobrien break; 75484865Sobrien 75584865Sobrien case IMPORT_CONST: 75684865Sobrien /* XXX code yet to be written. */ 757218822Sdim _bfd_error_handler (_("%B: Unhandled import type; %x"), 758218822Sdim abfd, import_type); 759130561Sobrien return FALSE; 76084865Sobrien 76184865Sobrien default: 762218822Sdim _bfd_error_handler (_("%B: Unrecognised import type; %x"), 763218822Sdim abfd, import_type); 764130561Sobrien return FALSE; 76584865Sobrien } 76684865Sobrien 76784865Sobrien switch (import_name_type) 76884865Sobrien { 76984865Sobrien case IMPORT_ORDINAL: 77084865Sobrien case IMPORT_NAME: 77184865Sobrien case IMPORT_NAME_NOPREFIX: 77284865Sobrien case IMPORT_NAME_UNDECORATE: 77384865Sobrien break; 77484865Sobrien 77584865Sobrien default: 776218822Sdim _bfd_error_handler (_("%B: Unrecognised import name type; %x"), 777218822Sdim abfd, import_name_type); 778130561Sobrien return FALSE; 77984865Sobrien } 78084865Sobrien 78184865Sobrien /* Initialise local variables. 78284865Sobrien 78384865Sobrien Note these are kept in a structure rather than being 78484865Sobrien declared as statics since bfd frowns on global variables. 78584865Sobrien 78684865Sobrien We are going to construct the contents of the BFD in memory, 78784865Sobrien so allocate all the space that we will need right now. */ 78894536Sobrien ptr = bfd_zalloc (abfd, (bfd_size_type) ILF_DATA_SIZE); 78984865Sobrien if (ptr == NULL) 790130561Sobrien return FALSE; 79184865Sobrien 79284865Sobrien /* Create a bfd_in_memory structure. */ 79384865Sobrien vars.bim = (struct bfd_in_memory *) ptr; 79484865Sobrien vars.bim->buffer = ptr; 79584865Sobrien vars.bim->size = ILF_DATA_SIZE; 79684865Sobrien ptr += sizeof (* vars.bim); 79784865Sobrien 79884865Sobrien /* Initialise the pointers to regions of the memory and the 79984865Sobrien other contents of the pe_ILF_vars structure as well. */ 80084865Sobrien vars.sym_cache = (coff_symbol_type *) ptr; 80184865Sobrien vars.sym_ptr = (coff_symbol_type *) ptr; 80284865Sobrien vars.sym_index = 0; 80384865Sobrien ptr += SIZEOF_ILF_SYMS; 80484865Sobrien 80584865Sobrien vars.sym_table = (unsigned int *) ptr; 80684865Sobrien vars.table_ptr = (unsigned int *) ptr; 80784865Sobrien ptr += SIZEOF_ILF_SYM_TABLE; 80884865Sobrien 80984865Sobrien vars.native_syms = (combined_entry_type *) ptr; 81084865Sobrien vars.native_ptr = (combined_entry_type *) ptr; 81184865Sobrien ptr += SIZEOF_ILF_NATIVE_SYMS; 81284865Sobrien 81384865Sobrien vars.sym_ptr_table = (coff_symbol_type **) ptr; 81484865Sobrien vars.sym_ptr_ptr = (coff_symbol_type **) ptr; 81584865Sobrien ptr += SIZEOF_ILF_SYM_PTR_TABLE; 81684865Sobrien 81784865Sobrien vars.esym_table = (SYMENT *) ptr; 81884865Sobrien vars.esym_ptr = (SYMENT *) ptr; 81984865Sobrien ptr += SIZEOF_ILF_EXT_SYMS; 82084865Sobrien 82184865Sobrien vars.reltab = (arelent *) ptr; 82284865Sobrien vars.relcount = 0; 82384865Sobrien ptr += SIZEOF_ILF_RELOCS; 82484865Sobrien 82584865Sobrien vars.int_reltab = (struct internal_reloc *) ptr; 82684865Sobrien ptr += SIZEOF_ILF_INT_RELOCS; 82784865Sobrien 828218822Sdim vars.string_table = (char *) ptr; 829218822Sdim vars.string_ptr = (char *) ptr + STRING_SIZE_SIZE; 83084865Sobrien ptr += SIZEOF_ILF_STRINGS; 831218822Sdim vars.end_string_ptr = (char *) ptr; 83284865Sobrien 83384865Sobrien /* The remaining space in bim->buffer is used 83484865Sobrien by the pe_ILF_make_a_section() function. */ 83584865Sobrien vars.data = ptr; 83684865Sobrien vars.abfd = abfd; 83784865Sobrien vars.sec_index = 0; 83884865Sobrien vars.magic = magic; 83984865Sobrien 84084865Sobrien /* Create the initial .idata$<n> sections: 84184865Sobrien [.idata$2: Import Directory Table -- not needed] 84284865Sobrien .idata$4: Import Lookup Table 84384865Sobrien .idata$5: Import Address Table 84484865Sobrien 84584865Sobrien Note we do not create a .idata$3 section as this is 84684865Sobrien created for us by the linker script. */ 84784865Sobrien id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0); 84884865Sobrien id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0); 84984865Sobrien if (id4 == NULL || id5 == NULL) 850130561Sobrien return FALSE; 85184865Sobrien 85284865Sobrien /* Fill in the contents of these sections. */ 85384865Sobrien if (import_name_type == IMPORT_ORDINAL) 85484865Sobrien { 85584865Sobrien if (ordinal == 0) 85684865Sobrien /* XXX - treat as IMPORT_NAME ??? */ 85784865Sobrien abort (); 85884865Sobrien 859218822Sdim#ifdef COFF_WITH_pex64 860218822Sdim ((unsigned int *) id4->contents)[0] = ordinal; 861218822Sdim ((unsigned int *) id4->contents)[1] = 0x80000000; 862218822Sdim ((unsigned int *) id5->contents)[0] = ordinal; 863218822Sdim ((unsigned int *) id5->contents)[1] = 0x80000000; 864218822Sdim#else 86584865Sobrien * (unsigned int *) id4->contents = ordinal | 0x80000000; 86684865Sobrien * (unsigned int *) id5->contents = ordinal | 0x80000000; 867218822Sdim#endif 86884865Sobrien } 86984865Sobrien else 87084865Sobrien { 87184865Sobrien char * symbol; 872218822Sdim unsigned int len; 87384865Sobrien 87484865Sobrien /* Create .idata$6 - the Hint Name Table. */ 87584865Sobrien id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0); 87684865Sobrien if (id6 == NULL) 877130561Sobrien return FALSE; 87884865Sobrien 87984865Sobrien /* If necessary, trim the import symbol name. */ 88084865Sobrien symbol = symbol_name; 88184865Sobrien 882218822Sdim /* As used by MS compiler, '_', '@', and '?' are alternative 883218822Sdim forms of USER_LABEL_PREFIX, with '?' for c++ mangled names, 884218822Sdim '@' used for fastcall (in C), '_' everywhere else. Only one 885218822Sdim of these is used for a symbol. We strip this leading char for 886218822Sdim IMPORT_NAME_NOPREFIX and IMPORT_NAME_UNDECORATE as per the 887218822Sdim PE COFF 6.0 spec (section 8.3, Import Name Type). */ 888218822Sdim 88984865Sobrien if (import_name_type != IMPORT_NAME) 890130561Sobrien { 891218822Sdim char c = symbol[0]; 892218822Sdim if (c == '_' || c == '@' || c == '?') 893218822Sdim symbol++; 894130561Sobrien } 895130561Sobrien 896218822Sdim len = strlen (symbol); 89784865Sobrien if (import_name_type == IMPORT_NAME_UNDECORATE) 89884865Sobrien { 899218822Sdim /* Truncate at the first '@'. */ 900218822Sdim char *at = strchr (symbol, '@'); 90184865Sobrien 902218822Sdim if (at != NULL) 903218822Sdim len = at - symbol; 90484865Sobrien } 90584865Sobrien 90684865Sobrien id6->contents[0] = ordinal & 0xff; 90784865Sobrien id6->contents[1] = ordinal >> 8; 90884865Sobrien 909218822Sdim memcpy ((char *) id6->contents + 2, symbol, len); 910218822Sdim id6->contents[len + 2] = '\0'; 91184865Sobrien } 91284865Sobrien 91384865Sobrien if (import_name_type != IMPORT_ORDINAL) 91484865Sobrien { 91594536Sobrien pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6); 91694536Sobrien pe_ILF_save_relocs (&vars, id4); 91784865Sobrien 91894536Sobrien pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6); 91994536Sobrien pe_ILF_save_relocs (&vars, id5); 92084865Sobrien } 92184865Sobrien 92284865Sobrien /* Create extra sections depending upon the type of import we are dealing with. */ 92384865Sobrien switch (import_type) 92484865Sobrien { 92584865Sobrien int i; 92684865Sobrien 92784865Sobrien case IMPORT_CODE: 92884865Sobrien /* Create a .text section. 92984865Sobrien First we need to look up its contents in the jump table. */ 93084865Sobrien for (i = NUM_ENTRIES (jtab); i--;) 93184865Sobrien { 93284865Sobrien if (jtab[i].size == 0) 93384865Sobrien continue; 93484865Sobrien if (jtab[i].magic == magic) 93584865Sobrien break; 93684865Sobrien } 93784865Sobrien /* If we did not find a matching entry something is wrong. */ 93884865Sobrien if (i < 0) 93984865Sobrien abort (); 94084865Sobrien 94184865Sobrien /* Create the .text section. */ 94284865Sobrien text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE); 94384865Sobrien if (text == NULL) 944130561Sobrien return FALSE; 94584865Sobrien 94684865Sobrien /* Copy in the jump code. */ 94784865Sobrien memcpy (text->contents, jtab[i].data, jtab[i].size); 94884865Sobrien 94984865Sobrien /* Create an import symbol. */ 95084865Sobrien pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0); 95184865Sobrien imp_sym = vars.sym_ptr_ptr - 1; 95284865Sobrien imp_index = vars.sym_index - 1; 95384865Sobrien 95484865Sobrien /* Create a reloc for the data in the text section. */ 95584865Sobrien#ifdef MIPS_ARCH_MAGIC_WINCE 95684865Sobrien if (magic == MIPS_ARCH_MAGIC_WINCE) 95784865Sobrien { 95894536Sobrien pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S, 959130561Sobrien (struct bfd_symbol **) imp_sym, 96094536Sobrien imp_index); 96194536Sobrien pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text); 96294536Sobrien pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16, 963130561Sobrien (struct bfd_symbol **) imp_sym, 96494536Sobrien imp_index); 96584865Sobrien } 96684865Sobrien else 96784865Sobrien#endif 96894536Sobrien pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset, 96994536Sobrien BFD_RELOC_32, (asymbol **) imp_sym, 97094536Sobrien imp_index); 97184865Sobrien 97284865Sobrien pe_ILF_save_relocs (& vars, text); 97384865Sobrien break; 97484865Sobrien 97584865Sobrien case IMPORT_DATA: 97684865Sobrien break; 97784865Sobrien 97884865Sobrien default: 97984865Sobrien /* XXX code not yet written. */ 98084865Sobrien abort (); 98184865Sobrien } 98284865Sobrien 98384865Sobrien /* Initialise the bfd. */ 98484865Sobrien memset (& internal_f, 0, sizeof (internal_f)); 98584865Sobrien 98684865Sobrien internal_f.f_magic = magic; 98784865Sobrien internal_f.f_symptr = 0; 98884865Sobrien internal_f.f_nsyms = 0; 98984865Sobrien internal_f.f_flags = F_AR32WR | F_LNNO; /* XXX is this correct ? */ 99084865Sobrien 99194536Sobrien if ( ! bfd_set_start_address (abfd, (bfd_vma) 0) 99284865Sobrien || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f)) 993130561Sobrien return FALSE; 99484865Sobrien 995218822Sdim if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL) 996130561Sobrien return FALSE; 99784865Sobrien 99884865Sobrien coff_data (abfd)->pe = 1; 99984865Sobrien#ifdef THUMBPEMAGIC 100084865Sobrien if (vars.magic == THUMBPEMAGIC) 100184865Sobrien /* Stop some linker warnings about thumb code not supporting interworking. */ 100284865Sobrien coff_data (abfd)->flags |= F_INTERWORK | F_INTERWORK_SET; 100384865Sobrien#endif 100484865Sobrien 100584865Sobrien /* Switch from file contents to memory contents. */ 100684865Sobrien bfd_cache_close (abfd); 100784865Sobrien 1008218822Sdim abfd->iostream = (void *) vars.bim; 100984865Sobrien abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */; 101084865Sobrien abfd->where = 0; 101184865Sobrien obj_sym_filepos (abfd) = 0; 101284865Sobrien 101384865Sobrien /* Now create a symbol describing the imported value. */ 101484865Sobrien switch (import_type) 101584865Sobrien { 101684865Sobrien case IMPORT_CODE: 101784865Sobrien pe_ILF_make_a_symbol (& vars, "", symbol_name, text, 101884865Sobrien BSF_NOT_AT_END | BSF_FUNCTION); 101984865Sobrien 102084865Sobrien /* Create an import symbol for the DLL, without the 102184865Sobrien .dll suffix. */ 1022218822Sdim ptr = (bfd_byte *) strrchr (source_dll, '.'); 102384865Sobrien if (ptr) 102484865Sobrien * ptr = 0; 102584865Sobrien pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0); 102684865Sobrien if (ptr) 102784865Sobrien * ptr = '.'; 102884865Sobrien break; 102984865Sobrien 103084865Sobrien case IMPORT_DATA: 103184865Sobrien /* Nothing to do here. */ 103284865Sobrien break; 103384865Sobrien 103484865Sobrien default: 103584865Sobrien /* XXX code not yet written. */ 103684865Sobrien abort (); 103784865Sobrien } 103884865Sobrien 103984865Sobrien /* Point the bfd at the symbol table. */ 104084865Sobrien obj_symbols (abfd) = vars.sym_cache; 104184865Sobrien bfd_get_symcount (abfd) = vars.sym_index; 104284865Sobrien 104384865Sobrien obj_raw_syments (abfd) = vars.native_syms; 104484865Sobrien obj_raw_syment_count (abfd) = vars.sym_index; 104584865Sobrien 1046218822Sdim obj_coff_external_syms (abfd) = (void *) vars.esym_table; 1047130561Sobrien obj_coff_keep_syms (abfd) = TRUE; 104884865Sobrien 104984865Sobrien obj_convert (abfd) = vars.sym_table; 105084865Sobrien obj_conv_table_size (abfd) = vars.sym_index; 105184865Sobrien 105284865Sobrien obj_coff_strings (abfd) = vars.string_table; 1053130561Sobrien obj_coff_keep_strings (abfd) = TRUE; 105484865Sobrien 105584865Sobrien abfd->flags |= HAS_SYMS; 105684865Sobrien 1057130561Sobrien return TRUE; 105884865Sobrien} 105984865Sobrien 106084865Sobrien/* We have detected a Image Library Format archive element. 106184865Sobrien Decode the element and return the appropriate target. */ 1062218822Sdim 106384865Sobrienstatic const bfd_target * 106484865Sobrienpe_ILF_object_p (bfd * abfd) 106584865Sobrien{ 106684865Sobrien bfd_byte buffer[16]; 106784865Sobrien bfd_byte * ptr; 1068218822Sdim char * symbol_name; 1069218822Sdim char * source_dll; 107084865Sobrien unsigned int machine; 107194536Sobrien bfd_size_type size; 107284865Sobrien unsigned int ordinal; 107384865Sobrien unsigned int types; 107494536Sobrien unsigned int magic; 107584865Sobrien 107684865Sobrien /* Upon entry the first four buyes of the ILF header have 107784865Sobrien already been read. Now read the rest of the header. */ 107894536Sobrien if (bfd_bread (buffer, (bfd_size_type) 16, abfd) != 16) 107984865Sobrien return NULL; 108084865Sobrien 108184865Sobrien ptr = buffer; 108284865Sobrien 108384865Sobrien /* We do not bother to check the version number. 108494536Sobrien version = H_GET_16 (abfd, ptr); */ 108584865Sobrien ptr += 2; 108684865Sobrien 108794536Sobrien machine = H_GET_16 (abfd, ptr); 108884865Sobrien ptr += 2; 108984865Sobrien 109084865Sobrien /* Check that the machine type is recognised. */ 109184865Sobrien magic = 0; 109284865Sobrien 109384865Sobrien switch (machine) 109484865Sobrien { 109584865Sobrien case IMAGE_FILE_MACHINE_UNKNOWN: 109684865Sobrien case IMAGE_FILE_MACHINE_ALPHA: 109784865Sobrien case IMAGE_FILE_MACHINE_ALPHA64: 109884865Sobrien case IMAGE_FILE_MACHINE_IA64: 109984865Sobrien break; 110084865Sobrien 110184865Sobrien case IMAGE_FILE_MACHINE_I386: 110284865Sobrien#ifdef I386MAGIC 110384865Sobrien magic = I386MAGIC; 110484865Sobrien#endif 110584865Sobrien break; 110684865Sobrien 1107218822Sdim case IMAGE_FILE_MACHINE_AMD64: 1108218822Sdim#ifdef AMD64MAGIC 1109218822Sdim magic = AMD64MAGIC; 1110218822Sdim#endif 1111218822Sdim break; 1112218822Sdim 111384865Sobrien case IMAGE_FILE_MACHINE_M68K: 111484865Sobrien#ifdef MC68AGIC 111584865Sobrien magic = MC68MAGIC; 111684865Sobrien#endif 111784865Sobrien break; 111884865Sobrien 111984865Sobrien case IMAGE_FILE_MACHINE_R3000: 112084865Sobrien case IMAGE_FILE_MACHINE_R4000: 112184865Sobrien case IMAGE_FILE_MACHINE_R10000: 112284865Sobrien 112384865Sobrien case IMAGE_FILE_MACHINE_MIPS16: 112484865Sobrien case IMAGE_FILE_MACHINE_MIPSFPU: 112584865Sobrien case IMAGE_FILE_MACHINE_MIPSFPU16: 112684865Sobrien#ifdef MIPS_ARCH_MAGIC_WINCE 112784865Sobrien magic = MIPS_ARCH_MAGIC_WINCE; 112884865Sobrien#endif 112984865Sobrien break; 113084865Sobrien 113184865Sobrien case IMAGE_FILE_MACHINE_SH3: 113284865Sobrien case IMAGE_FILE_MACHINE_SH4: 113384865Sobrien#ifdef SH_ARCH_MAGIC_WINCE 113484865Sobrien magic = SH_ARCH_MAGIC_WINCE; 113584865Sobrien#endif 113684865Sobrien break; 113784865Sobrien 113884865Sobrien case IMAGE_FILE_MACHINE_ARM: 113984865Sobrien#ifdef ARMPEMAGIC 114084865Sobrien magic = ARMPEMAGIC; 114184865Sobrien#endif 114284865Sobrien break; 114384865Sobrien 114484865Sobrien case IMAGE_FILE_MACHINE_THUMB: 114584865Sobrien#ifdef THUMBPEMAGIC 114684865Sobrien { 114784865Sobrien extern const bfd_target TARGET_LITTLE_SYM; 114884865Sobrien 114984865Sobrien if (abfd->xvec == & TARGET_LITTLE_SYM) 115084865Sobrien magic = THUMBPEMAGIC; 115184865Sobrien } 115284865Sobrien#endif 115384865Sobrien break; 115484865Sobrien 115584865Sobrien case IMAGE_FILE_MACHINE_POWERPC: 115684865Sobrien /* We no longer support PowerPC. */ 115784865Sobrien default: 115884865Sobrien _bfd_error_handler 1159218822Sdim (_("%B: Unrecognised machine type (0x%x)" 1160218822Sdim " in Import Library Format archive"), 1161218822Sdim abfd, machine); 116284865Sobrien bfd_set_error (bfd_error_malformed_archive); 116384865Sobrien 116484865Sobrien return NULL; 116584865Sobrien break; 116684865Sobrien } 116784865Sobrien 116884865Sobrien if (magic == 0) 116984865Sobrien { 117084865Sobrien _bfd_error_handler 1171218822Sdim (_("%B: Recognised but unhandled machine type (0x%x)" 1172218822Sdim " in Import Library Format archive"), 1173218822Sdim abfd, machine); 117484865Sobrien bfd_set_error (bfd_error_wrong_format); 117584865Sobrien 117684865Sobrien return NULL; 117784865Sobrien } 117884865Sobrien 117984865Sobrien /* We do not bother to check the date. 118094536Sobrien date = H_GET_32 (abfd, ptr); */ 118184865Sobrien ptr += 4; 118284865Sobrien 118394536Sobrien size = H_GET_32 (abfd, ptr); 118484865Sobrien ptr += 4; 118584865Sobrien 118684865Sobrien if (size == 0) 118784865Sobrien { 118884865Sobrien _bfd_error_handler 1189218822Sdim (_("%B: size field is zero in Import Library Format header"), abfd); 119084865Sobrien bfd_set_error (bfd_error_malformed_archive); 119184865Sobrien 119284865Sobrien return NULL; 119384865Sobrien } 119484865Sobrien 119594536Sobrien ordinal = H_GET_16 (abfd, ptr); 119684865Sobrien ptr += 2; 119784865Sobrien 119894536Sobrien types = H_GET_16 (abfd, ptr); 119984865Sobrien /* ptr += 2; */ 120084865Sobrien 120184865Sobrien /* Now read in the two strings that follow. */ 120284865Sobrien ptr = bfd_alloc (abfd, size); 120384865Sobrien if (ptr == NULL) 120484865Sobrien return NULL; 120584865Sobrien 120694536Sobrien if (bfd_bread (ptr, size, abfd) != size) 1207107492Sobrien { 1208107492Sobrien bfd_release (abfd, ptr); 1209107492Sobrien return NULL; 1210107492Sobrien } 121184865Sobrien 1212218822Sdim symbol_name = (char *) ptr; 1213218822Sdim source_dll = symbol_name + strlen (symbol_name) + 1; 121484865Sobrien 121584865Sobrien /* Verify that the strings are null terminated. */ 1216218822Sdim if (ptr[size - 1] != 0 1217218822Sdim || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size) 121884865Sobrien { 121984865Sobrien _bfd_error_handler 1220218822Sdim (_("%B: string not null terminated in ILF object file."), abfd); 122184865Sobrien bfd_set_error (bfd_error_malformed_archive); 1222107492Sobrien bfd_release (abfd, ptr); 122384865Sobrien return NULL; 122484865Sobrien } 122584865Sobrien 122684865Sobrien /* Now construct the bfd. */ 122784865Sobrien if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name, 122884865Sobrien source_dll, ordinal, types)) 1229107492Sobrien { 1230107492Sobrien bfd_release (abfd, ptr); 1231107492Sobrien return NULL; 1232107492Sobrien } 123384865Sobrien 123484865Sobrien return abfd->xvec; 123584865Sobrien} 123684865Sobrien 1237218822Sdimenum arch_type 1238218822Sdim{ 1239218822Sdim arch_type_unknown, 1240218822Sdim arch_type_i386, 1241218822Sdim arch_type_x86_64 1242218822Sdim}; 1243218822Sdim 1244218822Sdimstatic enum arch_type 1245218822Sdimpe_arch (const char *arch) 1246218822Sdim{ 1247218822Sdim if (strcmp (arch, "i386") == 0 || strcmp (arch, "ia32") == 0) 1248218822Sdim return arch_type_i386; 1249218822Sdim 1250218822Sdim if (strcmp (arch, "x86_64") == 0 || strcmp (arch, "x86-64") == 0) 1251218822Sdim return arch_type_x86_64; 1252218822Sdim 1253218822Sdim return arch_type_unknown; 1254218822Sdim} 1255218822Sdim 125684865Sobrienstatic const bfd_target * 125784865Sobrienpe_bfd_object_p (bfd * abfd) 125884865Sobrien{ 125984865Sobrien bfd_byte buffer[4]; 126084865Sobrien struct external_PEI_DOS_hdr dos_hdr; 126184865Sobrien struct external_PEI_IMAGE_hdr image_hdr; 126284865Sobrien file_ptr offset; 1263218822Sdim const bfd_target *target; 126484865Sobrien 126584865Sobrien /* Detect if this a Microsoft Import Library Format element. */ 126694536Sobrien if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 126794536Sobrien || bfd_bread (buffer, (bfd_size_type) 4, abfd) != 4) 126884865Sobrien { 126984865Sobrien if (bfd_get_error () != bfd_error_system_call) 127084865Sobrien bfd_set_error (bfd_error_wrong_format); 127184865Sobrien return NULL; 127284865Sobrien } 127384865Sobrien 127494536Sobrien if (H_GET_32 (abfd, buffer) == 0xffff0000) 127584865Sobrien return pe_ILF_object_p (abfd); 127684865Sobrien 127794536Sobrien if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 127894536Sobrien || bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd) 127984865Sobrien != sizeof (dos_hdr)) 128084865Sobrien { 128184865Sobrien if (bfd_get_error () != bfd_error_system_call) 128284865Sobrien bfd_set_error (bfd_error_wrong_format); 128384865Sobrien return NULL; 128484865Sobrien } 128584865Sobrien 128684865Sobrien /* There are really two magic numbers involved; the magic number 128784865Sobrien that says this is a NT executable (PEI) and the magic number that 128884865Sobrien determines the architecture. The former is DOSMAGIC, stored in 128984865Sobrien the e_magic field. The latter is stored in the f_magic field. 129084865Sobrien If the NT magic number isn't valid, the architecture magic number 129184865Sobrien could be mimicked by some other field (specifically, the number 129284865Sobrien of relocs in section 3). Since this routine can only be called 129384865Sobrien correctly for a PEI file, check the e_magic number here, and, if 129484865Sobrien it doesn't match, clobber the f_magic number so that we don't get 129584865Sobrien a false match. */ 129694536Sobrien if (H_GET_16 (abfd, dos_hdr.e_magic) != DOSMAGIC) 129784865Sobrien { 129884865Sobrien bfd_set_error (bfd_error_wrong_format); 129984865Sobrien return NULL; 130084865Sobrien } 130184865Sobrien 130294536Sobrien offset = H_GET_32 (abfd, dos_hdr.e_lfanew); 130394536Sobrien if (bfd_seek (abfd, offset, SEEK_SET) != 0 130494536Sobrien || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd) 130594536Sobrien != sizeof (image_hdr))) 130684865Sobrien { 130784865Sobrien if (bfd_get_error () != bfd_error_system_call) 130884865Sobrien bfd_set_error (bfd_error_wrong_format); 130984865Sobrien return NULL; 131084865Sobrien } 131184865Sobrien 131294536Sobrien if (H_GET_32 (abfd, image_hdr.nt_signature) != 0x4550) 131384865Sobrien { 131484865Sobrien bfd_set_error (bfd_error_wrong_format); 131584865Sobrien return NULL; 131684865Sobrien } 131784865Sobrien 131884865Sobrien /* Here is the hack. coff_object_p wants to read filhsz bytes to 131984865Sobrien pick up the COFF header for PE, see "struct external_PEI_filehdr" 132084865Sobrien in include/coff/pe.h. We adjust so that that will work. */ 132194536Sobrien if (bfd_seek (abfd, (file_ptr) (offset - sizeof (dos_hdr)), SEEK_SET) != 0) 132284865Sobrien { 132384865Sobrien if (bfd_get_error () != bfd_error_system_call) 132484865Sobrien bfd_set_error (bfd_error_wrong_format); 132584865Sobrien return NULL; 132684865Sobrien } 132784865Sobrien 1328218822Sdim target = coff_object_p (abfd); 1329218822Sdim if (target) 1330218822Sdim { 1331218822Sdim pe_data_type *pe = pe_data (abfd); 1332218822Sdim struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr; 1333218822Sdim bfd_boolean efi = i->Subsystem == IMAGE_SUBSYSTEM_EFI_APPLICATION; 1334218822Sdim enum arch_type arch; 1335218822Sdim const bfd_target * const *target_ptr; 1336218822Sdim 1337218822Sdim /* Get the machine. */ 1338218822Sdim if (bfd_target_efi_p (abfd->xvec)) 1339218822Sdim arch = pe_arch (bfd_target_efi_arch (abfd->xvec)); 1340218822Sdim else 1341218822Sdim arch = pe_arch (bfd_target_pei_arch (abfd->xvec)); 1342218822Sdim 1343218822Sdim for (target_ptr = bfd_target_vector; *target_ptr != NULL; 1344218822Sdim target_ptr++) 1345218822Sdim { 1346218822Sdim if (*target_ptr == target 1347218822Sdim || (*target_ptr)->flavour != bfd_target_coff_flavour) 1348218822Sdim continue; 1349218822Sdim 1350218822Sdim if (bfd_target_efi_p (*target_ptr)) 1351218822Sdim { 1352218822Sdim /* Skip incompatible arch. */ 1353218822Sdim if (pe_arch (bfd_target_efi_arch (*target_ptr)) != arch) 1354218822Sdim continue; 1355218822Sdim 1356357351Sdim if (efi) 1357357351Sdim { 1358357351Sdim /* TARGET_PTR is an EFI backend. Don't match 1359357351Sdim TARGET with a EFI file. */ 1360357351Sdim bfd_set_error (bfd_error_wrong_format); 1361357351Sdim return NULL; 1362357351Sdim } 1363218822Sdim } 1364218822Sdim else if (bfd_target_pei_p (*target_ptr)) 1365218822Sdim { 1366218822Sdim /* Skip incompatible arch. */ 1367218822Sdim if (pe_arch (bfd_target_pei_arch (*target_ptr)) != arch) 1368218822Sdim continue; 1369218822Sdim 1370357351Sdim if (!efi) 1371357351Sdim { 1372357351Sdim /* TARGET_PTR is a PE backend. Don't match 1373357351Sdim TARGET with a PE file. */ 1374357351Sdim bfd_set_error (bfd_error_wrong_format); 1375357351Sdim return NULL; 1376357351Sdim } 1377218822Sdim } 1378218822Sdim } 1379218822Sdim } 1380218822Sdim 1381218822Sdim return target; 138284865Sobrien} 138384865Sobrien 138484865Sobrien#define coff_object_p pe_bfd_object_p 138584865Sobrien#endif /* COFF_IMAGE_WITH_PE */ 1386