175fd0b74Schristos /* Support for the generic parts of PE/PEI, for BFD.
2*e992f068Schristos Copyright (C) 1995-2022 Free Software Foundation, Inc.
375fd0b74Schristos Written by Cygnus Solutions.
475fd0b74Schristos
575fd0b74Schristos This file is part of BFD, the Binary File Descriptor library.
675fd0b74Schristos
775fd0b74Schristos This program is free software; you can redistribute it and/or modify
875fd0b74Schristos it under the terms of the GNU General Public License as published by
975fd0b74Schristos the Free Software Foundation; either version 3 of the License, or
1075fd0b74Schristos (at your option) any later version.
1175fd0b74Schristos
1275fd0b74Schristos This program is distributed in the hope that it will be useful,
1375fd0b74Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1475fd0b74Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1575fd0b74Schristos GNU General Public License for more details.
1675fd0b74Schristos
1775fd0b74Schristos You should have received a copy of the GNU General Public License
1875fd0b74Schristos along with this program; if not, write to the Free Software
1975fd0b74Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
2075fd0b74Schristos MA 02110-1301, USA. */
2175fd0b74Schristos
2275fd0b74Schristos
2375fd0b74Schristos /* Most of this hacked by Steve Chamberlain,
2475fd0b74Schristos sac@cygnus.com
2575fd0b74Schristos
2675fd0b74Schristos PE/PEI rearrangement (and code added): Donn Terry
2775fd0b74Schristos Softway Systems, Inc. */
2875fd0b74Schristos
2975fd0b74Schristos /* Hey look, some documentation [and in a place you expect to find it]!
3075fd0b74Schristos
3175fd0b74Schristos The main reference for the pei format is "Microsoft Portable Executable
3275fd0b74Schristos and Common Object File Format Specification 4.1". Get it if you need to
3375fd0b74Schristos do some serious hacking on this code.
3475fd0b74Schristos
3575fd0b74Schristos Another reference:
3675fd0b74Schristos "Peering Inside the PE: A Tour of the Win32 Portable Executable
3775fd0b74Schristos File Format", MSJ 1994, Volume 9.
3875fd0b74Schristos
3975fd0b74Schristos The *sole* difference between the pe format and the pei format is that the
4075fd0b74Schristos latter has an MSDOS 2.0 .exe header on the front that prints the message
4175fd0b74Schristos "This app must be run under Windows." (or some such).
4275fd0b74Schristos (FIXME: Whether that statement is *really* true or not is unknown.
4375fd0b74Schristos Are there more subtle differences between pe and pei formats?
4475fd0b74Schristos For now assume there aren't. If you find one, then for God sakes
4575fd0b74Schristos document it here!)
4675fd0b74Schristos
4775fd0b74Schristos The Microsoft docs use the word "image" instead of "executable" because
4875fd0b74Schristos the former can also refer to a DLL (shared library). Confusion can arise
4975fd0b74Schristos because the `i' in `pei' also refers to "image". The `pe' format can
5075fd0b74Schristos also create images (i.e. executables), it's just that to run on a win32
5175fd0b74Schristos system you need to use the pei format.
5275fd0b74Schristos
5375fd0b74Schristos FIXME: Please add more docs here so the next poor fool that has to hack
5475fd0b74Schristos on this code has a chance of getting something accomplished without
5575fd0b74Schristos wasting too much time. */
5675fd0b74Schristos
5775fd0b74Schristos #include "libpei.h"
5875fd0b74Schristos
59*e992f068Schristos static bool (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
6075fd0b74Schristos #ifndef coff_bfd_print_private_bfd_data
6175fd0b74Schristos NULL;
6275fd0b74Schristos #else
6375fd0b74Schristos coff_bfd_print_private_bfd_data;
6475fd0b74Schristos #undef coff_bfd_print_private_bfd_data
6575fd0b74Schristos #endif
6675fd0b74Schristos
67*e992f068Schristos static bool pe_print_private_bfd_data (bfd *, void *);
6875fd0b74Schristos #define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
6975fd0b74Schristos
70*e992f068Schristos static bool (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
7175fd0b74Schristos #ifndef coff_bfd_copy_private_bfd_data
7275fd0b74Schristos NULL;
7375fd0b74Schristos #else
7475fd0b74Schristos coff_bfd_copy_private_bfd_data;
7575fd0b74Schristos #undef coff_bfd_copy_private_bfd_data
7675fd0b74Schristos #endif
7775fd0b74Schristos
78*e992f068Schristos static bool pe_bfd_copy_private_bfd_data (bfd *, bfd *);
7975fd0b74Schristos #define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
8075fd0b74Schristos
8175fd0b74Schristos #define coff_mkobject pe_mkobject
8275fd0b74Schristos #define coff_mkobject_hook pe_mkobject_hook
8375fd0b74Schristos
8475fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
8575fd0b74Schristos /* This structure contains static variables used by the ILF code. */
8675fd0b74Schristos typedef asection * asection_ptr;
8775fd0b74Schristos
8875fd0b74Schristos typedef struct
8975fd0b74Schristos {
9075fd0b74Schristos bfd * abfd;
9175fd0b74Schristos bfd_byte * data;
9275fd0b74Schristos struct bfd_in_memory * bim;
9375fd0b74Schristos unsigned short magic;
9475fd0b74Schristos
9575fd0b74Schristos arelent * reltab;
9675fd0b74Schristos unsigned int relcount;
9775fd0b74Schristos
9875fd0b74Schristos coff_symbol_type * sym_cache;
9975fd0b74Schristos coff_symbol_type * sym_ptr;
10075fd0b74Schristos unsigned int sym_index;
10175fd0b74Schristos
10275fd0b74Schristos unsigned int * sym_table;
10375fd0b74Schristos unsigned int * table_ptr;
10475fd0b74Schristos
10575fd0b74Schristos combined_entry_type * native_syms;
10675fd0b74Schristos combined_entry_type * native_ptr;
10775fd0b74Schristos
10875fd0b74Schristos coff_symbol_type ** sym_ptr_table;
10975fd0b74Schristos coff_symbol_type ** sym_ptr_ptr;
11075fd0b74Schristos
11175fd0b74Schristos unsigned int sec_index;
11275fd0b74Schristos
11375fd0b74Schristos char * string_table;
11475fd0b74Schristos char * string_ptr;
11575fd0b74Schristos char * end_string_ptr;
11675fd0b74Schristos
11775fd0b74Schristos SYMENT * esym_table;
11875fd0b74Schristos SYMENT * esym_ptr;
11975fd0b74Schristos
12075fd0b74Schristos struct internal_reloc * int_reltab;
12175fd0b74Schristos }
12275fd0b74Schristos pe_ILF_vars;
12375fd0b74Schristos #endif /* COFF_IMAGE_WITH_PE */
12475fd0b74Schristos
125*e992f068Schristos bfd_cleanup coff_real_object_p
12675fd0b74Schristos (bfd *, unsigned, struct internal_filehdr *, struct internal_aouthdr *);
12775fd0b74Schristos
12875fd0b74Schristos #ifndef NO_COFF_RELOCS
12975fd0b74Schristos static void
coff_swap_reloc_in(bfd * abfd,void * src,void * dst)13075fd0b74Schristos coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
13175fd0b74Schristos {
13275fd0b74Schristos RELOC *reloc_src = (RELOC *) src;
13375fd0b74Schristos struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
13475fd0b74Schristos
13575fd0b74Schristos reloc_dst->r_vaddr = H_GET_32 (abfd, reloc_src->r_vaddr);
13675fd0b74Schristos reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
13775fd0b74Schristos reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type);
13875fd0b74Schristos #ifdef SWAP_IN_RELOC_OFFSET
13975fd0b74Schristos reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
14075fd0b74Schristos #endif
14175fd0b74Schristos }
14275fd0b74Schristos
14375fd0b74Schristos static unsigned int
coff_swap_reloc_out(bfd * abfd,void * src,void * dst)14475fd0b74Schristos coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
14575fd0b74Schristos {
14675fd0b74Schristos struct internal_reloc *reloc_src = (struct internal_reloc *) src;
14775fd0b74Schristos struct external_reloc *reloc_dst = (struct external_reloc *) dst;
14875fd0b74Schristos
14975fd0b74Schristos H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
15075fd0b74Schristos H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
15175fd0b74Schristos H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
15275fd0b74Schristos
15375fd0b74Schristos #ifdef SWAP_OUT_RELOC_OFFSET
15475fd0b74Schristos SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
15575fd0b74Schristos #endif
15675fd0b74Schristos #ifdef SWAP_OUT_RELOC_EXTRA
15775fd0b74Schristos SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
15875fd0b74Schristos #endif
15975fd0b74Schristos return RELSZ;
16075fd0b74Schristos }
16175fd0b74Schristos #endif /* not NO_COFF_RELOCS */
16275fd0b74Schristos
16375fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
16475fd0b74Schristos #undef FILHDR
16575fd0b74Schristos #define FILHDR struct external_PEI_IMAGE_hdr
16675fd0b74Schristos #endif
16775fd0b74Schristos
16875fd0b74Schristos static void
coff_swap_filehdr_in(bfd * abfd,void * src,void * dst)16975fd0b74Schristos coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
17075fd0b74Schristos {
17175fd0b74Schristos FILHDR *filehdr_src = (FILHDR *) src;
17275fd0b74Schristos struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
17375fd0b74Schristos
17475fd0b74Schristos filehdr_dst->f_magic = H_GET_16 (abfd, filehdr_src->f_magic);
17575fd0b74Schristos filehdr_dst->f_nscns = H_GET_16 (abfd, filehdr_src->f_nscns);
17675fd0b74Schristos filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
17775fd0b74Schristos filehdr_dst->f_nsyms = H_GET_32 (abfd, filehdr_src->f_nsyms);
17875fd0b74Schristos filehdr_dst->f_flags = H_GET_16 (abfd, filehdr_src->f_flags);
17975fd0b74Schristos filehdr_dst->f_symptr = H_GET_32 (abfd, filehdr_src->f_symptr);
18075fd0b74Schristos
18175fd0b74Schristos /* Other people's tools sometimes generate headers with an nsyms but
18275fd0b74Schristos a zero symptr. */
18375fd0b74Schristos if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0)
18475fd0b74Schristos {
18575fd0b74Schristos filehdr_dst->f_nsyms = 0;
18675fd0b74Schristos filehdr_dst->f_flags |= F_LSYMS;
18775fd0b74Schristos }
18875fd0b74Schristos
18975fd0b74Schristos filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src-> f_opthdr);
19075fd0b74Schristos }
19175fd0b74Schristos
19275fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
19375fd0b74Schristos # define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
19475fd0b74Schristos #elif defined COFF_WITH_pex64
19575fd0b74Schristos # define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
19675fd0b74Schristos #elif defined COFF_WITH_pep
19775fd0b74Schristos # define coff_swap_filehdr_out _bfd_pep_only_swap_filehdr_out
19875fd0b74Schristos #else
19975fd0b74Schristos # define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
20075fd0b74Schristos #endif
20175fd0b74Schristos
20275fd0b74Schristos static void
coff_swap_scnhdr_in(bfd * abfd,void * ext,void * in)20375fd0b74Schristos coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
20475fd0b74Schristos {
20575fd0b74Schristos SCNHDR *scnhdr_ext = (SCNHDR *) ext;
20675fd0b74Schristos struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
20775fd0b74Schristos
20875fd0b74Schristos memcpy (scnhdr_int->s_name, scnhdr_ext->s_name, sizeof (scnhdr_int->s_name));
20975fd0b74Schristos
21075fd0b74Schristos scnhdr_int->s_vaddr = GET_SCNHDR_VADDR (abfd, scnhdr_ext->s_vaddr);
21175fd0b74Schristos scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
21275fd0b74Schristos scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
21375fd0b74Schristos scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
21475fd0b74Schristos scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
21575fd0b74Schristos scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
21675fd0b74Schristos scnhdr_int->s_flags = H_GET_32 (abfd, scnhdr_ext->s_flags);
21775fd0b74Schristos
21875fd0b74Schristos /* MS handles overflow of line numbers by carrying into the reloc
21975fd0b74Schristos field (it appears). Since it's supposed to be zero for PE
22075fd0b74Schristos *IMAGE* format, that's safe. This is still a bit iffy. */
22175fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
22275fd0b74Schristos scnhdr_int->s_nlnno = (H_GET_16 (abfd, scnhdr_ext->s_nlnno)
22375fd0b74Schristos + (H_GET_16 (abfd, scnhdr_ext->s_nreloc) << 16));
22475fd0b74Schristos scnhdr_int->s_nreloc = 0;
22575fd0b74Schristos #else
22675fd0b74Schristos scnhdr_int->s_nreloc = H_GET_16 (abfd, scnhdr_ext->s_nreloc);
22775fd0b74Schristos scnhdr_int->s_nlnno = H_GET_16 (abfd, scnhdr_ext->s_nlnno);
22875fd0b74Schristos #endif
22975fd0b74Schristos
23075fd0b74Schristos if (scnhdr_int->s_vaddr != 0)
23175fd0b74Schristos {
23275fd0b74Schristos scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
23375fd0b74Schristos /* Do not cut upper 32-bits for 64-bit vma. */
234*e992f068Schristos #if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64)
23575fd0b74Schristos scnhdr_int->s_vaddr &= 0xffffffff;
23675fd0b74Schristos #endif
23775fd0b74Schristos }
23875fd0b74Schristos
23975fd0b74Schristos #ifndef COFF_NO_HACK_SCNHDR_SIZE
24075fd0b74Schristos /* If this section holds uninitialized data and is from an object file
24175fd0b74Schristos or from an executable image that has not initialized the field,
24275fd0b74Schristos or if the image is an executable file and the physical size is padded,
24375fd0b74Schristos use the virtual size (stored in s_paddr) instead. */
24475fd0b74Schristos if (scnhdr_int->s_paddr > 0
24575fd0b74Schristos && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0
24675fd0b74Schristos && (! bfd_pei_p (abfd) || scnhdr_int->s_size == 0))
24775fd0b74Schristos || (bfd_pei_p (abfd) && (scnhdr_int->s_size > scnhdr_int->s_paddr))))
24875fd0b74Schristos /* This code used to set scnhdr_int->s_paddr to 0. However,
24975fd0b74Schristos coff_set_alignment_hook stores s_paddr in virt_size, which
25075fd0b74Schristos only works if it correctly holds the virtual size of the
25175fd0b74Schristos section. */
25275fd0b74Schristos scnhdr_int->s_size = scnhdr_int->s_paddr;
25375fd0b74Schristos #endif
25475fd0b74Schristos }
25575fd0b74Schristos
256*e992f068Schristos static bool
pe_mkobject(bfd * abfd)25775fd0b74Schristos pe_mkobject (bfd * abfd)
25875fd0b74Schristos {
25975fd0b74Schristos pe_data_type *pe;
260*e992f068Schristos size_t amt = sizeof (pe_data_type);
26175fd0b74Schristos
26275fd0b74Schristos abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt);
26375fd0b74Schristos
26475fd0b74Schristos if (abfd->tdata.pe_obj_data == 0)
265*e992f068Schristos return false;
26675fd0b74Schristos
26775fd0b74Schristos pe = pe_data (abfd);
26875fd0b74Schristos
26975fd0b74Schristos pe->coff.pe = 1;
27075fd0b74Schristos
27175fd0b74Schristos /* in_reloc_p is architecture dependent. */
27275fd0b74Schristos pe->in_reloc_p = in_reloc_p;
27375fd0b74Schristos
274012573ebSchristos /* Default DOS message string. */
275012573ebSchristos pe->dos_message[0] = 0x0eba1f0e;
276012573ebSchristos pe->dos_message[1] = 0xcd09b400;
277012573ebSchristos pe->dos_message[2] = 0x4c01b821;
278012573ebSchristos pe->dos_message[3] = 0x685421cd;
279012573ebSchristos pe->dos_message[4] = 0x70207369;
280012573ebSchristos pe->dos_message[5] = 0x72676f72;
281012573ebSchristos pe->dos_message[6] = 0x63206d61;
282012573ebSchristos pe->dos_message[7] = 0x6f6e6e61;
283012573ebSchristos pe->dos_message[8] = 0x65622074;
284012573ebSchristos pe->dos_message[9] = 0x6e757220;
285012573ebSchristos pe->dos_message[10] = 0x206e6920;
286012573ebSchristos pe->dos_message[11] = 0x20534f44;
287012573ebSchristos pe->dos_message[12] = 0x65646f6d;
288012573ebSchristos pe->dos_message[13] = 0x0a0d0d2e;
289012573ebSchristos pe->dos_message[14] = 0x24;
290012573ebSchristos pe->dos_message[15] = 0x0;
291012573ebSchristos
29275fd0b74Schristos memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr);
293*e992f068Schristos return true;
29475fd0b74Schristos }
29575fd0b74Schristos
29675fd0b74Schristos /* Create the COFF backend specific information. */
29775fd0b74Schristos
29875fd0b74Schristos static void *
pe_mkobject_hook(bfd * abfd,void * filehdr,void * aouthdr ATTRIBUTE_UNUSED)29975fd0b74Schristos pe_mkobject_hook (bfd * abfd,
30075fd0b74Schristos void * filehdr,
30175fd0b74Schristos void * aouthdr ATTRIBUTE_UNUSED)
30275fd0b74Schristos {
30375fd0b74Schristos struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
30475fd0b74Schristos pe_data_type *pe;
30575fd0b74Schristos
30675fd0b74Schristos if (! pe_mkobject (abfd))
30775fd0b74Schristos return NULL;
30875fd0b74Schristos
30975fd0b74Schristos pe = pe_data (abfd);
31075fd0b74Schristos pe->coff.sym_filepos = internal_f->f_symptr;
31175fd0b74Schristos /* These members communicate important constants about the symbol
31275fd0b74Schristos table to GDB's symbol-reading code. These `constants'
31375fd0b74Schristos unfortunately vary among coff implementations... */
31475fd0b74Schristos pe->coff.local_n_btmask = N_BTMASK;
31575fd0b74Schristos pe->coff.local_n_btshft = N_BTSHFT;
31675fd0b74Schristos pe->coff.local_n_tmask = N_TMASK;
31775fd0b74Schristos pe->coff.local_n_tshift = N_TSHIFT;
31875fd0b74Schristos pe->coff.local_symesz = SYMESZ;
31975fd0b74Schristos pe->coff.local_auxesz = AUXESZ;
32075fd0b74Schristos pe->coff.local_linesz = LINESZ;
32175fd0b74Schristos
32275fd0b74Schristos pe->coff.timestamp = internal_f->f_timdat;
32375fd0b74Schristos
32475fd0b74Schristos obj_raw_syment_count (abfd) =
32575fd0b74Schristos obj_conv_table_size (abfd) =
32675fd0b74Schristos internal_f->f_nsyms;
32775fd0b74Schristos
32875fd0b74Schristos pe->real_flags = internal_f->f_flags;
32975fd0b74Schristos
33075fd0b74Schristos if ((internal_f->f_flags & F_DLL) != 0)
33175fd0b74Schristos pe->dll = 1;
33275fd0b74Schristos
33375fd0b74Schristos if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
33475fd0b74Schristos abfd->flags |= HAS_DEBUG;
33575fd0b74Schristos
33675fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
33775fd0b74Schristos if (aouthdr)
33875fd0b74Schristos pe->pe_opthdr = ((struct internal_aouthdr *) aouthdr)->pe;
33975fd0b74Schristos #endif
34075fd0b74Schristos
34175fd0b74Schristos #ifdef ARM
34275fd0b74Schristos if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
34375fd0b74Schristos coff_data (abfd) ->flags = 0;
34475fd0b74Schristos #endif
34575fd0b74Schristos
346012573ebSchristos memcpy (pe->dos_message, internal_f->pe.dos_message,
347012573ebSchristos sizeof (pe->dos_message));
348012573ebSchristos
34975fd0b74Schristos return (void *) pe;
35075fd0b74Schristos }
35175fd0b74Schristos
352*e992f068Schristos static bool
pe_print_private_bfd_data(bfd * abfd,void * vfile)35375fd0b74Schristos pe_print_private_bfd_data (bfd *abfd, void * vfile)
35475fd0b74Schristos {
35575fd0b74Schristos FILE *file = (FILE *) vfile;
35675fd0b74Schristos
35775fd0b74Schristos if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile))
358*e992f068Schristos return false;
35975fd0b74Schristos
36075fd0b74Schristos if (pe_saved_coff_bfd_print_private_bfd_data == NULL)
361*e992f068Schristos return true;
36275fd0b74Schristos
36375fd0b74Schristos fputc ('\n', file);
36475fd0b74Schristos
36575fd0b74Schristos return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile);
36675fd0b74Schristos }
36775fd0b74Schristos
36875fd0b74Schristos /* Copy any private info we understand from the input bfd
36975fd0b74Schristos to the output bfd. */
37075fd0b74Schristos
371*e992f068Schristos static bool
pe_bfd_copy_private_bfd_data(bfd * ibfd,bfd * obfd)37275fd0b74Schristos pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
37375fd0b74Schristos {
37475fd0b74Schristos /* PR binutils/716: Copy the large address aware flag.
37575fd0b74Schristos XXX: Should we be copying other flags or other fields in the pe_data()
37675fd0b74Schristos structure ? */
37775fd0b74Schristos if (pe_data (obfd) != NULL
37875fd0b74Schristos && pe_data (ibfd) != NULL
37975fd0b74Schristos && pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE)
38075fd0b74Schristos pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
38175fd0b74Schristos
38275fd0b74Schristos if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
383*e992f068Schristos return false;
38475fd0b74Schristos
38575fd0b74Schristos if (pe_saved_coff_bfd_copy_private_bfd_data)
38675fd0b74Schristos return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
38775fd0b74Schristos
388*e992f068Schristos return true;
38975fd0b74Schristos }
39075fd0b74Schristos
39175fd0b74Schristos #define coff_bfd_copy_private_section_data \
39275fd0b74Schristos _bfd_XX_bfd_copy_private_section_data
39375fd0b74Schristos
39475fd0b74Schristos #define coff_get_symbol_info _bfd_XX_get_symbol_info
39575fd0b74Schristos
39675fd0b74Schristos #ifdef COFF_IMAGE_WITH_PE
39775fd0b74Schristos
39875fd0b74Schristos /* Code to handle Microsoft's Image Library Format.
39975fd0b74Schristos Also known as LINK6 format.
40075fd0b74Schristos Documentation about this format can be found at:
40175fd0b74Schristos
40275fd0b74Schristos http://msdn.microsoft.com/library/specs/pecoff_section8.htm */
40375fd0b74Schristos
40475fd0b74Schristos /* The following constants specify the sizes of the various data
40575fd0b74Schristos structures that we have to create in order to build a bfd describing
40675fd0b74Schristos an ILF object file. The final "+ 1" in the definitions of SIZEOF_IDATA6
40775fd0b74Schristos and SIZEOF_IDATA7 below is to allow for the possibility that we might
40875fd0b74Schristos need a padding byte in order to ensure 16 bit alignment for the section's
40975fd0b74Schristos contents.
41075fd0b74Schristos
41175fd0b74Schristos The value for SIZEOF_ILF_STRINGS is computed as follows:
41275fd0b74Schristos
41375fd0b74Schristos There will be NUM_ILF_SECTIONS section symbols. Allow 9 characters
41475fd0b74Schristos per symbol for their names (longest section name is .idata$x).
41575fd0b74Schristos
41675fd0b74Schristos There will be two symbols for the imported value, one the symbol name
41775fd0b74Schristos and one with _imp__ prefixed. Allowing for the terminating nul's this
41875fd0b74Schristos is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll).
41975fd0b74Schristos
42075fd0b74Schristos The strings in the string table must start STRING__SIZE_SIZE bytes into
42175fd0b74Schristos the table in order to for the string lookup code in coffgen/coffcode to
42275fd0b74Schristos work. */
42375fd0b74Schristos #define NUM_ILF_RELOCS 8
42475fd0b74Schristos #define NUM_ILF_SECTIONS 6
42575fd0b74Schristos #define NUM_ILF_SYMS (2 + NUM_ILF_SECTIONS)
42675fd0b74Schristos
42775fd0b74Schristos #define SIZEOF_ILF_SYMS (NUM_ILF_SYMS * sizeof (* vars.sym_cache))
42875fd0b74Schristos #define SIZEOF_ILF_SYM_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_table))
42975fd0b74Schristos #define SIZEOF_ILF_NATIVE_SYMS (NUM_ILF_SYMS * sizeof (* vars.native_syms))
43075fd0b74Schristos #define SIZEOF_ILF_SYM_PTR_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_ptr_table))
43175fd0b74Schristos #define SIZEOF_ILF_EXT_SYMS (NUM_ILF_SYMS * sizeof (* vars.esym_table))
43275fd0b74Schristos #define SIZEOF_ILF_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.reltab))
43375fd0b74Schristos #define SIZEOF_ILF_INT_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.int_reltab))
43475fd0b74Schristos #define SIZEOF_ILF_STRINGS (strlen (symbol_name) * 2 + 8 \
43575fd0b74Schristos + 21 + strlen (source_dll) \
43675fd0b74Schristos + NUM_ILF_SECTIONS * 9 \
43775fd0b74Schristos + STRING_SIZE_SIZE)
43875fd0b74Schristos #define SIZEOF_IDATA2 (5 * 4)
43975fd0b74Schristos
44075fd0b74Schristos /* For PEx64 idata4 & 5 have thumb size of 8 bytes. */
44175fd0b74Schristos #ifdef COFF_WITH_pex64
44275fd0b74Schristos #define SIZEOF_IDATA4 (2 * 4)
44375fd0b74Schristos #define SIZEOF_IDATA5 (2 * 4)
44475fd0b74Schristos #else
44575fd0b74Schristos #define SIZEOF_IDATA4 (1 * 4)
44675fd0b74Schristos #define SIZEOF_IDATA5 (1 * 4)
44775fd0b74Schristos #endif
44875fd0b74Schristos
44975fd0b74Schristos #define SIZEOF_IDATA6 (2 + strlen (symbol_name) + 1 + 1)
45075fd0b74Schristos #define SIZEOF_IDATA7 (strlen (source_dll) + 1 + 1)
45175fd0b74Schristos #define SIZEOF_ILF_SECTIONS (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
45275fd0b74Schristos
45375fd0b74Schristos #define ILF_DATA_SIZE \
45475fd0b74Schristos + SIZEOF_ILF_SYMS \
45575fd0b74Schristos + SIZEOF_ILF_SYM_TABLE \
45675fd0b74Schristos + SIZEOF_ILF_NATIVE_SYMS \
45775fd0b74Schristos + SIZEOF_ILF_SYM_PTR_TABLE \
45875fd0b74Schristos + SIZEOF_ILF_EXT_SYMS \
45975fd0b74Schristos + SIZEOF_ILF_RELOCS \
46075fd0b74Schristos + SIZEOF_ILF_INT_RELOCS \
46175fd0b74Schristos + SIZEOF_ILF_STRINGS \
46275fd0b74Schristos + SIZEOF_IDATA2 \
46375fd0b74Schristos + SIZEOF_IDATA4 \
46475fd0b74Schristos + SIZEOF_IDATA5 \
46575fd0b74Schristos + SIZEOF_IDATA6 \
46675fd0b74Schristos + SIZEOF_IDATA7 \
46775fd0b74Schristos + SIZEOF_ILF_SECTIONS \
46875fd0b74Schristos + MAX_TEXT_SECTION_SIZE
46975fd0b74Schristos
47075fd0b74Schristos /* Create an empty relocation against the given symbol. */
47175fd0b74Schristos
47275fd0b74Schristos static void
pe_ILF_make_a_symbol_reloc(pe_ILF_vars * vars,bfd_vma address,bfd_reloc_code_real_type reloc,struct bfd_symbol ** sym,unsigned int sym_index)47375fd0b74Schristos pe_ILF_make_a_symbol_reloc (pe_ILF_vars * vars,
47475fd0b74Schristos bfd_vma address,
47575fd0b74Schristos bfd_reloc_code_real_type reloc,
47675fd0b74Schristos struct bfd_symbol ** sym,
47775fd0b74Schristos unsigned int sym_index)
47875fd0b74Schristos {
47975fd0b74Schristos arelent * entry;
48075fd0b74Schristos struct internal_reloc * internal;
48175fd0b74Schristos
48275fd0b74Schristos entry = vars->reltab + vars->relcount;
48375fd0b74Schristos internal = vars->int_reltab + vars->relcount;
48475fd0b74Schristos
48575fd0b74Schristos entry->address = address;
48675fd0b74Schristos entry->addend = 0;
48775fd0b74Schristos entry->howto = bfd_reloc_type_lookup (vars->abfd, reloc);
48875fd0b74Schristos entry->sym_ptr_ptr = sym;
48975fd0b74Schristos
49075fd0b74Schristos internal->r_vaddr = address;
49175fd0b74Schristos internal->r_symndx = sym_index;
492*e992f068Schristos internal->r_type = entry->howto ? entry->howto->type : 0;
49375fd0b74Schristos
49475fd0b74Schristos vars->relcount ++;
49575fd0b74Schristos
49675fd0b74Schristos BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS);
49775fd0b74Schristos }
49875fd0b74Schristos
49975fd0b74Schristos /* Create an empty relocation against the given section. */
50075fd0b74Schristos
50175fd0b74Schristos static void
pe_ILF_make_a_reloc(pe_ILF_vars * vars,bfd_vma address,bfd_reloc_code_real_type reloc,asection_ptr sec)50275fd0b74Schristos pe_ILF_make_a_reloc (pe_ILF_vars * vars,
50375fd0b74Schristos bfd_vma address,
50475fd0b74Schristos bfd_reloc_code_real_type reloc,
50575fd0b74Schristos asection_ptr sec)
50675fd0b74Schristos {
50775fd0b74Schristos pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
50875fd0b74Schristos coff_section_data (vars->abfd, sec)->i);
50975fd0b74Schristos }
51075fd0b74Schristos
51175fd0b74Schristos /* Move the queued relocs into the given section. */
51275fd0b74Schristos
51375fd0b74Schristos static void
pe_ILF_save_relocs(pe_ILF_vars * vars,asection_ptr sec)51475fd0b74Schristos pe_ILF_save_relocs (pe_ILF_vars * vars,
51575fd0b74Schristos asection_ptr sec)
51675fd0b74Schristos {
51775fd0b74Schristos /* Make sure that there is somewhere to store the internal relocs. */
51875fd0b74Schristos if (coff_section_data (vars->abfd, sec) == NULL)
51975fd0b74Schristos /* We should probably return an error indication here. */
52075fd0b74Schristos abort ();
52175fd0b74Schristos
52275fd0b74Schristos coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab;
523*e992f068Schristos coff_section_data (vars->abfd, sec)->keep_relocs = true;
52475fd0b74Schristos
52575fd0b74Schristos sec->relocation = vars->reltab;
52675fd0b74Schristos sec->reloc_count = vars->relcount;
52775fd0b74Schristos sec->flags |= SEC_RELOC;
52875fd0b74Schristos
52975fd0b74Schristos vars->reltab += vars->relcount;
53075fd0b74Schristos vars->int_reltab += vars->relcount;
53175fd0b74Schristos vars->relcount = 0;
53275fd0b74Schristos
53375fd0b74Schristos BFD_ASSERT ((bfd_byte *) vars->int_reltab < (bfd_byte *) vars->string_table);
53475fd0b74Schristos }
53575fd0b74Schristos
53675fd0b74Schristos /* Create a global symbol and add it to the relevant tables. */
53775fd0b74Schristos
53875fd0b74Schristos static void
pe_ILF_make_a_symbol(pe_ILF_vars * vars,const char * prefix,const char * symbol_name,asection_ptr section,flagword extra_flags)53975fd0b74Schristos pe_ILF_make_a_symbol (pe_ILF_vars * vars,
54075fd0b74Schristos const char * prefix,
54175fd0b74Schristos const char * symbol_name,
54275fd0b74Schristos asection_ptr section,
54375fd0b74Schristos flagword extra_flags)
54475fd0b74Schristos {
54575fd0b74Schristos coff_symbol_type * sym;
54675fd0b74Schristos combined_entry_type * ent;
54775fd0b74Schristos SYMENT * esym;
54875fd0b74Schristos unsigned short sclass;
54975fd0b74Schristos
55075fd0b74Schristos if (extra_flags & BSF_LOCAL)
55175fd0b74Schristos sclass = C_STAT;
55275fd0b74Schristos else
55375fd0b74Schristos sclass = C_EXT;
55475fd0b74Schristos
55575fd0b74Schristos #ifdef THUMBPEMAGIC
55675fd0b74Schristos if (vars->magic == THUMBPEMAGIC)
55775fd0b74Schristos {
55875fd0b74Schristos if (extra_flags & BSF_FUNCTION)
55975fd0b74Schristos sclass = C_THUMBEXTFUNC;
56075fd0b74Schristos else if (extra_flags & BSF_LOCAL)
56175fd0b74Schristos sclass = C_THUMBSTAT;
56275fd0b74Schristos else
56375fd0b74Schristos sclass = C_THUMBEXT;
56475fd0b74Schristos }
56575fd0b74Schristos #endif
56675fd0b74Schristos
56775fd0b74Schristos BFD_ASSERT (vars->sym_index < NUM_ILF_SYMS);
56875fd0b74Schristos
56975fd0b74Schristos sym = vars->sym_ptr;
57075fd0b74Schristos ent = vars->native_ptr;
57175fd0b74Schristos esym = vars->esym_ptr;
57275fd0b74Schristos
57375fd0b74Schristos /* Copy the symbol's name into the string table. */
57475fd0b74Schristos sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
57575fd0b74Schristos
57675fd0b74Schristos if (section == NULL)
57775fd0b74Schristos section = bfd_und_section_ptr;
57875fd0b74Schristos
57975fd0b74Schristos /* Initialise the external symbol. */
58075fd0b74Schristos H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table,
58175fd0b74Schristos esym->e.e.e_offset);
58275fd0b74Schristos H_PUT_16 (vars->abfd, section->target_index, esym->e_scnum);
58375fd0b74Schristos esym->e_sclass[0] = sclass;
58475fd0b74Schristos
58575fd0b74Schristos /* The following initialisations are unnecessary - the memory is
58675fd0b74Schristos zero initialised. They are just kept here as reminders. */
58775fd0b74Schristos
58875fd0b74Schristos /* Initialise the internal symbol structure. */
58975fd0b74Schristos ent->u.syment.n_sclass = sclass;
59075fd0b74Schristos ent->u.syment.n_scnum = section->target_index;
591*e992f068Schristos ent->u.syment._n._n_n._n_offset = (uintptr_t) sym;
592*e992f068Schristos ent->is_sym = true;
59375fd0b74Schristos
59475fd0b74Schristos sym->symbol.the_bfd = vars->abfd;
59575fd0b74Schristos sym->symbol.name = vars->string_ptr;
59675fd0b74Schristos sym->symbol.flags = BSF_EXPORT | BSF_GLOBAL | extra_flags;
59775fd0b74Schristos sym->symbol.section = section;
59875fd0b74Schristos sym->native = ent;
59975fd0b74Schristos
60075fd0b74Schristos * vars->table_ptr = vars->sym_index;
60175fd0b74Schristos * vars->sym_ptr_ptr = sym;
60275fd0b74Schristos
60375fd0b74Schristos /* Adjust pointers for the next symbol. */
60475fd0b74Schristos vars->sym_index ++;
60575fd0b74Schristos vars->sym_ptr ++;
60675fd0b74Schristos vars->sym_ptr_ptr ++;
60775fd0b74Schristos vars->table_ptr ++;
60875fd0b74Schristos vars->native_ptr ++;
60975fd0b74Schristos vars->esym_ptr ++;
61075fd0b74Schristos vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
61175fd0b74Schristos
61275fd0b74Schristos BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
61375fd0b74Schristos }
61475fd0b74Schristos
61575fd0b74Schristos /* Create a section. */
61675fd0b74Schristos
61775fd0b74Schristos static asection_ptr
pe_ILF_make_a_section(pe_ILF_vars * vars,const char * name,unsigned int size,flagword extra_flags)61875fd0b74Schristos pe_ILF_make_a_section (pe_ILF_vars * vars,
61975fd0b74Schristos const char * name,
62075fd0b74Schristos unsigned int size,
62175fd0b74Schristos flagword extra_flags)
62275fd0b74Schristos {
62375fd0b74Schristos asection_ptr sec;
62475fd0b74Schristos flagword flags;
625*e992f068Schristos intptr_t alignment;
62675fd0b74Schristos
62775fd0b74Schristos sec = bfd_make_section_old_way (vars->abfd, name);
62875fd0b74Schristos if (sec == NULL)
62975fd0b74Schristos return NULL;
63075fd0b74Schristos
63175fd0b74Schristos flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY;
63275fd0b74Schristos
633012573ebSchristos bfd_set_section_flags (sec, flags | extra_flags);
63475fd0b74Schristos
635012573ebSchristos bfd_set_section_alignment (sec, 2);
63675fd0b74Schristos
63775fd0b74Schristos /* Check that we will not run out of space. */
63875fd0b74Schristos BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size);
63975fd0b74Schristos
64075fd0b74Schristos /* Set the section size and contents. The actual
64175fd0b74Schristos contents are filled in by our parent. */
642012573ebSchristos bfd_set_section_size (sec, (bfd_size_type) size);
64375fd0b74Schristos sec->contents = vars->data;
64475fd0b74Schristos sec->target_index = vars->sec_index ++;
64575fd0b74Schristos
64675fd0b74Schristos /* Advance data pointer in the vars structure. */
64775fd0b74Schristos vars->data += size;
64875fd0b74Schristos
64975fd0b74Schristos /* Skip the padding byte if it was not needed.
65075fd0b74Schristos The logic here is that if the string length is odd,
65175fd0b74Schristos then the entire string length, including the null byte,
65275fd0b74Schristos is even and so the extra, padding byte, is not needed. */
65375fd0b74Schristos if (size & 1)
65475fd0b74Schristos vars->data --;
65575fd0b74Schristos
65675fd0b74Schristos /* PR 18758: See note in pe_ILF_buid_a_bfd. We must make sure that we
657*e992f068Schristos preserve host alignment requirements. The BFD_ASSERTs in this
658*e992f068Schristos functions will warn us if we run out of room, but we should
659*e992f068Schristos already have enough padding built in to ILF_DATA_SIZE. */
660*e992f068Schristos #if GCC_VERSION >= 3000
661*e992f068Schristos alignment = __alignof__ (struct coff_section_tdata);
662*e992f068Schristos #else
663*e992f068Schristos alignment = 8;
66475fd0b74Schristos #endif
665*e992f068Schristos vars->data
666*e992f068Schristos = (bfd_byte *) (((intptr_t) vars->data + alignment - 1) & -alignment);
667*e992f068Schristos
66875fd0b74Schristos /* Create a coff_section_tdata structure for our use. */
66975fd0b74Schristos sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
67075fd0b74Schristos vars->data += sizeof (struct coff_section_tdata);
67175fd0b74Schristos
67275fd0b74Schristos BFD_ASSERT (vars->data <= vars->bim->buffer + vars->bim->size);
67375fd0b74Schristos
67475fd0b74Schristos /* Create a symbol to refer to this section. */
67575fd0b74Schristos pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
67675fd0b74Schristos
67775fd0b74Schristos /* Cache the index to the symbol in the coff_section_data structure. */
67875fd0b74Schristos coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
67975fd0b74Schristos
68075fd0b74Schristos return sec;
68175fd0b74Schristos }
68275fd0b74Schristos
68375fd0b74Schristos /* This structure contains the code that goes into the .text section
68475fd0b74Schristos in order to perform a jump into the DLL lookup table. The entries
68575fd0b74Schristos in the table are index by the magic number used to represent the
68675fd0b74Schristos machine type in the PE file. The contents of the data[] arrays in
68775fd0b74Schristos these entries are stolen from the jtab[] arrays in ld/pe-dll.c.
68875fd0b74Schristos The SIZE field says how many bytes in the DATA array are actually
68975fd0b74Schristos used. The OFFSET field says where in the data array the address
69075fd0b74Schristos of the .idata$5 section should be placed. */
69175fd0b74Schristos #define MAX_TEXT_SECTION_SIZE 32
69275fd0b74Schristos
69375fd0b74Schristos typedef struct
69475fd0b74Schristos {
69575fd0b74Schristos unsigned short magic;
69675fd0b74Schristos unsigned char data[MAX_TEXT_SECTION_SIZE];
69775fd0b74Schristos unsigned int size;
69875fd0b74Schristos unsigned int offset;
69975fd0b74Schristos }
70075fd0b74Schristos jump_table;
70175fd0b74Schristos
702*e992f068Schristos static const jump_table jtab[] =
70375fd0b74Schristos {
70475fd0b74Schristos #ifdef I386MAGIC
70575fd0b74Schristos { I386MAGIC,
70675fd0b74Schristos { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
70775fd0b74Schristos 8, 2
70875fd0b74Schristos },
70975fd0b74Schristos #endif
71075fd0b74Schristos
71175fd0b74Schristos #ifdef AMD64MAGIC
71275fd0b74Schristos { AMD64MAGIC,
71375fd0b74Schristos { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
71475fd0b74Schristos 8, 2
71575fd0b74Schristos },
71675fd0b74Schristos #endif
71775fd0b74Schristos
71875fd0b74Schristos #ifdef MC68MAGIC
71975fd0b74Schristos { MC68MAGIC,
72075fd0b74Schristos { /* XXX fill me in */ },
72175fd0b74Schristos 0, 0
72275fd0b74Schristos },
72375fd0b74Schristos #endif
72475fd0b74Schristos
72575fd0b74Schristos #ifdef MIPS_ARCH_MAGIC_WINCE
72675fd0b74Schristos { MIPS_ARCH_MAGIC_WINCE,
72775fd0b74Schristos { 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
72875fd0b74Schristos 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 },
72975fd0b74Schristos 16, 0
73075fd0b74Schristos },
73175fd0b74Schristos #endif
73275fd0b74Schristos
73375fd0b74Schristos #ifdef SH_ARCH_MAGIC_WINCE
73475fd0b74Schristos { SH_ARCH_MAGIC_WINCE,
73575fd0b74Schristos { 0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40,
73675fd0b74Schristos 0x09, 0x00, 0x00, 0x00, 0x00, 0x00 },
73775fd0b74Schristos 12, 8
73875fd0b74Schristos },
73975fd0b74Schristos #endif
74075fd0b74Schristos
741*e992f068Schristos #ifdef AARCH64MAGIC
742*e992f068Schristos /* We don't currently support jumping to DLLs, so if
743*e992f068Schristos someone does try emit a runtime trap. Through UDF #0. */
744*e992f068Schristos { AARCH64MAGIC,
745*e992f068Schristos { 0x00, 0x00, 0x00, 0x00 },
746*e992f068Schristos 4, 0
747*e992f068Schristos },
748*e992f068Schristos
749*e992f068Schristos #endif
750*e992f068Schristos
75175fd0b74Schristos #ifdef ARMPEMAGIC
75275fd0b74Schristos { ARMPEMAGIC,
75375fd0b74Schristos { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
75475fd0b74Schristos 0x9c, 0xe5, 0x00, 0x00, 0x00, 0x00},
75575fd0b74Schristos 12, 8
75675fd0b74Schristos },
75775fd0b74Schristos #endif
75875fd0b74Schristos
75975fd0b74Schristos #ifdef THUMBPEMAGIC
76075fd0b74Schristos { THUMBPEMAGIC,
76175fd0b74Schristos { 0x40, 0xb4, 0x02, 0x4e, 0x36, 0x68, 0xb4, 0x46,
76275fd0b74Schristos 0x40, 0xbc, 0x60, 0x47, 0x00, 0x00, 0x00, 0x00 },
76375fd0b74Schristos 16, 12
76475fd0b74Schristos },
76575fd0b74Schristos #endif
76675fd0b74Schristos { 0, { 0 }, 0, 0 }
76775fd0b74Schristos };
76875fd0b74Schristos
76975fd0b74Schristos #ifndef NUM_ENTRIES
77075fd0b74Schristos #define NUM_ENTRIES(a) (sizeof (a) / sizeof (a)[0])
77175fd0b74Schristos #endif
77275fd0b74Schristos
77375fd0b74Schristos /* Build a full BFD from the information supplied in a ILF object. */
77475fd0b74Schristos
775*e992f068Schristos static bool
pe_ILF_build_a_bfd(bfd * abfd,unsigned int magic,char * symbol_name,char * source_dll,unsigned int ordinal,unsigned int types)77675fd0b74Schristos pe_ILF_build_a_bfd (bfd * abfd,
77775fd0b74Schristos unsigned int magic,
77875fd0b74Schristos char * symbol_name,
77975fd0b74Schristos char * source_dll,
78075fd0b74Schristos unsigned int ordinal,
78175fd0b74Schristos unsigned int types)
78275fd0b74Schristos {
78375fd0b74Schristos bfd_byte * ptr;
78475fd0b74Schristos pe_ILF_vars vars;
78575fd0b74Schristos struct internal_filehdr internal_f;
78675fd0b74Schristos unsigned int import_type;
78775fd0b74Schristos unsigned int import_name_type;
78875fd0b74Schristos asection_ptr id4, id5, id6 = NULL, text = NULL;
78975fd0b74Schristos coff_symbol_type ** imp_sym;
79075fd0b74Schristos unsigned int imp_index;
791*e992f068Schristos intptr_t alignment;
79275fd0b74Schristos
79375fd0b74Schristos /* Decode and verify the types field of the ILF structure. */
79475fd0b74Schristos import_type = types & 0x3;
79575fd0b74Schristos import_name_type = (types & 0x1c) >> 2;
79675fd0b74Schristos
79775fd0b74Schristos switch (import_type)
79875fd0b74Schristos {
79975fd0b74Schristos case IMPORT_CODE:
80075fd0b74Schristos case IMPORT_DATA:
80175fd0b74Schristos break;
80275fd0b74Schristos
80375fd0b74Schristos case IMPORT_CONST:
80475fd0b74Schristos /* XXX code yet to be written. */
805ede78133Schristos /* xgettext:c-format */
806ede78133Schristos _bfd_error_handler (_("%pB: unhandled import type; %x"),
80775fd0b74Schristos abfd, import_type);
808*e992f068Schristos return false;
80975fd0b74Schristos
81075fd0b74Schristos default:
811ede78133Schristos /* xgettext:c-format */
812ede78133Schristos _bfd_error_handler (_("%pB: unrecognized import type; %x"),
81375fd0b74Schristos abfd, import_type);
814*e992f068Schristos return false;
81575fd0b74Schristos }
81675fd0b74Schristos
81775fd0b74Schristos switch (import_name_type)
81875fd0b74Schristos {
81975fd0b74Schristos case IMPORT_ORDINAL:
82075fd0b74Schristos case IMPORT_NAME:
82175fd0b74Schristos case IMPORT_NAME_NOPREFIX:
82275fd0b74Schristos case IMPORT_NAME_UNDECORATE:
82375fd0b74Schristos break;
82475fd0b74Schristos
82575fd0b74Schristos default:
826ede78133Schristos /* xgettext:c-format */
827ede78133Schristos _bfd_error_handler (_("%pB: unrecognized import name type; %x"),
82875fd0b74Schristos abfd, import_name_type);
829*e992f068Schristos return false;
83075fd0b74Schristos }
83175fd0b74Schristos
83275fd0b74Schristos /* Initialise local variables.
83375fd0b74Schristos
83475fd0b74Schristos Note these are kept in a structure rather than being
83575fd0b74Schristos declared as statics since bfd frowns on global variables.
83675fd0b74Schristos
83775fd0b74Schristos We are going to construct the contents of the BFD in memory,
83875fd0b74Schristos so allocate all the space that we will need right now. */
83975fd0b74Schristos vars.bim
84075fd0b74Schristos = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
84175fd0b74Schristos if (vars.bim == NULL)
842*e992f068Schristos return false;
84375fd0b74Schristos
84475fd0b74Schristos ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
84575fd0b74Schristos vars.bim->buffer = ptr;
84675fd0b74Schristos vars.bim->size = ILF_DATA_SIZE;
84775fd0b74Schristos if (ptr == NULL)
84875fd0b74Schristos goto error_return;
84975fd0b74Schristos
85075fd0b74Schristos /* Initialise the pointers to regions of the memory and the
85175fd0b74Schristos other contents of the pe_ILF_vars structure as well. */
85275fd0b74Schristos vars.sym_cache = (coff_symbol_type *) ptr;
85375fd0b74Schristos vars.sym_ptr = (coff_symbol_type *) ptr;
85475fd0b74Schristos vars.sym_index = 0;
85575fd0b74Schristos ptr += SIZEOF_ILF_SYMS;
85675fd0b74Schristos
85775fd0b74Schristos vars.sym_table = (unsigned int *) ptr;
85875fd0b74Schristos vars.table_ptr = (unsigned int *) ptr;
85975fd0b74Schristos ptr += SIZEOF_ILF_SYM_TABLE;
86075fd0b74Schristos
86175fd0b74Schristos vars.native_syms = (combined_entry_type *) ptr;
86275fd0b74Schristos vars.native_ptr = (combined_entry_type *) ptr;
86375fd0b74Schristos ptr += SIZEOF_ILF_NATIVE_SYMS;
86475fd0b74Schristos
86575fd0b74Schristos vars.sym_ptr_table = (coff_symbol_type **) ptr;
86675fd0b74Schristos vars.sym_ptr_ptr = (coff_symbol_type **) ptr;
86775fd0b74Schristos ptr += SIZEOF_ILF_SYM_PTR_TABLE;
86875fd0b74Schristos
86975fd0b74Schristos vars.esym_table = (SYMENT *) ptr;
87075fd0b74Schristos vars.esym_ptr = (SYMENT *) ptr;
87175fd0b74Schristos ptr += SIZEOF_ILF_EXT_SYMS;
87275fd0b74Schristos
87375fd0b74Schristos vars.reltab = (arelent *) ptr;
87475fd0b74Schristos vars.relcount = 0;
87575fd0b74Schristos ptr += SIZEOF_ILF_RELOCS;
87675fd0b74Schristos
87775fd0b74Schristos vars.int_reltab = (struct internal_reloc *) ptr;
87875fd0b74Schristos ptr += SIZEOF_ILF_INT_RELOCS;
87975fd0b74Schristos
88075fd0b74Schristos vars.string_table = (char *) ptr;
88175fd0b74Schristos vars.string_ptr = (char *) ptr + STRING_SIZE_SIZE;
88275fd0b74Schristos ptr += SIZEOF_ILF_STRINGS;
88375fd0b74Schristos vars.end_string_ptr = (char *) ptr;
88475fd0b74Schristos
88575fd0b74Schristos /* The remaining space in bim->buffer is used
88675fd0b74Schristos by the pe_ILF_make_a_section() function. */
887*e992f068Schristos
88875fd0b74Schristos /* PR 18758: Make sure that the data area is sufficiently aligned for
889*e992f068Schristos struct coff_section_tdata. __alignof__ is a gcc extension, hence
890*e992f068Schristos the test of GCC_VERSION. For other compilers we assume 8 byte
891*e992f068Schristos alignment. */
892*e992f068Schristos #if GCC_VERSION >= 3000
893*e992f068Schristos alignment = __alignof__ (struct coff_section_tdata);
894*e992f068Schristos #else
895*e992f068Schristos alignment = 8;
89675fd0b74Schristos #endif
897*e992f068Schristos ptr = (bfd_byte *) (((intptr_t) ptr + alignment - 1) & -alignment);
89875fd0b74Schristos
89975fd0b74Schristos vars.data = ptr;
90075fd0b74Schristos vars.abfd = abfd;
90175fd0b74Schristos vars.sec_index = 0;
90275fd0b74Schristos vars.magic = magic;
90375fd0b74Schristos
90475fd0b74Schristos /* Create the initial .idata$<n> sections:
90575fd0b74Schristos [.idata$2: Import Directory Table -- not needed]
90675fd0b74Schristos .idata$4: Import Lookup Table
90775fd0b74Schristos .idata$5: Import Address Table
90875fd0b74Schristos
90975fd0b74Schristos Note we do not create a .idata$3 section as this is
91075fd0b74Schristos created for us by the linker script. */
91175fd0b74Schristos id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
91275fd0b74Schristos id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
91375fd0b74Schristos if (id4 == NULL || id5 == NULL)
91475fd0b74Schristos goto error_return;
91575fd0b74Schristos
91675fd0b74Schristos /* Fill in the contents of these sections. */
91775fd0b74Schristos if (import_name_type == IMPORT_ORDINAL)
91875fd0b74Schristos {
91975fd0b74Schristos if (ordinal == 0)
920ede78133Schristos /* See PR 20907 for a reproducer. */
921ede78133Schristos goto error_return;
92275fd0b74Schristos
923*e992f068Schristos #if defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64)
92475fd0b74Schristos ((unsigned int *) id4->contents)[0] = ordinal;
92575fd0b74Schristos ((unsigned int *) id4->contents)[1] = 0x80000000;
92675fd0b74Schristos ((unsigned int *) id5->contents)[0] = ordinal;
92775fd0b74Schristos ((unsigned int *) id5->contents)[1] = 0x80000000;
92875fd0b74Schristos #else
92975fd0b74Schristos * (unsigned int *) id4->contents = ordinal | 0x80000000;
93075fd0b74Schristos * (unsigned int *) id5->contents = ordinal | 0x80000000;
93175fd0b74Schristos #endif
93275fd0b74Schristos }
93375fd0b74Schristos else
93475fd0b74Schristos {
93575fd0b74Schristos char * symbol;
93675fd0b74Schristos unsigned int len;
93775fd0b74Schristos
93875fd0b74Schristos /* Create .idata$6 - the Hint Name Table. */
93975fd0b74Schristos id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0);
94075fd0b74Schristos if (id6 == NULL)
94175fd0b74Schristos goto error_return;
94275fd0b74Schristos
94375fd0b74Schristos /* If necessary, trim the import symbol name. */
94475fd0b74Schristos symbol = symbol_name;
94575fd0b74Schristos
94675fd0b74Schristos /* As used by MS compiler, '_', '@', and '?' are alternative
94775fd0b74Schristos forms of USER_LABEL_PREFIX, with '?' for c++ mangled names,
94875fd0b74Schristos '@' used for fastcall (in C), '_' everywhere else. Only one
94975fd0b74Schristos of these is used for a symbol. We strip this leading char for
95075fd0b74Schristos IMPORT_NAME_NOPREFIX and IMPORT_NAME_UNDECORATE as per the
95175fd0b74Schristos PE COFF 6.0 spec (section 8.3, Import Name Type). */
95275fd0b74Schristos
95375fd0b74Schristos if (import_name_type != IMPORT_NAME)
95475fd0b74Schristos {
95575fd0b74Schristos char c = symbol[0];
95675fd0b74Schristos
95775fd0b74Schristos /* Check that we don't remove for targets with empty
95875fd0b74Schristos USER_LABEL_PREFIX the leading underscore. */
95975fd0b74Schristos if ((c == '_' && abfd->xvec->symbol_leading_char != 0)
96075fd0b74Schristos || c == '@' || c == '?')
96175fd0b74Schristos symbol++;
96275fd0b74Schristos }
96375fd0b74Schristos
96475fd0b74Schristos len = strlen (symbol);
96575fd0b74Schristos if (import_name_type == IMPORT_NAME_UNDECORATE)
96675fd0b74Schristos {
96775fd0b74Schristos /* Truncate at the first '@'. */
96875fd0b74Schristos char *at = strchr (symbol, '@');
96975fd0b74Schristos
97075fd0b74Schristos if (at != NULL)
97175fd0b74Schristos len = at - symbol;
97275fd0b74Schristos }
97375fd0b74Schristos
97475fd0b74Schristos id6->contents[0] = ordinal & 0xff;
97575fd0b74Schristos id6->contents[1] = ordinal >> 8;
97675fd0b74Schristos
97775fd0b74Schristos memcpy ((char *) id6->contents + 2, symbol, len);
97875fd0b74Schristos id6->contents[len + 2] = '\0';
97975fd0b74Schristos }
98075fd0b74Schristos
98175fd0b74Schristos if (import_name_type != IMPORT_ORDINAL)
98275fd0b74Schristos {
98375fd0b74Schristos pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
98475fd0b74Schristos pe_ILF_save_relocs (&vars, id4);
98575fd0b74Schristos
98675fd0b74Schristos pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
98775fd0b74Schristos pe_ILF_save_relocs (&vars, id5);
98875fd0b74Schristos }
98975fd0b74Schristos
99075fd0b74Schristos /* Create an import symbol. */
99175fd0b74Schristos pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0);
99275fd0b74Schristos imp_sym = vars.sym_ptr_ptr - 1;
99375fd0b74Schristos imp_index = vars.sym_index - 1;
99475fd0b74Schristos
99575fd0b74Schristos /* Create extra sections depending upon the type of import we are dealing with. */
99675fd0b74Schristos switch (import_type)
99775fd0b74Schristos {
99875fd0b74Schristos int i;
99975fd0b74Schristos
100075fd0b74Schristos case IMPORT_CODE:
100175fd0b74Schristos /* CODE functions are special, in that they get a trampoline that
100275fd0b74Schristos jumps to the main import symbol. Create a .text section to hold it.
100375fd0b74Schristos First we need to look up its contents in the jump table. */
100475fd0b74Schristos for (i = NUM_ENTRIES (jtab); i--;)
100575fd0b74Schristos {
100675fd0b74Schristos if (jtab[i].size == 0)
100775fd0b74Schristos continue;
100875fd0b74Schristos if (jtab[i].magic == magic)
100975fd0b74Schristos break;
101075fd0b74Schristos }
101175fd0b74Schristos /* If we did not find a matching entry something is wrong. */
101275fd0b74Schristos if (i < 0)
101375fd0b74Schristos abort ();
101475fd0b74Schristos
101575fd0b74Schristos /* Create the .text section. */
101675fd0b74Schristos text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE);
101775fd0b74Schristos if (text == NULL)
101875fd0b74Schristos goto error_return;
101975fd0b74Schristos
102075fd0b74Schristos /* Copy in the jump code. */
102175fd0b74Schristos memcpy (text->contents, jtab[i].data, jtab[i].size);
102275fd0b74Schristos
102375fd0b74Schristos /* Create a reloc for the data in the text section. */
102475fd0b74Schristos #ifdef MIPS_ARCH_MAGIC_WINCE
102575fd0b74Schristos if (magic == MIPS_ARCH_MAGIC_WINCE)
102675fd0b74Schristos {
102775fd0b74Schristos pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S,
102875fd0b74Schristos (struct bfd_symbol **) imp_sym,
102975fd0b74Schristos imp_index);
103075fd0b74Schristos pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text);
103175fd0b74Schristos pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16,
103275fd0b74Schristos (struct bfd_symbol **) imp_sym,
103375fd0b74Schristos imp_index);
103475fd0b74Schristos }
103575fd0b74Schristos else
103675fd0b74Schristos #endif
103775fd0b74Schristos #ifdef AMD64MAGIC
103875fd0b74Schristos if (magic == AMD64MAGIC)
103975fd0b74Schristos {
104075fd0b74Schristos pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
104175fd0b74Schristos BFD_RELOC_32_PCREL, (asymbol **) imp_sym,
104275fd0b74Schristos imp_index);
104375fd0b74Schristos }
104475fd0b74Schristos else
104575fd0b74Schristos #endif
104675fd0b74Schristos pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
104775fd0b74Schristos BFD_RELOC_32, (asymbol **) imp_sym,
104875fd0b74Schristos imp_index);
104975fd0b74Schristos
105075fd0b74Schristos pe_ILF_save_relocs (& vars, text);
105175fd0b74Schristos break;
105275fd0b74Schristos
105375fd0b74Schristos case IMPORT_DATA:
105475fd0b74Schristos break;
105575fd0b74Schristos
105675fd0b74Schristos default:
105775fd0b74Schristos /* XXX code not yet written. */
105875fd0b74Schristos abort ();
105975fd0b74Schristos }
106075fd0b74Schristos
106175fd0b74Schristos /* Initialise the bfd. */
106275fd0b74Schristos memset (& internal_f, 0, sizeof (internal_f));
106375fd0b74Schristos
106475fd0b74Schristos internal_f.f_magic = magic;
106575fd0b74Schristos internal_f.f_symptr = 0;
106675fd0b74Schristos internal_f.f_nsyms = 0;
106775fd0b74Schristos internal_f.f_flags = F_AR32WR | F_LNNO; /* XXX is this correct ? */
106875fd0b74Schristos
106975fd0b74Schristos if ( ! bfd_set_start_address (abfd, (bfd_vma) 0)
107075fd0b74Schristos || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f))
107175fd0b74Schristos goto error_return;
107275fd0b74Schristos
107375fd0b74Schristos if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
107475fd0b74Schristos goto error_return;
107575fd0b74Schristos
107675fd0b74Schristos coff_data (abfd)->pe = 1;
107775fd0b74Schristos #ifdef THUMBPEMAGIC
107875fd0b74Schristos if (vars.magic == THUMBPEMAGIC)
107975fd0b74Schristos /* Stop some linker warnings about thumb code not supporting interworking. */
108075fd0b74Schristos coff_data (abfd)->flags |= F_INTERWORK | F_INTERWORK_SET;
108175fd0b74Schristos #endif
108275fd0b74Schristos
108375fd0b74Schristos /* Switch from file contents to memory contents. */
108475fd0b74Schristos bfd_cache_close (abfd);
108575fd0b74Schristos
108675fd0b74Schristos abfd->iostream = (void *) vars.bim;
108775fd0b74Schristos abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */;
108875fd0b74Schristos abfd->iovec = &_bfd_memory_iovec;
108975fd0b74Schristos abfd->where = 0;
109075fd0b74Schristos abfd->origin = 0;
109175fd0b74Schristos obj_sym_filepos (abfd) = 0;
109275fd0b74Schristos
109375fd0b74Schristos /* Now create a symbol describing the imported value. */
109475fd0b74Schristos switch (import_type)
109575fd0b74Schristos {
109675fd0b74Schristos case IMPORT_CODE:
109775fd0b74Schristos pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
109875fd0b74Schristos BSF_NOT_AT_END | BSF_FUNCTION);
109975fd0b74Schristos
110075fd0b74Schristos break;
110175fd0b74Schristos
110275fd0b74Schristos case IMPORT_DATA:
110375fd0b74Schristos /* Nothing to do here. */
110475fd0b74Schristos break;
110575fd0b74Schristos
110675fd0b74Schristos default:
110775fd0b74Schristos /* XXX code not yet written. */
110875fd0b74Schristos abort ();
110975fd0b74Schristos }
111075fd0b74Schristos
111175fd0b74Schristos /* Create an import symbol for the DLL, without the .dll suffix. */
111275fd0b74Schristos ptr = (bfd_byte *) strrchr (source_dll, '.');
111375fd0b74Schristos if (ptr)
111475fd0b74Schristos * ptr = 0;
111575fd0b74Schristos pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
111675fd0b74Schristos if (ptr)
111775fd0b74Schristos * ptr = '.';
111875fd0b74Schristos
111975fd0b74Schristos /* Point the bfd at the symbol table. */
112075fd0b74Schristos obj_symbols (abfd) = vars.sym_cache;
1121012573ebSchristos abfd->symcount = vars.sym_index;
112275fd0b74Schristos
112375fd0b74Schristos obj_raw_syments (abfd) = vars.native_syms;
112475fd0b74Schristos obj_raw_syment_count (abfd) = vars.sym_index;
112575fd0b74Schristos
112675fd0b74Schristos obj_coff_external_syms (abfd) = (void *) vars.esym_table;
1127*e992f068Schristos obj_coff_keep_syms (abfd) = true;
112875fd0b74Schristos
112975fd0b74Schristos obj_convert (abfd) = vars.sym_table;
113075fd0b74Schristos obj_conv_table_size (abfd) = vars.sym_index;
113175fd0b74Schristos
113275fd0b74Schristos obj_coff_strings (abfd) = vars.string_table;
1133*e992f068Schristos obj_coff_keep_strings (abfd) = true;
113475fd0b74Schristos
113575fd0b74Schristos abfd->flags |= HAS_SYMS;
113675fd0b74Schristos
1137*e992f068Schristos return true;
113875fd0b74Schristos
113975fd0b74Schristos error_return:
114075fd0b74Schristos free (vars.bim->buffer);
114175fd0b74Schristos free (vars.bim);
1142*e992f068Schristos return false;
114375fd0b74Schristos }
114475fd0b74Schristos
114575fd0b74Schristos /* We have detected a Image Library Format archive element.
114675fd0b74Schristos Decode the element and return the appropriate target. */
114775fd0b74Schristos
1148*e992f068Schristos static bfd_cleanup
pe_ILF_object_p(bfd * abfd)114975fd0b74Schristos pe_ILF_object_p (bfd * abfd)
115075fd0b74Schristos {
115175fd0b74Schristos bfd_byte buffer[14];
115275fd0b74Schristos bfd_byte * ptr;
115375fd0b74Schristos char * symbol_name;
115475fd0b74Schristos char * source_dll;
115575fd0b74Schristos unsigned int machine;
115675fd0b74Schristos bfd_size_type size;
115775fd0b74Schristos unsigned int ordinal;
115875fd0b74Schristos unsigned int types;
115975fd0b74Schristos unsigned int magic;
116075fd0b74Schristos
116175fd0b74Schristos /* Upon entry the first six bytes of the ILF header have
116275fd0b74Schristos already been read. Now read the rest of the header. */
116375fd0b74Schristos if (bfd_bread (buffer, (bfd_size_type) 14, abfd) != 14)
116475fd0b74Schristos return NULL;
116575fd0b74Schristos
116675fd0b74Schristos ptr = buffer;
116775fd0b74Schristos
116875fd0b74Schristos machine = H_GET_16 (abfd, ptr);
116975fd0b74Schristos ptr += 2;
117075fd0b74Schristos
117175fd0b74Schristos /* Check that the machine type is recognised. */
117275fd0b74Schristos magic = 0;
117375fd0b74Schristos
117475fd0b74Schristos switch (machine)
117575fd0b74Schristos {
117675fd0b74Schristos case IMAGE_FILE_MACHINE_UNKNOWN:
117775fd0b74Schristos case IMAGE_FILE_MACHINE_ALPHA:
117875fd0b74Schristos case IMAGE_FILE_MACHINE_ALPHA64:
117975fd0b74Schristos case IMAGE_FILE_MACHINE_IA64:
118075fd0b74Schristos break;
118175fd0b74Schristos
118275fd0b74Schristos case IMAGE_FILE_MACHINE_I386:
118375fd0b74Schristos #ifdef I386MAGIC
118475fd0b74Schristos magic = I386MAGIC;
118575fd0b74Schristos #endif
118675fd0b74Schristos break;
118775fd0b74Schristos
118875fd0b74Schristos case IMAGE_FILE_MACHINE_AMD64:
118975fd0b74Schristos #ifdef AMD64MAGIC
119075fd0b74Schristos magic = AMD64MAGIC;
119175fd0b74Schristos #endif
119275fd0b74Schristos break;
119375fd0b74Schristos
119475fd0b74Schristos case IMAGE_FILE_MACHINE_R3000:
119575fd0b74Schristos case IMAGE_FILE_MACHINE_R4000:
119675fd0b74Schristos case IMAGE_FILE_MACHINE_R10000:
119775fd0b74Schristos
119875fd0b74Schristos case IMAGE_FILE_MACHINE_MIPS16:
119975fd0b74Schristos case IMAGE_FILE_MACHINE_MIPSFPU:
120075fd0b74Schristos case IMAGE_FILE_MACHINE_MIPSFPU16:
120175fd0b74Schristos #ifdef MIPS_ARCH_MAGIC_WINCE
120275fd0b74Schristos magic = MIPS_ARCH_MAGIC_WINCE;
120375fd0b74Schristos #endif
120475fd0b74Schristos break;
120575fd0b74Schristos
120675fd0b74Schristos case IMAGE_FILE_MACHINE_SH3:
120775fd0b74Schristos case IMAGE_FILE_MACHINE_SH4:
120875fd0b74Schristos #ifdef SH_ARCH_MAGIC_WINCE
120975fd0b74Schristos magic = SH_ARCH_MAGIC_WINCE;
121075fd0b74Schristos #endif
121175fd0b74Schristos break;
121275fd0b74Schristos
121375fd0b74Schristos case IMAGE_FILE_MACHINE_ARM:
121475fd0b74Schristos #ifdef ARMPEMAGIC
121575fd0b74Schristos magic = ARMPEMAGIC;
121675fd0b74Schristos #endif
121775fd0b74Schristos break;
121875fd0b74Schristos
1219*e992f068Schristos case IMAGE_FILE_MACHINE_ARM64:
1220*e992f068Schristos #ifdef AARCH64MAGIC
1221*e992f068Schristos magic = AARCH64MAGIC;
1222*e992f068Schristos #endif
1223*e992f068Schristos break;
1224*e992f068Schristos
122575fd0b74Schristos case IMAGE_FILE_MACHINE_THUMB:
122675fd0b74Schristos #ifdef THUMBPEMAGIC
122775fd0b74Schristos {
122875fd0b74Schristos extern const bfd_target TARGET_LITTLE_SYM;
122975fd0b74Schristos
123075fd0b74Schristos if (abfd->xvec == & TARGET_LITTLE_SYM)
123175fd0b74Schristos magic = THUMBPEMAGIC;
123275fd0b74Schristos }
123375fd0b74Schristos #endif
123475fd0b74Schristos break;
123575fd0b74Schristos
123675fd0b74Schristos case IMAGE_FILE_MACHINE_POWERPC:
123775fd0b74Schristos /* We no longer support PowerPC. */
123875fd0b74Schristos default:
123975fd0b74Schristos _bfd_error_handler
1240ede78133Schristos /* xgettext:c-format */
1241ede78133Schristos (_("%pB: unrecognised machine type (0x%x)"
124275fd0b74Schristos " in Import Library Format archive"),
124375fd0b74Schristos abfd, machine);
124475fd0b74Schristos bfd_set_error (bfd_error_malformed_archive);
124575fd0b74Schristos
124675fd0b74Schristos return NULL;
124775fd0b74Schristos break;
124875fd0b74Schristos }
124975fd0b74Schristos
125075fd0b74Schristos if (magic == 0)
125175fd0b74Schristos {
125275fd0b74Schristos _bfd_error_handler
1253ede78133Schristos /* xgettext:c-format */
1254ede78133Schristos (_("%pB: recognised but unhandled machine type (0x%x)"
125575fd0b74Schristos " in Import Library Format archive"),
125675fd0b74Schristos abfd, machine);
125775fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
125875fd0b74Schristos
125975fd0b74Schristos return NULL;
126075fd0b74Schristos }
126175fd0b74Schristos
126275fd0b74Schristos /* We do not bother to check the date.
126375fd0b74Schristos date = H_GET_32 (abfd, ptr); */
126475fd0b74Schristos ptr += 4;
126575fd0b74Schristos
126675fd0b74Schristos size = H_GET_32 (abfd, ptr);
126775fd0b74Schristos ptr += 4;
126875fd0b74Schristos
126975fd0b74Schristos if (size == 0)
127075fd0b74Schristos {
127175fd0b74Schristos _bfd_error_handler
1272ede78133Schristos (_("%pB: size field is zero in Import Library Format header"), abfd);
127375fd0b74Schristos bfd_set_error (bfd_error_malformed_archive);
127475fd0b74Schristos
127575fd0b74Schristos return NULL;
127675fd0b74Schristos }
127775fd0b74Schristos
127875fd0b74Schristos ordinal = H_GET_16 (abfd, ptr);
127975fd0b74Schristos ptr += 2;
128075fd0b74Schristos
128175fd0b74Schristos types = H_GET_16 (abfd, ptr);
128275fd0b74Schristos /* ptr += 2; */
128375fd0b74Schristos
128475fd0b74Schristos /* Now read in the two strings that follow. */
1285*e992f068Schristos ptr = (bfd_byte *) _bfd_alloc_and_read (abfd, size, size);
128675fd0b74Schristos if (ptr == NULL)
128775fd0b74Schristos return NULL;
128875fd0b74Schristos
128975fd0b74Schristos symbol_name = (char *) ptr;
1290ede78133Schristos /* See PR 20905 for an example of where the strnlen is necessary. */
1291ede78133Schristos source_dll = symbol_name + strnlen (symbol_name, size - 1) + 1;
129275fd0b74Schristos
129375fd0b74Schristos /* Verify that the strings are null terminated. */
129475fd0b74Schristos if (ptr[size - 1] != 0
129575fd0b74Schristos || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size)
129675fd0b74Schristos {
129775fd0b74Schristos _bfd_error_handler
1298ede78133Schristos (_("%pB: string not null terminated in ILF object file"), abfd);
129975fd0b74Schristos bfd_set_error (bfd_error_malformed_archive);
130075fd0b74Schristos bfd_release (abfd, ptr);
130175fd0b74Schristos return NULL;
130275fd0b74Schristos }
130375fd0b74Schristos
130475fd0b74Schristos /* Now construct the bfd. */
130575fd0b74Schristos if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name,
130675fd0b74Schristos source_dll, ordinal, types))
130775fd0b74Schristos {
130875fd0b74Schristos bfd_release (abfd, ptr);
130975fd0b74Schristos return NULL;
131075fd0b74Schristos }
131175fd0b74Schristos
1312*e992f068Schristos return _bfd_no_cleanup;
131375fd0b74Schristos }
131475fd0b74Schristos
131575fd0b74Schristos static void
pe_bfd_read_buildid(bfd * abfd)131675fd0b74Schristos pe_bfd_read_buildid (bfd *abfd)
131775fd0b74Schristos {
131875fd0b74Schristos pe_data_type *pe = pe_data (abfd);
131975fd0b74Schristos struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
132075fd0b74Schristos asection *section;
132175fd0b74Schristos bfd_byte *data = 0;
132275fd0b74Schristos bfd_size_type dataoff;
132375fd0b74Schristos unsigned int i;
132475fd0b74Schristos bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
132575fd0b74Schristos bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
132675fd0b74Schristos
132775fd0b74Schristos if (size == 0)
132875fd0b74Schristos return;
132975fd0b74Schristos
133075fd0b74Schristos addr += extra->ImageBase;
133175fd0b74Schristos
1332ede78133Schristos /* Search for the section containing the DebugDirectory. */
133375fd0b74Schristos for (section = abfd->sections; section != NULL; section = section->next)
133475fd0b74Schristos {
133575fd0b74Schristos if ((addr >= section->vma) && (addr < (section->vma + section->size)))
133675fd0b74Schristos break;
133775fd0b74Schristos }
133875fd0b74Schristos
133975fd0b74Schristos if (section == NULL)
134075fd0b74Schristos return;
1341ede78133Schristos
1342ede78133Schristos if (!(section->flags & SEC_HAS_CONTENTS))
134375fd0b74Schristos return;
134475fd0b74Schristos
134575fd0b74Schristos dataoff = addr - section->vma;
134675fd0b74Schristos
1347ede78133Schristos /* PR 20605 and 22373: Make sure that the data is really there.
1348ede78133Schristos Note - since we are dealing with unsigned quantities we have
1349ede78133Schristos to be careful to check for potential overflows. */
1350ede78133Schristos if (dataoff >= section->size
1351ede78133Schristos || size > section->size - dataoff)
1352ede78133Schristos {
1353ede78133Schristos _bfd_error_handler
1354ede78133Schristos (_("%pB: error: debug data ends beyond end of debug directory"),
1355ede78133Schristos abfd);
1356ede78133Schristos return;
1357ede78133Schristos }
1358ede78133Schristos
135975fd0b74Schristos /* Read the whole section. */
136075fd0b74Schristos if (!bfd_malloc_and_get_section (abfd, section, &data))
136175fd0b74Schristos {
136275fd0b74Schristos free (data);
136375fd0b74Schristos return;
136475fd0b74Schristos }
136575fd0b74Schristos
136675fd0b74Schristos /* Search for a CodeView entry in the DebugDirectory */
136775fd0b74Schristos for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
136875fd0b74Schristos {
136975fd0b74Schristos struct external_IMAGE_DEBUG_DIRECTORY *ext
137075fd0b74Schristos = &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
137175fd0b74Schristos struct internal_IMAGE_DEBUG_DIRECTORY idd;
137275fd0b74Schristos
137375fd0b74Schristos _bfd_XXi_swap_debugdir_in (abfd, ext, &idd);
137475fd0b74Schristos
137575fd0b74Schristos if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW)
137675fd0b74Schristos {
137775fd0b74Schristos char buffer[256 + 1];
137875fd0b74Schristos CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer;
137975fd0b74Schristos
138075fd0b74Schristos /*
138175fd0b74Schristos The debug entry doesn't have to have to be in a section, in which
138275fd0b74Schristos case AddressOfRawData is 0, so always use PointerToRawData.
138375fd0b74Schristos */
138475fd0b74Schristos if (_bfd_XXi_slurp_codeview_record (abfd,
138575fd0b74Schristos (file_ptr) idd.PointerToRawData,
138675fd0b74Schristos idd.SizeOfData, cvinfo))
138775fd0b74Schristos {
138875fd0b74Schristos struct bfd_build_id* build_id = bfd_alloc (abfd,
138975fd0b74Schristos sizeof (struct bfd_build_id) + cvinfo->SignatureLength);
139075fd0b74Schristos if (build_id)
139175fd0b74Schristos {
139275fd0b74Schristos build_id->size = cvinfo->SignatureLength;
139375fd0b74Schristos memcpy(build_id->data, cvinfo->Signature,
139475fd0b74Schristos cvinfo->SignatureLength);
139575fd0b74Schristos abfd->build_id = build_id;
139675fd0b74Schristos }
139775fd0b74Schristos }
139875fd0b74Schristos break;
139975fd0b74Schristos }
140075fd0b74Schristos }
1401012573ebSchristos
1402012573ebSchristos free (data);
140375fd0b74Schristos }
140475fd0b74Schristos
1405*e992f068Schristos static bfd_cleanup
pe_bfd_object_p(bfd * abfd)140675fd0b74Schristos pe_bfd_object_p (bfd * abfd)
140775fd0b74Schristos {
140875fd0b74Schristos bfd_byte buffer[6];
1409ede78133Schristos struct external_DOS_hdr dos_hdr;
141075fd0b74Schristos struct external_PEI_IMAGE_hdr image_hdr;
141175fd0b74Schristos struct internal_filehdr internal_f;
141275fd0b74Schristos struct internal_aouthdr internal_a;
1413*e992f068Schristos bfd_size_type opt_hdr_size;
141475fd0b74Schristos file_ptr offset;
1415*e992f068Schristos bfd_cleanup result;
141675fd0b74Schristos
141775fd0b74Schristos /* Detect if this a Microsoft Import Library Format element. */
141875fd0b74Schristos /* First read the beginning of the header. */
141975fd0b74Schristos if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
142075fd0b74Schristos || bfd_bread (buffer, (bfd_size_type) 6, abfd) != 6)
142175fd0b74Schristos {
142275fd0b74Schristos if (bfd_get_error () != bfd_error_system_call)
142375fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
142475fd0b74Schristos return NULL;
142575fd0b74Schristos }
142675fd0b74Schristos
142775fd0b74Schristos /* Then check the magic and the version (only 0 is supported). */
142875fd0b74Schristos if (H_GET_32 (abfd, buffer) == 0xffff0000
142975fd0b74Schristos && H_GET_16 (abfd, buffer + 4) == 0)
143075fd0b74Schristos return pe_ILF_object_p (abfd);
143175fd0b74Schristos
143275fd0b74Schristos if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
143375fd0b74Schristos || bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd)
143475fd0b74Schristos != sizeof (dos_hdr))
143575fd0b74Schristos {
143675fd0b74Schristos if (bfd_get_error () != bfd_error_system_call)
143775fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
143875fd0b74Schristos return NULL;
143975fd0b74Schristos }
144075fd0b74Schristos
144175fd0b74Schristos /* There are really two magic numbers involved; the magic number
144275fd0b74Schristos that says this is a NT executable (PEI) and the magic number that
1443ede78133Schristos determines the architecture. The former is IMAGE_DOS_SIGNATURE, stored in
144475fd0b74Schristos the e_magic field. The latter is stored in the f_magic field.
144575fd0b74Schristos If the NT magic number isn't valid, the architecture magic number
144675fd0b74Schristos could be mimicked by some other field (specifically, the number
144775fd0b74Schristos of relocs in section 3). Since this routine can only be called
144875fd0b74Schristos correctly for a PEI file, check the e_magic number here, and, if
144975fd0b74Schristos it doesn't match, clobber the f_magic number so that we don't get
145075fd0b74Schristos a false match. */
1451ede78133Schristos if (H_GET_16 (abfd, dos_hdr.e_magic) != IMAGE_DOS_SIGNATURE)
145275fd0b74Schristos {
145375fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
145475fd0b74Schristos return NULL;
145575fd0b74Schristos }
145675fd0b74Schristos
145775fd0b74Schristos offset = H_GET_32 (abfd, dos_hdr.e_lfanew);
145875fd0b74Schristos if (bfd_seek (abfd, offset, SEEK_SET) != 0
145975fd0b74Schristos || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd)
146075fd0b74Schristos != sizeof (image_hdr)))
146175fd0b74Schristos {
146275fd0b74Schristos if (bfd_get_error () != bfd_error_system_call)
146375fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
146475fd0b74Schristos return NULL;
146575fd0b74Schristos }
146675fd0b74Schristos
146775fd0b74Schristos if (H_GET_32 (abfd, image_hdr.nt_signature) != 0x4550)
146875fd0b74Schristos {
146975fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
147075fd0b74Schristos return NULL;
147175fd0b74Schristos }
147275fd0b74Schristos
147375fd0b74Schristos /* Swap file header, so that we get the location for calling
147475fd0b74Schristos real_object_p. */
147575fd0b74Schristos bfd_coff_swap_filehdr_in (abfd, &image_hdr, &internal_f);
147675fd0b74Schristos
147775fd0b74Schristos if (! bfd_coff_bad_format_hook (abfd, &internal_f)
147875fd0b74Schristos || internal_f.f_opthdr > bfd_coff_aoutsz (abfd))
147975fd0b74Schristos {
148075fd0b74Schristos bfd_set_error (bfd_error_wrong_format);
148175fd0b74Schristos return NULL;
148275fd0b74Schristos }
148375fd0b74Schristos
1484012573ebSchristos memcpy (internal_f.pe.dos_message, dos_hdr.dos_message,
1485012573ebSchristos sizeof (internal_f.pe.dos_message));
1486012573ebSchristos
148775fd0b74Schristos /* Read the optional header, which has variable size. */
148875fd0b74Schristos opt_hdr_size = internal_f.f_opthdr;
148975fd0b74Schristos
149075fd0b74Schristos if (opt_hdr_size != 0)
149175fd0b74Schristos {
149275fd0b74Schristos bfd_size_type amt = opt_hdr_size;
1493*e992f068Schristos bfd_byte * opthdr;
149475fd0b74Schristos
149575fd0b74Schristos /* PR 17521 file: 230-131433-0.004. */
149675fd0b74Schristos if (amt < sizeof (PEAOUTHDR))
149775fd0b74Schristos amt = sizeof (PEAOUTHDR);
149875fd0b74Schristos
1499*e992f068Schristos opthdr = _bfd_alloc_and_read (abfd, amt, opt_hdr_size);
150075fd0b74Schristos if (opthdr == NULL)
150175fd0b74Schristos return NULL;
1502*e992f068Schristos if (amt > opt_hdr_size)
1503*e992f068Schristos memset (opthdr + opt_hdr_size, 0, amt - opt_hdr_size);
150475fd0b74Schristos
150575fd0b74Schristos bfd_set_error (bfd_error_no_error);
150675fd0b74Schristos bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a);
150775fd0b74Schristos if (bfd_get_error () != bfd_error_no_error)
150875fd0b74Schristos return NULL;
150975fd0b74Schristos }
151075fd0b74Schristos
151175fd0b74Schristos
151275fd0b74Schristos result = coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
151375fd0b74Schristos (opt_hdr_size != 0
151475fd0b74Schristos ? &internal_a
151575fd0b74Schristos : (struct internal_aouthdr *) NULL));
151675fd0b74Schristos
151775fd0b74Schristos
151875fd0b74Schristos if (result)
151975fd0b74Schristos {
152075fd0b74Schristos /* Now the whole header has been processed, see if there is a build-id */
152175fd0b74Schristos pe_bfd_read_buildid(abfd);
152275fd0b74Schristos }
152375fd0b74Schristos
152475fd0b74Schristos return result;
152575fd0b74Schristos }
152675fd0b74Schristos
152775fd0b74Schristos #define coff_object_p pe_bfd_object_p
152875fd0b74Schristos #endif /* COFF_IMAGE_WITH_PE */
1529