1377e23a2Schristos /* Support for the generic parts of PE/PEI, for BFD. 2377e23a2Schristos Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 3*48596154Schristos 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 4*48596154Schristos Free Software Foundation, Inc. 5377e23a2Schristos Written by Cygnus Solutions. 6377e23a2Schristos 7377e23a2Schristos This file is part of BFD, the Binary File Descriptor library. 8377e23a2Schristos 9377e23a2Schristos This program is free software; you can redistribute it and/or modify 10377e23a2Schristos it under the terms of the GNU General Public License as published by 11377e23a2Schristos the Free Software Foundation; either version 3 of the License, or 12377e23a2Schristos (at your option) any later version. 13377e23a2Schristos 14377e23a2Schristos This program is distributed in the hope that it will be useful, 15377e23a2Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 16377e23a2Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17377e23a2Schristos GNU General Public License for more details. 18377e23a2Schristos 19377e23a2Schristos You should have received a copy of the GNU General Public License 20377e23a2Schristos along with this program; if not, write to the Free Software 21377e23a2Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 22377e23a2Schristos MA 02110-1301, USA. */ 23377e23a2Schristos 24377e23a2Schristos 25377e23a2Schristos /* Most of this hacked by Steve Chamberlain, 26377e23a2Schristos sac@cygnus.com 27377e23a2Schristos 28377e23a2Schristos PE/PEI rearrangement (and code added): Donn Terry 29377e23a2Schristos Softway Systems, Inc. */ 30377e23a2Schristos 31377e23a2Schristos /* Hey look, some documentation [and in a place you expect to find it]! 32377e23a2Schristos 33377e23a2Schristos The main reference for the pei format is "Microsoft Portable Executable 34377e23a2Schristos and Common Object File Format Specification 4.1". Get it if you need to 35377e23a2Schristos do some serious hacking on this code. 36377e23a2Schristos 37377e23a2Schristos Another reference: 38377e23a2Schristos "Peering Inside the PE: A Tour of the Win32 Portable Executable 39377e23a2Schristos File Format", MSJ 1994, Volume 9. 40377e23a2Schristos 41377e23a2Schristos The *sole* difference between the pe format and the pei format is that the 42377e23a2Schristos latter has an MSDOS 2.0 .exe header on the front that prints the message 43377e23a2Schristos "This app must be run under Windows." (or some such). 44377e23a2Schristos (FIXME: Whether that statement is *really* true or not is unknown. 45377e23a2Schristos Are there more subtle differences between pe and pei formats? 46377e23a2Schristos For now assume there aren't. If you find one, then for God sakes 47377e23a2Schristos document it here!) 48377e23a2Schristos 49377e23a2Schristos The Microsoft docs use the word "image" instead of "executable" because 50377e23a2Schristos the former can also refer to a DLL (shared library). Confusion can arise 51377e23a2Schristos because the `i' in `pei' also refers to "image". The `pe' format can 52377e23a2Schristos also create images (i.e. executables), it's just that to run on a win32 53377e23a2Schristos system you need to use the pei format. 54377e23a2Schristos 55377e23a2Schristos FIXME: Please add more docs here so the next poor fool that has to hack 56377e23a2Schristos on this code has a chance of getting something accomplished without 57377e23a2Schristos wasting too much time. */ 58377e23a2Schristos 59377e23a2Schristos #include "libpei.h" 60377e23a2Schristos 61377e23a2Schristos static bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) = 62377e23a2Schristos #ifndef coff_bfd_print_private_bfd_data 63377e23a2Schristos NULL; 64377e23a2Schristos #else 65377e23a2Schristos coff_bfd_print_private_bfd_data; 66377e23a2Schristos #undef coff_bfd_print_private_bfd_data 67377e23a2Schristos #endif 68377e23a2Schristos 69377e23a2Schristos static bfd_boolean pe_print_private_bfd_data (bfd *, void *); 70377e23a2Schristos #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data 71377e23a2Schristos 72377e23a2Schristos static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) = 73377e23a2Schristos #ifndef coff_bfd_copy_private_bfd_data 74377e23a2Schristos NULL; 75377e23a2Schristos #else 76377e23a2Schristos coff_bfd_copy_private_bfd_data; 77377e23a2Schristos #undef coff_bfd_copy_private_bfd_data 78377e23a2Schristos #endif 79377e23a2Schristos 80377e23a2Schristos static bfd_boolean pe_bfd_copy_private_bfd_data (bfd *, bfd *); 81377e23a2Schristos #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data 82377e23a2Schristos 83377e23a2Schristos #define coff_mkobject pe_mkobject 84377e23a2Schristos #define coff_mkobject_hook pe_mkobject_hook 85377e23a2Schristos 86377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE 87377e23a2Schristos /* This structure contains static variables used by the ILF code. */ 88377e23a2Schristos typedef asection * asection_ptr; 89377e23a2Schristos 90377e23a2Schristos typedef struct 91377e23a2Schristos { 92377e23a2Schristos bfd * abfd; 93377e23a2Schristos bfd_byte * data; 94377e23a2Schristos struct bfd_in_memory * bim; 95377e23a2Schristos unsigned short magic; 96377e23a2Schristos 97377e23a2Schristos arelent * reltab; 98377e23a2Schristos unsigned int relcount; 99377e23a2Schristos 100377e23a2Schristos coff_symbol_type * sym_cache; 101377e23a2Schristos coff_symbol_type * sym_ptr; 102377e23a2Schristos unsigned int sym_index; 103377e23a2Schristos 104377e23a2Schristos unsigned int * sym_table; 105377e23a2Schristos unsigned int * table_ptr; 106377e23a2Schristos 107377e23a2Schristos combined_entry_type * native_syms; 108377e23a2Schristos combined_entry_type * native_ptr; 109377e23a2Schristos 110377e23a2Schristos coff_symbol_type ** sym_ptr_table; 111377e23a2Schristos coff_symbol_type ** sym_ptr_ptr; 112377e23a2Schristos 113377e23a2Schristos unsigned int sec_index; 114377e23a2Schristos 115377e23a2Schristos char * string_table; 116377e23a2Schristos char * string_ptr; 117377e23a2Schristos char * end_string_ptr; 118377e23a2Schristos 119377e23a2Schristos SYMENT * esym_table; 120377e23a2Schristos SYMENT * esym_ptr; 121377e23a2Schristos 122377e23a2Schristos struct internal_reloc * int_reltab; 123377e23a2Schristos } 124377e23a2Schristos pe_ILF_vars; 125377e23a2Schristos #endif /* COFF_IMAGE_WITH_PE */ 126377e23a2Schristos 127377e23a2Schristos #ifndef NO_COFF_RELOCS 128377e23a2Schristos static void 129377e23a2Schristos coff_swap_reloc_in (bfd * abfd, void * src, void * dst) 130377e23a2Schristos { 131377e23a2Schristos RELOC *reloc_src = (RELOC *) src; 132377e23a2Schristos struct internal_reloc *reloc_dst = (struct internal_reloc *) dst; 133377e23a2Schristos 134377e23a2Schristos reloc_dst->r_vaddr = H_GET_32 (abfd, reloc_src->r_vaddr); 135377e23a2Schristos reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx); 136377e23a2Schristos reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type); 137377e23a2Schristos #ifdef SWAP_IN_RELOC_OFFSET 138377e23a2Schristos reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset); 139377e23a2Schristos #endif 140377e23a2Schristos } 141377e23a2Schristos 142377e23a2Schristos static unsigned int 143377e23a2Schristos coff_swap_reloc_out (bfd * abfd, void * src, void * dst) 144377e23a2Schristos { 145377e23a2Schristos struct internal_reloc *reloc_src = (struct internal_reloc *) src; 146377e23a2Schristos struct external_reloc *reloc_dst = (struct external_reloc *) dst; 147377e23a2Schristos 148377e23a2Schristos H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr); 149377e23a2Schristos H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx); 150377e23a2Schristos H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type); 151377e23a2Schristos 152377e23a2Schristos #ifdef SWAP_OUT_RELOC_OFFSET 153377e23a2Schristos SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset); 154377e23a2Schristos #endif 155377e23a2Schristos #ifdef SWAP_OUT_RELOC_EXTRA 156377e23a2Schristos SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst); 157377e23a2Schristos #endif 158377e23a2Schristos return RELSZ; 159377e23a2Schristos } 160377e23a2Schristos #endif /* not NO_COFF_RELOCS */ 161377e23a2Schristos 162377e23a2Schristos static void 163377e23a2Schristos coff_swap_filehdr_in (bfd * abfd, void * src, void * dst) 164377e23a2Schristos { 165377e23a2Schristos FILHDR *filehdr_src = (FILHDR *) src; 166377e23a2Schristos struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst; 167377e23a2Schristos 168377e23a2Schristos filehdr_dst->f_magic = H_GET_16 (abfd, filehdr_src->f_magic); 169377e23a2Schristos filehdr_dst->f_nscns = H_GET_16 (abfd, filehdr_src->f_nscns); 170377e23a2Schristos filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat); 171377e23a2Schristos filehdr_dst->f_nsyms = H_GET_32 (abfd, filehdr_src->f_nsyms); 172377e23a2Schristos filehdr_dst->f_flags = H_GET_16 (abfd, filehdr_src->f_flags); 173377e23a2Schristos filehdr_dst->f_symptr = H_GET_32 (abfd, filehdr_src->f_symptr); 174377e23a2Schristos 175377e23a2Schristos /* Other people's tools sometimes generate headers with an nsyms but 176377e23a2Schristos a zero symptr. */ 177377e23a2Schristos if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0) 178377e23a2Schristos { 179377e23a2Schristos filehdr_dst->f_nsyms = 0; 180377e23a2Schristos filehdr_dst->f_flags |= F_LSYMS; 181377e23a2Schristos } 182377e23a2Schristos 183377e23a2Schristos filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src-> f_opthdr); 184377e23a2Schristos } 185377e23a2Schristos 186377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE 187377e23a2Schristos # define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out 188377e23a2Schristos #elif defined COFF_WITH_pex64 189377e23a2Schristos # define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out 190377e23a2Schristos #elif defined COFF_WITH_pep 191377e23a2Schristos # define coff_swap_filehdr_out _bfd_pep_only_swap_filehdr_out 192377e23a2Schristos #else 193377e23a2Schristos # define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out 194377e23a2Schristos #endif 195377e23a2Schristos 196377e23a2Schristos static void 197377e23a2Schristos coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in) 198377e23a2Schristos { 199377e23a2Schristos SCNHDR *scnhdr_ext = (SCNHDR *) ext; 200377e23a2Schristos struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in; 201377e23a2Schristos 202377e23a2Schristos memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name)); 203377e23a2Schristos 204377e23a2Schristos scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr); 205377e23a2Schristos scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr); 206377e23a2Schristos scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size); 207377e23a2Schristos scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr); 208377e23a2Schristos scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr); 209377e23a2Schristos scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr); 210377e23a2Schristos scnhdr_int->s_flags = H_GET_32 (abfd, scnhdr_ext->s_flags); 211377e23a2Schristos 212377e23a2Schristos /* MS handles overflow of line numbers by carrying into the reloc 213377e23a2Schristos field (it appears). Since it's supposed to be zero for PE 214377e23a2Schristos *IMAGE* format, that's safe. This is still a bit iffy. */ 215377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE 216377e23a2Schristos scnhdr_int->s_nlnno = (H_GET_16 (abfd, scnhdr_ext->s_nlnno) 217377e23a2Schristos + (H_GET_16 (abfd, scnhdr_ext->s_nreloc) << 16)); 218377e23a2Schristos scnhdr_int->s_nreloc = 0; 219377e23a2Schristos #else 220377e23a2Schristos scnhdr_int->s_nreloc = H_GET_16 (abfd, scnhdr_ext->s_nreloc); 221377e23a2Schristos scnhdr_int->s_nlnno = H_GET_16 (abfd, scnhdr_ext->s_nlnno); 222377e23a2Schristos #endif 223377e23a2Schristos 224377e23a2Schristos if (scnhdr_int->s_vaddr != 0) 225377e23a2Schristos { 226377e23a2Schristos scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase; 227377e23a2Schristos /* Do not cut upper 32-bits for 64-bit vma. */ 228377e23a2Schristos #ifndef COFF_WITH_pex64 229377e23a2Schristos scnhdr_int->s_vaddr &= 0xffffffff; 230377e23a2Schristos #endif 231377e23a2Schristos } 232377e23a2Schristos 233377e23a2Schristos #ifndef COFF_NO_HACK_SCNHDR_SIZE 234377e23a2Schristos /* If this section holds uninitialized data and is from an object file 235377e23a2Schristos or from an executable image that has not initialized the field, 236377e23a2Schristos or if the image is an executable file and the physical size is padded, 237377e23a2Schristos use the virtual size (stored in s_paddr) instead. */ 238377e23a2Schristos if (scnhdr_int->s_paddr > 0 239377e23a2Schristos && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0 240377e23a2Schristos && (! bfd_pei_p (abfd) || scnhdr_int->s_size == 0)) 241377e23a2Schristos || (bfd_pei_p (abfd) && (scnhdr_int->s_size > scnhdr_int->s_paddr)))) 242377e23a2Schristos /* This code used to set scnhdr_int->s_paddr to 0. However, 243377e23a2Schristos coff_set_alignment_hook stores s_paddr in virt_size, which 244377e23a2Schristos only works if it correctly holds the virtual size of the 245377e23a2Schristos section. */ 246377e23a2Schristos scnhdr_int->s_size = scnhdr_int->s_paddr; 247377e23a2Schristos #endif 248377e23a2Schristos } 249377e23a2Schristos 250377e23a2Schristos static bfd_boolean 251377e23a2Schristos pe_mkobject (bfd * abfd) 252377e23a2Schristos { 253377e23a2Schristos pe_data_type *pe; 254377e23a2Schristos bfd_size_type amt = sizeof (pe_data_type); 255377e23a2Schristos 256377e23a2Schristos abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt); 257377e23a2Schristos 258377e23a2Schristos if (abfd->tdata.pe_obj_data == 0) 259377e23a2Schristos return FALSE; 260377e23a2Schristos 261377e23a2Schristos pe = pe_data (abfd); 262377e23a2Schristos 263377e23a2Schristos pe->coff.pe = 1; 264377e23a2Schristos 265377e23a2Schristos /* in_reloc_p is architecture dependent. */ 266377e23a2Schristos pe->in_reloc_p = in_reloc_p; 267377e23a2Schristos 268377e23a2Schristos return TRUE; 269377e23a2Schristos } 270377e23a2Schristos 271377e23a2Schristos /* Create the COFF backend specific information. */ 272377e23a2Schristos 273377e23a2Schristos static void * 274377e23a2Schristos pe_mkobject_hook (bfd * abfd, 275377e23a2Schristos void * filehdr, 276377e23a2Schristos void * aouthdr ATTRIBUTE_UNUSED) 277377e23a2Schristos { 278377e23a2Schristos struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; 279377e23a2Schristos pe_data_type *pe; 280377e23a2Schristos 281377e23a2Schristos if (! pe_mkobject (abfd)) 282377e23a2Schristos return NULL; 283377e23a2Schristos 284377e23a2Schristos pe = pe_data (abfd); 285377e23a2Schristos pe->coff.sym_filepos = internal_f->f_symptr; 286377e23a2Schristos /* These members communicate important constants about the symbol 287377e23a2Schristos table to GDB's symbol-reading code. These `constants' 288377e23a2Schristos unfortunately vary among coff implementations... */ 289377e23a2Schristos pe->coff.local_n_btmask = N_BTMASK; 290377e23a2Schristos pe->coff.local_n_btshft = N_BTSHFT; 291377e23a2Schristos pe->coff.local_n_tmask = N_TMASK; 292377e23a2Schristos pe->coff.local_n_tshift = N_TSHIFT; 293377e23a2Schristos pe->coff.local_symesz = SYMESZ; 294377e23a2Schristos pe->coff.local_auxesz = AUXESZ; 295377e23a2Schristos pe->coff.local_linesz = LINESZ; 296377e23a2Schristos 297377e23a2Schristos pe->coff.timestamp = internal_f->f_timdat; 298377e23a2Schristos 299377e23a2Schristos obj_raw_syment_count (abfd) = 300377e23a2Schristos obj_conv_table_size (abfd) = 301377e23a2Schristos internal_f->f_nsyms; 302377e23a2Schristos 303377e23a2Schristos pe->real_flags = internal_f->f_flags; 304377e23a2Schristos 305377e23a2Schristos if ((internal_f->f_flags & F_DLL) != 0) 306377e23a2Schristos pe->dll = 1; 307377e23a2Schristos 308377e23a2Schristos if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0) 309377e23a2Schristos abfd->flags |= HAS_DEBUG; 310377e23a2Schristos 311377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE 312377e23a2Schristos if (aouthdr) 313377e23a2Schristos pe->pe_opthdr = ((struct internal_aouthdr *) aouthdr)->pe; 314377e23a2Schristos #endif 315377e23a2Schristos 316377e23a2Schristos #ifdef ARM 317377e23a2Schristos if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags)) 318377e23a2Schristos coff_data (abfd) ->flags = 0; 319377e23a2Schristos #endif 320377e23a2Schristos 321377e23a2Schristos return (void *) pe; 322377e23a2Schristos } 323377e23a2Schristos 324377e23a2Schristos static bfd_boolean 325377e23a2Schristos pe_print_private_bfd_data (bfd *abfd, void * vfile) 326377e23a2Schristos { 327377e23a2Schristos FILE *file = (FILE *) vfile; 328377e23a2Schristos 329377e23a2Schristos if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile)) 330377e23a2Schristos return FALSE; 331377e23a2Schristos 332377e23a2Schristos if (pe_saved_coff_bfd_print_private_bfd_data == NULL) 333377e23a2Schristos return TRUE; 334377e23a2Schristos 335377e23a2Schristos fputc ('\n', file); 336377e23a2Schristos 337377e23a2Schristos return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile); 338377e23a2Schristos } 339377e23a2Schristos 340377e23a2Schristos /* Copy any private info we understand from the input bfd 341377e23a2Schristos to the output bfd. */ 342377e23a2Schristos 343377e23a2Schristos static bfd_boolean 344377e23a2Schristos pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd) 345377e23a2Schristos { 346377e23a2Schristos /* PR binutils/716: Copy the large address aware flag. 347377e23a2Schristos XXX: Should we be copying other flags or other fields in the pe_data() 348377e23a2Schristos structure ? */ 349377e23a2Schristos if (pe_data (obfd) != NULL 350377e23a2Schristos && pe_data (ibfd) != NULL 351377e23a2Schristos && pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE) 352377e23a2Schristos pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE; 353377e23a2Schristos 354377e23a2Schristos if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd)) 355377e23a2Schristos return FALSE; 356377e23a2Schristos 357377e23a2Schristos if (pe_saved_coff_bfd_copy_private_bfd_data) 358377e23a2Schristos return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd); 359377e23a2Schristos 360377e23a2Schristos return TRUE; 361377e23a2Schristos } 362377e23a2Schristos 363377e23a2Schristos #define coff_bfd_copy_private_section_data \ 364377e23a2Schristos _bfd_XX_bfd_copy_private_section_data 365377e23a2Schristos 366377e23a2Schristos #define coff_get_symbol_info _bfd_XX_get_symbol_info 367377e23a2Schristos 368377e23a2Schristos #ifdef COFF_IMAGE_WITH_PE 369377e23a2Schristos 370377e23a2Schristos /* Code to handle Microsoft's Image Library Format. 371377e23a2Schristos Also known as LINK6 format. 372377e23a2Schristos Documentation about this format can be found at: 373377e23a2Schristos 374377e23a2Schristos http://msdn.microsoft.com/library/specs/pecoff_section8.htm */ 375377e23a2Schristos 376377e23a2Schristos /* The following constants specify the sizes of the various data 377377e23a2Schristos structures that we have to create in order to build a bfd describing 378377e23a2Schristos an ILF object file. The final "+ 1" in the definitions of SIZEOF_IDATA6 379377e23a2Schristos and SIZEOF_IDATA7 below is to allow for the possibility that we might 380377e23a2Schristos need a padding byte in order to ensure 16 bit alignment for the section's 381377e23a2Schristos contents. 382377e23a2Schristos 383377e23a2Schristos The value for SIZEOF_ILF_STRINGS is computed as follows: 384377e23a2Schristos 385377e23a2Schristos There will be NUM_ILF_SECTIONS section symbols. Allow 9 characters 386377e23a2Schristos per symbol for their names (longest section name is .idata$x). 387377e23a2Schristos 388377e23a2Schristos There will be two symbols for the imported value, one the symbol name 389377e23a2Schristos and one with _imp__ prefixed. Allowing for the terminating nul's this 390377e23a2Schristos is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll). 391377e23a2Schristos 392377e23a2Schristos The strings in the string table must start STRING__SIZE_SIZE bytes into 393377e23a2Schristos the table in order to for the string lookup code in coffgen/coffcode to 394377e23a2Schristos work. */ 395377e23a2Schristos #define NUM_ILF_RELOCS 8 396377e23a2Schristos #define NUM_ILF_SECTIONS 6 397377e23a2Schristos #define NUM_ILF_SYMS (2 + NUM_ILF_SECTIONS) 398377e23a2Schristos 399377e23a2Schristos #define SIZEOF_ILF_SYMS (NUM_ILF_SYMS * sizeof (* vars.sym_cache)) 400377e23a2Schristos #define SIZEOF_ILF_SYM_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_table)) 401377e23a2Schristos #define SIZEOF_ILF_NATIVE_SYMS (NUM_ILF_SYMS * sizeof (* vars.native_syms)) 402377e23a2Schristos #define SIZEOF_ILF_SYM_PTR_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_ptr_table)) 403377e23a2Schristos #define SIZEOF_ILF_EXT_SYMS (NUM_ILF_SYMS * sizeof (* vars.esym_table)) 404377e23a2Schristos #define SIZEOF_ILF_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.reltab)) 405377e23a2Schristos #define SIZEOF_ILF_INT_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.int_reltab)) 406377e23a2Schristos #define SIZEOF_ILF_STRINGS (strlen (symbol_name) * 2 + 8 \ 407377e23a2Schristos + 21 + strlen (source_dll) \ 408377e23a2Schristos + NUM_ILF_SECTIONS * 9 \ 409377e23a2Schristos + STRING_SIZE_SIZE) 410377e23a2Schristos #define SIZEOF_IDATA2 (5 * 4) 411377e23a2Schristos 412377e23a2Schristos /* For PEx64 idata4 & 5 have thumb size of 8 bytes. */ 413377e23a2Schristos #ifdef COFF_WITH_pex64 414377e23a2Schristos #define SIZEOF_IDATA4 (2 * 4) 415377e23a2Schristos #define SIZEOF_IDATA5 (2 * 4) 416377e23a2Schristos #else 417377e23a2Schristos #define SIZEOF_IDATA4 (1 * 4) 418377e23a2Schristos #define SIZEOF_IDATA5 (1 * 4) 419377e23a2Schristos #endif 420377e23a2Schristos 421377e23a2Schristos #define SIZEOF_IDATA6 (2 + strlen (symbol_name) + 1 + 1) 422377e23a2Schristos #define SIZEOF_IDATA7 (strlen (source_dll) + 1 + 1) 423377e23a2Schristos #define SIZEOF_ILF_SECTIONS (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata)) 424377e23a2Schristos 425377e23a2Schristos #define ILF_DATA_SIZE \ 426377e23a2Schristos + SIZEOF_ILF_SYMS \ 427377e23a2Schristos + SIZEOF_ILF_SYM_TABLE \ 428377e23a2Schristos + SIZEOF_ILF_NATIVE_SYMS \ 429377e23a2Schristos + SIZEOF_ILF_SYM_PTR_TABLE \ 430377e23a2Schristos + SIZEOF_ILF_EXT_SYMS \ 431377e23a2Schristos + SIZEOF_ILF_RELOCS \ 432377e23a2Schristos + SIZEOF_ILF_INT_RELOCS \ 433377e23a2Schristos + SIZEOF_ILF_STRINGS \ 434377e23a2Schristos + SIZEOF_IDATA2 \ 435377e23a2Schristos + SIZEOF_IDATA4 \ 436377e23a2Schristos + SIZEOF_IDATA5 \ 437377e23a2Schristos + SIZEOF_IDATA6 \ 438377e23a2Schristos + SIZEOF_IDATA7 \ 439377e23a2Schristos + SIZEOF_ILF_SECTIONS \ 440377e23a2Schristos + MAX_TEXT_SECTION_SIZE 441377e23a2Schristos 442377e23a2Schristos /* Create an empty relocation against the given symbol. */ 443377e23a2Schristos 444377e23a2Schristos static void 445377e23a2Schristos pe_ILF_make_a_symbol_reloc (pe_ILF_vars * vars, 446377e23a2Schristos bfd_vma address, 447377e23a2Schristos bfd_reloc_code_real_type reloc, 448377e23a2Schristos struct bfd_symbol ** sym, 449377e23a2Schristos unsigned int sym_index) 450377e23a2Schristos { 451377e23a2Schristos arelent * entry; 452377e23a2Schristos struct internal_reloc * internal; 453377e23a2Schristos 454377e23a2Schristos entry = vars->reltab + vars->relcount; 455377e23a2Schristos internal = vars->int_reltab + vars->relcount; 456377e23a2Schristos 457377e23a2Schristos entry->address = address; 458377e23a2Schristos entry->addend = 0; 459377e23a2Schristos entry->howto = bfd_reloc_type_lookup (vars->abfd, reloc); 460377e23a2Schristos entry->sym_ptr_ptr = sym; 461377e23a2Schristos 462377e23a2Schristos internal->r_vaddr = address; 463377e23a2Schristos internal->r_symndx = sym_index; 464377e23a2Schristos internal->r_type = entry->howto->type; 465377e23a2Schristos 466377e23a2Schristos vars->relcount ++; 467377e23a2Schristos 468377e23a2Schristos BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS); 469377e23a2Schristos } 470377e23a2Schristos 471377e23a2Schristos /* Create an empty relocation against the given section. */ 472377e23a2Schristos 473377e23a2Schristos static void 474377e23a2Schristos pe_ILF_make_a_reloc (pe_ILF_vars * vars, 475377e23a2Schristos bfd_vma address, 476377e23a2Schristos bfd_reloc_code_real_type reloc, 477377e23a2Schristos asection_ptr sec) 478377e23a2Schristos { 479377e23a2Schristos pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr, 480377e23a2Schristos coff_section_data (vars->abfd, sec)->i); 481377e23a2Schristos } 482377e23a2Schristos 483377e23a2Schristos /* Move the queued relocs into the given section. */ 484377e23a2Schristos 485377e23a2Schristos static void 486377e23a2Schristos pe_ILF_save_relocs (pe_ILF_vars * vars, 487377e23a2Schristos asection_ptr sec) 488377e23a2Schristos { 489377e23a2Schristos /* Make sure that there is somewhere to store the internal relocs. */ 490377e23a2Schristos if (coff_section_data (vars->abfd, sec) == NULL) 491377e23a2Schristos /* We should probably return an error indication here. */ 492377e23a2Schristos abort (); 493377e23a2Schristos 494377e23a2Schristos coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab; 495377e23a2Schristos coff_section_data (vars->abfd, sec)->keep_relocs = TRUE; 496377e23a2Schristos 497377e23a2Schristos sec->relocation = vars->reltab; 498377e23a2Schristos sec->reloc_count = vars->relcount; 499377e23a2Schristos sec->flags |= SEC_RELOC; 500377e23a2Schristos 501377e23a2Schristos vars->reltab += vars->relcount; 502377e23a2Schristos vars->int_reltab += vars->relcount; 503377e23a2Schristos vars->relcount = 0; 504377e23a2Schristos 505377e23a2Schristos BFD_ASSERT ((bfd_byte *) vars->int_reltab < (bfd_byte *) vars->string_table); 506377e23a2Schristos } 507377e23a2Schristos 508377e23a2Schristos /* Create a global symbol and add it to the relevant tables. */ 509377e23a2Schristos 510377e23a2Schristos static void 511377e23a2Schristos pe_ILF_make_a_symbol (pe_ILF_vars * vars, 512377e23a2Schristos const char * prefix, 513377e23a2Schristos const char * symbol_name, 514377e23a2Schristos asection_ptr section, 515377e23a2Schristos flagword extra_flags) 516377e23a2Schristos { 517377e23a2Schristos coff_symbol_type * sym; 518377e23a2Schristos combined_entry_type * ent; 519377e23a2Schristos SYMENT * esym; 520377e23a2Schristos unsigned short sclass; 521377e23a2Schristos 522377e23a2Schristos if (extra_flags & BSF_LOCAL) 523377e23a2Schristos sclass = C_STAT; 524377e23a2Schristos else 525377e23a2Schristos sclass = C_EXT; 526377e23a2Schristos 527377e23a2Schristos #ifdef THUMBPEMAGIC 528377e23a2Schristos if (vars->magic == THUMBPEMAGIC) 529377e23a2Schristos { 530377e23a2Schristos if (extra_flags & BSF_FUNCTION) 531377e23a2Schristos sclass = C_THUMBEXTFUNC; 532377e23a2Schristos else if (extra_flags & BSF_LOCAL) 533377e23a2Schristos sclass = C_THUMBSTAT; 534377e23a2Schristos else 535377e23a2Schristos sclass = C_THUMBEXT; 536377e23a2Schristos } 537377e23a2Schristos #endif 538377e23a2Schristos 539377e23a2Schristos BFD_ASSERT (vars->sym_index < NUM_ILF_SYMS); 540377e23a2Schristos 541377e23a2Schristos sym = vars->sym_ptr; 542377e23a2Schristos ent = vars->native_ptr; 543377e23a2Schristos esym = vars->esym_ptr; 544377e23a2Schristos 545377e23a2Schristos /* Copy the symbol's name into the string table. */ 546377e23a2Schristos sprintf (vars->string_ptr, "%s%s", prefix, symbol_name); 547377e23a2Schristos 548377e23a2Schristos if (section == NULL) 549*48596154Schristos section = bfd_und_section_ptr; 550377e23a2Schristos 551377e23a2Schristos /* Initialise the external symbol. */ 552377e23a2Schristos H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table, 553377e23a2Schristos esym->e.e.e_offset); 554377e23a2Schristos H_PUT_16 (vars->abfd, section->target_index, esym->e_scnum); 555377e23a2Schristos esym->e_sclass[0] = sclass; 556377e23a2Schristos 557377e23a2Schristos /* The following initialisations are unnecessary - the memory is 558377e23a2Schristos zero initialised. They are just kept here as reminders. */ 559377e23a2Schristos 560377e23a2Schristos /* Initialise the internal symbol structure. */ 561377e23a2Schristos ent->u.syment.n_sclass = sclass; 562377e23a2Schristos ent->u.syment.n_scnum = section->target_index; 563377e23a2Schristos ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym; 564377e23a2Schristos 565377e23a2Schristos sym->symbol.the_bfd = vars->abfd; 566377e23a2Schristos sym->symbol.name = vars->string_ptr; 567377e23a2Schristos sym->symbol.flags = BSF_EXPORT | BSF_GLOBAL | extra_flags; 568377e23a2Schristos sym->symbol.section = section; 569377e23a2Schristos sym->native = ent; 570377e23a2Schristos 571377e23a2Schristos * vars->table_ptr = vars->sym_index; 572377e23a2Schristos * vars->sym_ptr_ptr = sym; 573377e23a2Schristos 574377e23a2Schristos /* Adjust pointers for the next symbol. */ 575377e23a2Schristos vars->sym_index ++; 576377e23a2Schristos vars->sym_ptr ++; 577377e23a2Schristos vars->sym_ptr_ptr ++; 578377e23a2Schristos vars->table_ptr ++; 579377e23a2Schristos vars->native_ptr ++; 580377e23a2Schristos vars->esym_ptr ++; 581377e23a2Schristos vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1; 582377e23a2Schristos 583377e23a2Schristos BFD_ASSERT (vars->string_ptr < vars->end_string_ptr); 584377e23a2Schristos } 585377e23a2Schristos 586377e23a2Schristos /* Create a section. */ 587377e23a2Schristos 588377e23a2Schristos static asection_ptr 589377e23a2Schristos pe_ILF_make_a_section (pe_ILF_vars * vars, 590377e23a2Schristos const char * name, 591377e23a2Schristos unsigned int size, 592377e23a2Schristos flagword extra_flags) 593377e23a2Schristos { 594377e23a2Schristos asection_ptr sec; 595377e23a2Schristos flagword flags; 596377e23a2Schristos 597377e23a2Schristos sec = bfd_make_section_old_way (vars->abfd, name); 598377e23a2Schristos if (sec == NULL) 599377e23a2Schristos return NULL; 600377e23a2Schristos 601377e23a2Schristos flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY; 602377e23a2Schristos 603377e23a2Schristos bfd_set_section_flags (vars->abfd, sec, flags | extra_flags); 604377e23a2Schristos 605377e23a2Schristos bfd_set_section_alignment (vars->abfd, sec, 2); 606377e23a2Schristos 607377e23a2Schristos /* Check that we will not run out of space. */ 608377e23a2Schristos BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size); 609377e23a2Schristos 610377e23a2Schristos /* Set the section size and contents. The actual 611377e23a2Schristos contents are filled in by our parent. */ 612377e23a2Schristos bfd_set_section_size (vars->abfd, sec, (bfd_size_type) size); 613377e23a2Schristos sec->contents = vars->data; 614377e23a2Schristos sec->target_index = vars->sec_index ++; 615377e23a2Schristos 616377e23a2Schristos /* Advance data pointer in the vars structure. */ 617377e23a2Schristos vars->data += size; 618377e23a2Schristos 619377e23a2Schristos /* Skip the padding byte if it was not needed. 620377e23a2Schristos The logic here is that if the string length is odd, 621377e23a2Schristos then the entire string length, including the null byte, 622377e23a2Schristos is even and so the extra, padding byte, is not needed. */ 623377e23a2Schristos if (size & 1) 624377e23a2Schristos vars->data --; 625377e23a2Schristos 626377e23a2Schristos /* Create a coff_section_tdata structure for our use. */ 627377e23a2Schristos sec->used_by_bfd = (struct coff_section_tdata *) vars->data; 628377e23a2Schristos vars->data += sizeof (struct coff_section_tdata); 629377e23a2Schristos 630377e23a2Schristos BFD_ASSERT (vars->data <= vars->bim->buffer + vars->bim->size); 631377e23a2Schristos 632377e23a2Schristos /* Create a symbol to refer to this section. */ 633377e23a2Schristos pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL); 634377e23a2Schristos 635377e23a2Schristos /* Cache the index to the symbol in the coff_section_data structure. */ 636377e23a2Schristos coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1; 637377e23a2Schristos 638377e23a2Schristos return sec; 639377e23a2Schristos } 640377e23a2Schristos 641377e23a2Schristos /* This structure contains the code that goes into the .text section 642377e23a2Schristos in order to perform a jump into the DLL lookup table. The entries 643377e23a2Schristos in the table are index by the magic number used to represent the 644377e23a2Schristos machine type in the PE file. The contents of the data[] arrays in 645377e23a2Schristos these entries are stolen from the jtab[] arrays in ld/pe-dll.c. 646377e23a2Schristos The SIZE field says how many bytes in the DATA array are actually 647377e23a2Schristos used. The OFFSET field says where in the data array the address 648377e23a2Schristos of the .idata$5 section should be placed. */ 649377e23a2Schristos #define MAX_TEXT_SECTION_SIZE 32 650377e23a2Schristos 651377e23a2Schristos typedef struct 652377e23a2Schristos { 653377e23a2Schristos unsigned short magic; 654377e23a2Schristos unsigned char data[MAX_TEXT_SECTION_SIZE]; 655377e23a2Schristos unsigned int size; 656377e23a2Schristos unsigned int offset; 657377e23a2Schristos } 658377e23a2Schristos jump_table; 659377e23a2Schristos 660377e23a2Schristos static jump_table jtab[] = 661377e23a2Schristos { 662377e23a2Schristos #ifdef I386MAGIC 663377e23a2Schristos { I386MAGIC, 664377e23a2Schristos { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 }, 665377e23a2Schristos 8, 2 666377e23a2Schristos }, 667377e23a2Schristos #endif 668377e23a2Schristos 669377e23a2Schristos #ifdef AMD64MAGIC 670377e23a2Schristos { AMD64MAGIC, 671377e23a2Schristos { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 }, 672377e23a2Schristos 8, 2 673377e23a2Schristos }, 674377e23a2Schristos #endif 675377e23a2Schristos 676377e23a2Schristos #ifdef MC68MAGIC 677377e23a2Schristos { MC68MAGIC, 678377e23a2Schristos { /* XXX fill me in */ }, 679377e23a2Schristos 0, 0 680377e23a2Schristos }, 681377e23a2Schristos #endif 682377e23a2Schristos 683377e23a2Schristos #ifdef MIPS_ARCH_MAGIC_WINCE 684377e23a2Schristos { MIPS_ARCH_MAGIC_WINCE, 685377e23a2Schristos { 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d, 686377e23a2Schristos 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }, 687377e23a2Schristos 16, 0 688377e23a2Schristos }, 689377e23a2Schristos #endif 690377e23a2Schristos 691377e23a2Schristos #ifdef SH_ARCH_MAGIC_WINCE 692377e23a2Schristos { SH_ARCH_MAGIC_WINCE, 693377e23a2Schristos { 0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40, 694377e23a2Schristos 0x09, 0x00, 0x00, 0x00, 0x00, 0x00 }, 695377e23a2Schristos 12, 8 696377e23a2Schristos }, 697377e23a2Schristos #endif 698377e23a2Schristos 699377e23a2Schristos #ifdef ARMPEMAGIC 700377e23a2Schristos { ARMPEMAGIC, 701377e23a2Schristos { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0, 702377e23a2Schristos 0x9c, 0xe5, 0x00, 0x00, 0x00, 0x00}, 703377e23a2Schristos 12, 8 704377e23a2Schristos }, 705377e23a2Schristos #endif 706377e23a2Schristos 707377e23a2Schristos #ifdef THUMBPEMAGIC 708377e23a2Schristos { THUMBPEMAGIC, 709377e23a2Schristos { 0x40, 0xb4, 0x02, 0x4e, 0x36, 0x68, 0xb4, 0x46, 710377e23a2Schristos 0x40, 0xbc, 0x60, 0x47, 0x00, 0x00, 0x00, 0x00 }, 711377e23a2Schristos 16, 12 712377e23a2Schristos }, 713377e23a2Schristos #endif 714377e23a2Schristos { 0, { 0 }, 0, 0 } 715377e23a2Schristos }; 716377e23a2Schristos 717377e23a2Schristos #ifndef NUM_ENTRIES 718377e23a2Schristos #define NUM_ENTRIES(a) (sizeof (a) / sizeof (a)[0]) 719377e23a2Schristos #endif 720377e23a2Schristos 721377e23a2Schristos /* Build a full BFD from the information supplied in a ILF object. */ 722377e23a2Schristos 723377e23a2Schristos static bfd_boolean 724377e23a2Schristos pe_ILF_build_a_bfd (bfd * abfd, 725377e23a2Schristos unsigned int magic, 726377e23a2Schristos char * symbol_name, 727377e23a2Schristos char * source_dll, 728377e23a2Schristos unsigned int ordinal, 729377e23a2Schristos unsigned int types) 730377e23a2Schristos { 731377e23a2Schristos bfd_byte * ptr; 732377e23a2Schristos pe_ILF_vars vars; 733377e23a2Schristos struct internal_filehdr internal_f; 734377e23a2Schristos unsigned int import_type; 735377e23a2Schristos unsigned int import_name_type; 736377e23a2Schristos asection_ptr id4, id5, id6 = NULL, text = NULL; 737377e23a2Schristos coff_symbol_type ** imp_sym; 738377e23a2Schristos unsigned int imp_index; 739377e23a2Schristos 740377e23a2Schristos /* Decode and verify the types field of the ILF structure. */ 741377e23a2Schristos import_type = types & 0x3; 742377e23a2Schristos import_name_type = (types & 0x1c) >> 2; 743377e23a2Schristos 744377e23a2Schristos switch (import_type) 745377e23a2Schristos { 746377e23a2Schristos case IMPORT_CODE: 747377e23a2Schristos case IMPORT_DATA: 748377e23a2Schristos break; 749377e23a2Schristos 750377e23a2Schristos case IMPORT_CONST: 751377e23a2Schristos /* XXX code yet to be written. */ 752377e23a2Schristos _bfd_error_handler (_("%B: Unhandled import type; %x"), 753377e23a2Schristos abfd, import_type); 754377e23a2Schristos return FALSE; 755377e23a2Schristos 756377e23a2Schristos default: 757377e23a2Schristos _bfd_error_handler (_("%B: Unrecognised import type; %x"), 758377e23a2Schristos abfd, import_type); 759377e23a2Schristos return FALSE; 760377e23a2Schristos } 761377e23a2Schristos 762377e23a2Schristos switch (import_name_type) 763377e23a2Schristos { 764377e23a2Schristos case IMPORT_ORDINAL: 765377e23a2Schristos case IMPORT_NAME: 766377e23a2Schristos case IMPORT_NAME_NOPREFIX: 767377e23a2Schristos case IMPORT_NAME_UNDECORATE: 768377e23a2Schristos break; 769377e23a2Schristos 770377e23a2Schristos default: 771377e23a2Schristos _bfd_error_handler (_("%B: Unrecognised import name type; %x"), 772377e23a2Schristos abfd, import_name_type); 773377e23a2Schristos return FALSE; 774377e23a2Schristos } 775377e23a2Schristos 776377e23a2Schristos /* Initialise local variables. 777377e23a2Schristos 778377e23a2Schristos Note these are kept in a structure rather than being 779377e23a2Schristos declared as statics since bfd frowns on global variables. 780377e23a2Schristos 781377e23a2Schristos We are going to construct the contents of the BFD in memory, 782377e23a2Schristos so allocate all the space that we will need right now. */ 783377e23a2Schristos vars.bim 784377e23a2Schristos = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim)); 785377e23a2Schristos if (vars.bim == NULL) 786377e23a2Schristos return FALSE; 787377e23a2Schristos 788377e23a2Schristos ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE); 789377e23a2Schristos vars.bim->buffer = ptr; 790377e23a2Schristos vars.bim->size = ILF_DATA_SIZE; 791377e23a2Schristos if (ptr == NULL) 792377e23a2Schristos goto error_return; 793377e23a2Schristos 794377e23a2Schristos /* Initialise the pointers to regions of the memory and the 795377e23a2Schristos other contents of the pe_ILF_vars structure as well. */ 796377e23a2Schristos vars.sym_cache = (coff_symbol_type *) ptr; 797377e23a2Schristos vars.sym_ptr = (coff_symbol_type *) ptr; 798377e23a2Schristos vars.sym_index = 0; 799377e23a2Schristos ptr += SIZEOF_ILF_SYMS; 800377e23a2Schristos 801377e23a2Schristos vars.sym_table = (unsigned int *) ptr; 802377e23a2Schristos vars.table_ptr = (unsigned int *) ptr; 803377e23a2Schristos ptr += SIZEOF_ILF_SYM_TABLE; 804377e23a2Schristos 805377e23a2Schristos vars.native_syms = (combined_entry_type *) ptr; 806377e23a2Schristos vars.native_ptr = (combined_entry_type *) ptr; 807377e23a2Schristos ptr += SIZEOF_ILF_NATIVE_SYMS; 808377e23a2Schristos 809377e23a2Schristos vars.sym_ptr_table = (coff_symbol_type **) ptr; 810377e23a2Schristos vars.sym_ptr_ptr = (coff_symbol_type **) ptr; 811377e23a2Schristos ptr += SIZEOF_ILF_SYM_PTR_TABLE; 812377e23a2Schristos 813377e23a2Schristos vars.esym_table = (SYMENT *) ptr; 814377e23a2Schristos vars.esym_ptr = (SYMENT *) ptr; 815377e23a2Schristos ptr += SIZEOF_ILF_EXT_SYMS; 816377e23a2Schristos 817377e23a2Schristos vars.reltab = (arelent *) ptr; 818377e23a2Schristos vars.relcount = 0; 819377e23a2Schristos ptr += SIZEOF_ILF_RELOCS; 820377e23a2Schristos 821377e23a2Schristos vars.int_reltab = (struct internal_reloc *) ptr; 822377e23a2Schristos ptr += SIZEOF_ILF_INT_RELOCS; 823377e23a2Schristos 824377e23a2Schristos vars.string_table = (char *) ptr; 825377e23a2Schristos vars.string_ptr = (char *) ptr + STRING_SIZE_SIZE; 826377e23a2Schristos ptr += SIZEOF_ILF_STRINGS; 827377e23a2Schristos vars.end_string_ptr = (char *) ptr; 828377e23a2Schristos 829377e23a2Schristos /* The remaining space in bim->buffer is used 830377e23a2Schristos by the pe_ILF_make_a_section() function. */ 831377e23a2Schristos vars.data = ptr; 832377e23a2Schristos vars.abfd = abfd; 833377e23a2Schristos vars.sec_index = 0; 834377e23a2Schristos vars.magic = magic; 835377e23a2Schristos 836377e23a2Schristos /* Create the initial .idata$<n> sections: 837377e23a2Schristos [.idata$2: Import Directory Table -- not needed] 838377e23a2Schristos .idata$4: Import Lookup Table 839377e23a2Schristos .idata$5: Import Address Table 840377e23a2Schristos 841377e23a2Schristos Note we do not create a .idata$3 section as this is 842377e23a2Schristos created for us by the linker script. */ 843377e23a2Schristos id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0); 844377e23a2Schristos id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0); 845377e23a2Schristos if (id4 == NULL || id5 == NULL) 846377e23a2Schristos goto error_return; 847377e23a2Schristos 848377e23a2Schristos /* Fill in the contents of these sections. */ 849377e23a2Schristos if (import_name_type == IMPORT_ORDINAL) 850377e23a2Schristos { 851377e23a2Schristos if (ordinal == 0) 852377e23a2Schristos /* XXX - treat as IMPORT_NAME ??? */ 853377e23a2Schristos abort (); 854377e23a2Schristos 855377e23a2Schristos #ifdef COFF_WITH_pex64 856377e23a2Schristos ((unsigned int *) id4->contents)[0] = ordinal; 857377e23a2Schristos ((unsigned int *) id4->contents)[1] = 0x80000000; 858377e23a2Schristos ((unsigned int *) id5->contents)[0] = ordinal; 859377e23a2Schristos ((unsigned int *) id5->contents)[1] = 0x80000000; 860377e23a2Schristos #else 861377e23a2Schristos * (unsigned int *) id4->contents = ordinal | 0x80000000; 862377e23a2Schristos * (unsigned int *) id5->contents = ordinal | 0x80000000; 863377e23a2Schristos #endif 864377e23a2Schristos } 865377e23a2Schristos else 866377e23a2Schristos { 867377e23a2Schristos char * symbol; 868377e23a2Schristos unsigned int len; 869377e23a2Schristos 870377e23a2Schristos /* Create .idata$6 - the Hint Name Table. */ 871377e23a2Schristos id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0); 872377e23a2Schristos if (id6 == NULL) 873377e23a2Schristos goto error_return; 874377e23a2Schristos 875377e23a2Schristos /* If necessary, trim the import symbol name. */ 876377e23a2Schristos symbol = symbol_name; 877377e23a2Schristos 878377e23a2Schristos /* As used by MS compiler, '_', '@', and '?' are alternative 879377e23a2Schristos forms of USER_LABEL_PREFIX, with '?' for c++ mangled names, 880377e23a2Schristos '@' used for fastcall (in C), '_' everywhere else. Only one 881377e23a2Schristos of these is used for a symbol. We strip this leading char for 882377e23a2Schristos IMPORT_NAME_NOPREFIX and IMPORT_NAME_UNDECORATE as per the 883377e23a2Schristos PE COFF 6.0 spec (section 8.3, Import Name Type). */ 884377e23a2Schristos 885377e23a2Schristos if (import_name_type != IMPORT_NAME) 886377e23a2Schristos { 887377e23a2Schristos char c = symbol[0]; 888*48596154Schristos 889*48596154Schristos /* Check that we don't remove for targets with empty 890*48596154Schristos USER_LABEL_PREFIX the leading underscore. */ 891*48596154Schristos if ((c == '_' && abfd->xvec->symbol_leading_char != 0) 892*48596154Schristos || c == '@' || c == '?') 893377e23a2Schristos symbol++; 894377e23a2Schristos } 895377e23a2Schristos 896377e23a2Schristos len = strlen (symbol); 897377e23a2Schristos if (import_name_type == IMPORT_NAME_UNDECORATE) 898377e23a2Schristos { 899377e23a2Schristos /* Truncate at the first '@'. */ 900377e23a2Schristos char *at = strchr (symbol, '@'); 901377e23a2Schristos 902377e23a2Schristos if (at != NULL) 903377e23a2Schristos len = at - symbol; 904377e23a2Schristos } 905377e23a2Schristos 906377e23a2Schristos id6->contents[0] = ordinal & 0xff; 907377e23a2Schristos id6->contents[1] = ordinal >> 8; 908377e23a2Schristos 909377e23a2Schristos memcpy ((char *) id6->contents + 2, symbol, len); 910377e23a2Schristos id6->contents[len + 2] = '\0'; 911377e23a2Schristos } 912377e23a2Schristos 913377e23a2Schristos if (import_name_type != IMPORT_ORDINAL) 914377e23a2Schristos { 915377e23a2Schristos pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6); 916377e23a2Schristos pe_ILF_save_relocs (&vars, id4); 917377e23a2Schristos 918377e23a2Schristos pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6); 919377e23a2Schristos pe_ILF_save_relocs (&vars, id5); 920377e23a2Schristos } 921377e23a2Schristos 922377e23a2Schristos /* Create extra sections depending upon the type of import we are dealing with. */ 923377e23a2Schristos switch (import_type) 924377e23a2Schristos { 925377e23a2Schristos int i; 926377e23a2Schristos 927377e23a2Schristos case IMPORT_CODE: 928377e23a2Schristos /* Create a .text section. 929377e23a2Schristos First we need to look up its contents in the jump table. */ 930377e23a2Schristos for (i = NUM_ENTRIES (jtab); i--;) 931377e23a2Schristos { 932377e23a2Schristos if (jtab[i].size == 0) 933377e23a2Schristos continue; 934377e23a2Schristos if (jtab[i].magic == magic) 935377e23a2Schristos break; 936377e23a2Schristos } 937377e23a2Schristos /* If we did not find a matching entry something is wrong. */ 938377e23a2Schristos if (i < 0) 939377e23a2Schristos abort (); 940377e23a2Schristos 941377e23a2Schristos /* Create the .text section. */ 942377e23a2Schristos text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE); 943377e23a2Schristos if (text == NULL) 944377e23a2Schristos goto error_return; 945377e23a2Schristos 946377e23a2Schristos /* Copy in the jump code. */ 947377e23a2Schristos memcpy (text->contents, jtab[i].data, jtab[i].size); 948377e23a2Schristos 949377e23a2Schristos /* Create an import symbol. */ 950377e23a2Schristos pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0); 951377e23a2Schristos imp_sym = vars.sym_ptr_ptr - 1; 952377e23a2Schristos imp_index = vars.sym_index - 1; 953377e23a2Schristos 954377e23a2Schristos /* Create a reloc for the data in the text section. */ 955377e23a2Schristos #ifdef MIPS_ARCH_MAGIC_WINCE 956377e23a2Schristos if (magic == MIPS_ARCH_MAGIC_WINCE) 957377e23a2Schristos { 958377e23a2Schristos pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S, 959377e23a2Schristos (struct bfd_symbol **) imp_sym, 960377e23a2Schristos imp_index); 961377e23a2Schristos pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text); 962377e23a2Schristos pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16, 963377e23a2Schristos (struct bfd_symbol **) imp_sym, 964377e23a2Schristos imp_index); 965377e23a2Schristos } 966377e23a2Schristos else 967377e23a2Schristos #endif 968377e23a2Schristos pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset, 969377e23a2Schristos BFD_RELOC_32, (asymbol **) imp_sym, 970377e23a2Schristos imp_index); 971377e23a2Schristos 972377e23a2Schristos pe_ILF_save_relocs (& vars, text); 973377e23a2Schristos break; 974377e23a2Schristos 975377e23a2Schristos case IMPORT_DATA: 976377e23a2Schristos break; 977377e23a2Schristos 978377e23a2Schristos default: 979377e23a2Schristos /* XXX code not yet written. */ 980377e23a2Schristos abort (); 981377e23a2Schristos } 982377e23a2Schristos 983377e23a2Schristos /* Initialise the bfd. */ 984377e23a2Schristos memset (& internal_f, 0, sizeof (internal_f)); 985377e23a2Schristos 986377e23a2Schristos internal_f.f_magic = magic; 987377e23a2Schristos internal_f.f_symptr = 0; 988377e23a2Schristos internal_f.f_nsyms = 0; 989377e23a2Schristos internal_f.f_flags = F_AR32WR | F_LNNO; /* XXX is this correct ? */ 990377e23a2Schristos 991377e23a2Schristos if ( ! bfd_set_start_address (abfd, (bfd_vma) 0) 992377e23a2Schristos || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f)) 993377e23a2Schristos goto error_return; 994377e23a2Schristos 995377e23a2Schristos if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL) 996377e23a2Schristos goto error_return; 997377e23a2Schristos 998377e23a2Schristos coff_data (abfd)->pe = 1; 999377e23a2Schristos #ifdef THUMBPEMAGIC 1000377e23a2Schristos if (vars.magic == THUMBPEMAGIC) 1001377e23a2Schristos /* Stop some linker warnings about thumb code not supporting interworking. */ 1002377e23a2Schristos coff_data (abfd)->flags |= F_INTERWORK | F_INTERWORK_SET; 1003377e23a2Schristos #endif 1004377e23a2Schristos 1005377e23a2Schristos /* Switch from file contents to memory contents. */ 1006377e23a2Schristos bfd_cache_close (abfd); 1007377e23a2Schristos 1008377e23a2Schristos abfd->iostream = (void *) vars.bim; 1009377e23a2Schristos abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */; 1010377e23a2Schristos abfd->iovec = &_bfd_memory_iovec; 1011377e23a2Schristos abfd->where = 0; 1012377e23a2Schristos abfd->origin = 0; 1013377e23a2Schristos obj_sym_filepos (abfd) = 0; 1014377e23a2Schristos 1015377e23a2Schristos /* Now create a symbol describing the imported value. */ 1016377e23a2Schristos switch (import_type) 1017377e23a2Schristos { 1018377e23a2Schristos case IMPORT_CODE: 1019377e23a2Schristos pe_ILF_make_a_symbol (& vars, "", symbol_name, text, 1020377e23a2Schristos BSF_NOT_AT_END | BSF_FUNCTION); 1021377e23a2Schristos 1022377e23a2Schristos /* Create an import symbol for the DLL, without the 1023377e23a2Schristos .dll suffix. */ 1024377e23a2Schristos ptr = (bfd_byte *) strrchr (source_dll, '.'); 1025377e23a2Schristos if (ptr) 1026377e23a2Schristos * ptr = 0; 1027377e23a2Schristos pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0); 1028377e23a2Schristos if (ptr) 1029377e23a2Schristos * ptr = '.'; 1030377e23a2Schristos break; 1031377e23a2Schristos 1032377e23a2Schristos case IMPORT_DATA: 1033377e23a2Schristos /* Nothing to do here. */ 1034377e23a2Schristos break; 1035377e23a2Schristos 1036377e23a2Schristos default: 1037377e23a2Schristos /* XXX code not yet written. */ 1038377e23a2Schristos abort (); 1039377e23a2Schristos } 1040377e23a2Schristos 1041377e23a2Schristos /* Point the bfd at the symbol table. */ 1042377e23a2Schristos obj_symbols (abfd) = vars.sym_cache; 1043377e23a2Schristos bfd_get_symcount (abfd) = vars.sym_index; 1044377e23a2Schristos 1045377e23a2Schristos obj_raw_syments (abfd) = vars.native_syms; 1046377e23a2Schristos obj_raw_syment_count (abfd) = vars.sym_index; 1047377e23a2Schristos 1048377e23a2Schristos obj_coff_external_syms (abfd) = (void *) vars.esym_table; 1049377e23a2Schristos obj_coff_keep_syms (abfd) = TRUE; 1050377e23a2Schristos 1051377e23a2Schristos obj_convert (abfd) = vars.sym_table; 1052377e23a2Schristos obj_conv_table_size (abfd) = vars.sym_index; 1053377e23a2Schristos 1054377e23a2Schristos obj_coff_strings (abfd) = vars.string_table; 1055377e23a2Schristos obj_coff_keep_strings (abfd) = TRUE; 1056377e23a2Schristos 1057377e23a2Schristos abfd->flags |= HAS_SYMS; 1058377e23a2Schristos 1059377e23a2Schristos return TRUE; 1060377e23a2Schristos 1061377e23a2Schristos error_return: 1062377e23a2Schristos if (vars.bim->buffer != NULL) 1063377e23a2Schristos free (vars.bim->buffer); 1064377e23a2Schristos free (vars.bim); 1065377e23a2Schristos return FALSE; 1066377e23a2Schristos } 1067377e23a2Schristos 1068377e23a2Schristos /* We have detected a Image Library Format archive element. 1069377e23a2Schristos Decode the element and return the appropriate target. */ 1070377e23a2Schristos 1071377e23a2Schristos static const bfd_target * 1072377e23a2Schristos pe_ILF_object_p (bfd * abfd) 1073377e23a2Schristos { 1074377e23a2Schristos bfd_byte buffer[16]; 1075377e23a2Schristos bfd_byte * ptr; 1076377e23a2Schristos char * symbol_name; 1077377e23a2Schristos char * source_dll; 1078377e23a2Schristos unsigned int machine; 1079377e23a2Schristos bfd_size_type size; 1080377e23a2Schristos unsigned int ordinal; 1081377e23a2Schristos unsigned int types; 1082377e23a2Schristos unsigned int magic; 1083377e23a2Schristos 1084377e23a2Schristos /* Upon entry the first four buyes of the ILF header have 1085377e23a2Schristos already been read. Now read the rest of the header. */ 1086377e23a2Schristos if (bfd_bread (buffer, (bfd_size_type) 16, abfd) != 16) 1087377e23a2Schristos return NULL; 1088377e23a2Schristos 1089377e23a2Schristos ptr = buffer; 1090377e23a2Schristos 1091377e23a2Schristos /* We do not bother to check the version number. 1092377e23a2Schristos version = H_GET_16 (abfd, ptr); */ 1093377e23a2Schristos ptr += 2; 1094377e23a2Schristos 1095377e23a2Schristos machine = H_GET_16 (abfd, ptr); 1096377e23a2Schristos ptr += 2; 1097377e23a2Schristos 1098377e23a2Schristos /* Check that the machine type is recognised. */ 1099377e23a2Schristos magic = 0; 1100377e23a2Schristos 1101377e23a2Schristos switch (machine) 1102377e23a2Schristos { 1103377e23a2Schristos case IMAGE_FILE_MACHINE_UNKNOWN: 1104377e23a2Schristos case IMAGE_FILE_MACHINE_ALPHA: 1105377e23a2Schristos case IMAGE_FILE_MACHINE_ALPHA64: 1106377e23a2Schristos case IMAGE_FILE_MACHINE_IA64: 1107377e23a2Schristos break; 1108377e23a2Schristos 1109377e23a2Schristos case IMAGE_FILE_MACHINE_I386: 1110377e23a2Schristos #ifdef I386MAGIC 1111377e23a2Schristos magic = I386MAGIC; 1112377e23a2Schristos #endif 1113377e23a2Schristos break; 1114377e23a2Schristos 1115377e23a2Schristos case IMAGE_FILE_MACHINE_AMD64: 1116377e23a2Schristos #ifdef AMD64MAGIC 1117377e23a2Schristos magic = AMD64MAGIC; 1118377e23a2Schristos #endif 1119377e23a2Schristos break; 1120377e23a2Schristos 1121377e23a2Schristos case IMAGE_FILE_MACHINE_M68K: 1122377e23a2Schristos #ifdef MC68AGIC 1123377e23a2Schristos magic = MC68MAGIC; 1124377e23a2Schristos #endif 1125377e23a2Schristos break; 1126377e23a2Schristos 1127377e23a2Schristos case IMAGE_FILE_MACHINE_R3000: 1128377e23a2Schristos case IMAGE_FILE_MACHINE_R4000: 1129377e23a2Schristos case IMAGE_FILE_MACHINE_R10000: 1130377e23a2Schristos 1131377e23a2Schristos case IMAGE_FILE_MACHINE_MIPS16: 1132377e23a2Schristos case IMAGE_FILE_MACHINE_MIPSFPU: 1133377e23a2Schristos case IMAGE_FILE_MACHINE_MIPSFPU16: 1134377e23a2Schristos #ifdef MIPS_ARCH_MAGIC_WINCE 1135377e23a2Schristos magic = MIPS_ARCH_MAGIC_WINCE; 1136377e23a2Schristos #endif 1137377e23a2Schristos break; 1138377e23a2Schristos 1139377e23a2Schristos case IMAGE_FILE_MACHINE_SH3: 1140377e23a2Schristos case IMAGE_FILE_MACHINE_SH4: 1141377e23a2Schristos #ifdef SH_ARCH_MAGIC_WINCE 1142377e23a2Schristos magic = SH_ARCH_MAGIC_WINCE; 1143377e23a2Schristos #endif 1144377e23a2Schristos break; 1145377e23a2Schristos 1146377e23a2Schristos case IMAGE_FILE_MACHINE_ARM: 1147377e23a2Schristos #ifdef ARMPEMAGIC 1148377e23a2Schristos magic = ARMPEMAGIC; 1149377e23a2Schristos #endif 1150377e23a2Schristos break; 1151377e23a2Schristos 1152377e23a2Schristos case IMAGE_FILE_MACHINE_THUMB: 1153377e23a2Schristos #ifdef THUMBPEMAGIC 1154377e23a2Schristos { 1155377e23a2Schristos extern const bfd_target TARGET_LITTLE_SYM; 1156377e23a2Schristos 1157377e23a2Schristos if (abfd->xvec == & TARGET_LITTLE_SYM) 1158377e23a2Schristos magic = THUMBPEMAGIC; 1159377e23a2Schristos } 1160377e23a2Schristos #endif 1161377e23a2Schristos break; 1162377e23a2Schristos 1163377e23a2Schristos case IMAGE_FILE_MACHINE_POWERPC: 1164377e23a2Schristos /* We no longer support PowerPC. */ 1165377e23a2Schristos default: 1166377e23a2Schristos _bfd_error_handler 1167377e23a2Schristos (_("%B: Unrecognised machine type (0x%x)" 1168377e23a2Schristos " in Import Library Format archive"), 1169377e23a2Schristos abfd, machine); 1170377e23a2Schristos bfd_set_error (bfd_error_malformed_archive); 1171377e23a2Schristos 1172377e23a2Schristos return NULL; 1173377e23a2Schristos break; 1174377e23a2Schristos } 1175377e23a2Schristos 1176377e23a2Schristos if (magic == 0) 1177377e23a2Schristos { 1178377e23a2Schristos _bfd_error_handler 1179377e23a2Schristos (_("%B: Recognised but unhandled machine type (0x%x)" 1180377e23a2Schristos " in Import Library Format archive"), 1181377e23a2Schristos abfd, machine); 1182377e23a2Schristos bfd_set_error (bfd_error_wrong_format); 1183377e23a2Schristos 1184377e23a2Schristos return NULL; 1185377e23a2Schristos } 1186377e23a2Schristos 1187377e23a2Schristos /* We do not bother to check the date. 1188377e23a2Schristos date = H_GET_32 (abfd, ptr); */ 1189377e23a2Schristos ptr += 4; 1190377e23a2Schristos 1191377e23a2Schristos size = H_GET_32 (abfd, ptr); 1192377e23a2Schristos ptr += 4; 1193377e23a2Schristos 1194377e23a2Schristos if (size == 0) 1195377e23a2Schristos { 1196377e23a2Schristos _bfd_error_handler 1197377e23a2Schristos (_("%B: size field is zero in Import Library Format header"), abfd); 1198377e23a2Schristos bfd_set_error (bfd_error_malformed_archive); 1199377e23a2Schristos 1200377e23a2Schristos return NULL; 1201377e23a2Schristos } 1202377e23a2Schristos 1203377e23a2Schristos ordinal = H_GET_16 (abfd, ptr); 1204377e23a2Schristos ptr += 2; 1205377e23a2Schristos 1206377e23a2Schristos types = H_GET_16 (abfd, ptr); 1207377e23a2Schristos /* ptr += 2; */ 1208377e23a2Schristos 1209377e23a2Schristos /* Now read in the two strings that follow. */ 1210377e23a2Schristos ptr = (bfd_byte *) bfd_alloc (abfd, size); 1211377e23a2Schristos if (ptr == NULL) 1212377e23a2Schristos return NULL; 1213377e23a2Schristos 1214377e23a2Schristos if (bfd_bread (ptr, size, abfd) != size) 1215377e23a2Schristos { 1216377e23a2Schristos bfd_release (abfd, ptr); 1217377e23a2Schristos return NULL; 1218377e23a2Schristos } 1219377e23a2Schristos 1220377e23a2Schristos symbol_name = (char *) ptr; 1221377e23a2Schristos source_dll = symbol_name + strlen (symbol_name) + 1; 1222377e23a2Schristos 1223377e23a2Schristos /* Verify that the strings are null terminated. */ 1224377e23a2Schristos if (ptr[size - 1] != 0 1225377e23a2Schristos || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size) 1226377e23a2Schristos { 1227377e23a2Schristos _bfd_error_handler 1228377e23a2Schristos (_("%B: string not null terminated in ILF object file."), abfd); 1229377e23a2Schristos bfd_set_error (bfd_error_malformed_archive); 1230377e23a2Schristos bfd_release (abfd, ptr); 1231377e23a2Schristos return NULL; 1232377e23a2Schristos } 1233377e23a2Schristos 1234377e23a2Schristos /* Now construct the bfd. */ 1235377e23a2Schristos if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name, 1236377e23a2Schristos source_dll, ordinal, types)) 1237377e23a2Schristos { 1238377e23a2Schristos bfd_release (abfd, ptr); 1239377e23a2Schristos return NULL; 1240377e23a2Schristos } 1241377e23a2Schristos 1242377e23a2Schristos return abfd->xvec; 1243377e23a2Schristos } 1244377e23a2Schristos 1245377e23a2Schristos static const bfd_target * 1246377e23a2Schristos pe_bfd_object_p (bfd * abfd) 1247377e23a2Schristos { 1248377e23a2Schristos bfd_byte buffer[4]; 1249377e23a2Schristos struct external_PEI_DOS_hdr dos_hdr; 1250377e23a2Schristos struct external_PEI_IMAGE_hdr image_hdr; 1251377e23a2Schristos file_ptr offset; 1252377e23a2Schristos 1253377e23a2Schristos /* Detect if this a Microsoft Import Library Format element. */ 1254377e23a2Schristos if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 1255377e23a2Schristos || bfd_bread (buffer, (bfd_size_type) 4, abfd) != 4) 1256377e23a2Schristos { 1257377e23a2Schristos if (bfd_get_error () != bfd_error_system_call) 1258377e23a2Schristos bfd_set_error (bfd_error_wrong_format); 1259377e23a2Schristos return NULL; 1260377e23a2Schristos } 1261377e23a2Schristos 1262377e23a2Schristos if (H_GET_32 (abfd, buffer) == 0xffff0000) 1263377e23a2Schristos return pe_ILF_object_p (abfd); 1264377e23a2Schristos 1265377e23a2Schristos if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 1266377e23a2Schristos || bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd) 1267377e23a2Schristos != sizeof (dos_hdr)) 1268377e23a2Schristos { 1269377e23a2Schristos if (bfd_get_error () != bfd_error_system_call) 1270377e23a2Schristos bfd_set_error (bfd_error_wrong_format); 1271377e23a2Schristos return NULL; 1272377e23a2Schristos } 1273377e23a2Schristos 1274377e23a2Schristos /* There are really two magic numbers involved; the magic number 1275377e23a2Schristos that says this is a NT executable (PEI) and the magic number that 1276377e23a2Schristos determines the architecture. The former is DOSMAGIC, stored in 1277377e23a2Schristos the e_magic field. The latter is stored in the f_magic field. 1278377e23a2Schristos If the NT magic number isn't valid, the architecture magic number 1279377e23a2Schristos could be mimicked by some other field (specifically, the number 1280377e23a2Schristos of relocs in section 3). Since this routine can only be called 1281377e23a2Schristos correctly for a PEI file, check the e_magic number here, and, if 1282377e23a2Schristos it doesn't match, clobber the f_magic number so that we don't get 1283377e23a2Schristos a false match. */ 1284377e23a2Schristos if (H_GET_16 (abfd, dos_hdr.e_magic) != DOSMAGIC) 1285377e23a2Schristos { 1286377e23a2Schristos bfd_set_error (bfd_error_wrong_format); 1287377e23a2Schristos return NULL; 1288377e23a2Schristos } 1289377e23a2Schristos 1290377e23a2Schristos offset = H_GET_32 (abfd, dos_hdr.e_lfanew); 1291377e23a2Schristos if (bfd_seek (abfd, offset, SEEK_SET) != 0 1292377e23a2Schristos || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd) 1293377e23a2Schristos != sizeof (image_hdr))) 1294377e23a2Schristos { 1295377e23a2Schristos if (bfd_get_error () != bfd_error_system_call) 1296377e23a2Schristos bfd_set_error (bfd_error_wrong_format); 1297377e23a2Schristos return NULL; 1298377e23a2Schristos } 1299377e23a2Schristos 1300377e23a2Schristos if (H_GET_32 (abfd, image_hdr.nt_signature) != 0x4550) 1301377e23a2Schristos { 1302377e23a2Schristos bfd_set_error (bfd_error_wrong_format); 1303377e23a2Schristos return NULL; 1304377e23a2Schristos } 1305377e23a2Schristos 1306377e23a2Schristos /* Here is the hack. coff_object_p wants to read filhsz bytes to 1307377e23a2Schristos pick up the COFF header for PE, see "struct external_PEI_filehdr" 1308377e23a2Schristos in include/coff/pe.h. We adjust so that that will work. */ 1309377e23a2Schristos if (bfd_seek (abfd, (file_ptr) (offset - sizeof (dos_hdr)), SEEK_SET) != 0) 1310377e23a2Schristos { 1311377e23a2Schristos if (bfd_get_error () != bfd_error_system_call) 1312377e23a2Schristos bfd_set_error (bfd_error_wrong_format); 1313377e23a2Schristos return NULL; 1314377e23a2Schristos } 1315377e23a2Schristos 1316377e23a2Schristos return coff_object_p (abfd); 1317377e23a2Schristos } 1318377e23a2Schristos 1319377e23a2Schristos #define coff_object_p pe_bfd_object_p 1320377e23a2Schristos #endif /* COFF_IMAGE_WITH_PE */ 1321