184865Sobrien/* BFD back-end for HP/Intel IA-64 COFF files. 2218822Sdim Copyright 1999, 2000, 2001, 2002, 2007 Free Software Foundation, Inc. 384865Sobrien Contributed by David Mosberger <davidm@hpl.hp.com> 484865Sobrien 584865SobrienThis file is part of BFD, the Binary File Descriptor library. 684865Sobrien 784865SobrienThis program is free software; you can redistribute it and/or modify 884865Sobrienit under the terms of the GNU General Public License as published by 984865Sobrienthe Free Software Foundation; either version 2 of the License, or 1084865Sobrien(at your option) any later version. 1184865Sobrien 1284865SobrienThis program is distributed in the hope that it will be useful, 1384865Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 1484865SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1584865SobrienGNU General Public License for more details. 1684865Sobrien 1784865SobrienYou should have received a copy of the GNU General Public License 1884865Sobrienalong with this program; if not, write to the Free Software 19218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2084865Sobrien 21218822Sdim#include "sysdep.h" 2284865Sobrien#include "bfd.h" 2384865Sobrien#include "libbfd.h" 2484865Sobrien#include "coff/ia64.h" 2584865Sobrien#include "coff/internal.h" 2684865Sobrien#include "coff/pe.h" 2784865Sobrien#include "libcoff.h" 2884865Sobrien 2984865Sobrien#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) 3084865Sobrien/* The page size is a guess based on ELF. */ 3184865Sobrien 3284865Sobrien#define COFF_PAGE_SIZE 0x1000 3384865Sobrien 3484865Sobrienstatic reloc_howto_type howto_table[] = 3584865Sobrien{ 3684865Sobrien EMPTY_HOWTO (0), 3784865Sobrien}; 3884865Sobrien 3984865Sobrien#define BADMAG(x) IA64BADMAG(x) 4084865Sobrien#define IA64 1 /* Customize coffcode.h */ 4184865Sobrien 4284865Sobrien#ifdef COFF_WITH_pep 4384865Sobrien# undef AOUTSZ 4484865Sobrien# define AOUTSZ PEPAOUTSZ 4584865Sobrien# define PEAOUTHDR PEPAOUTHDR 4684865Sobrien#endif 4784865Sobrien 4884865Sobrien#define RTYPE2HOWTO(cache_ptr, dst) \ 4984865Sobrien (cache_ptr)->howto = howto_table + (dst)->r_type; 5084865Sobrien 5184865Sobrien#ifdef COFF_WITH_PE 52130561Sobrien/* Return TRUE if this relocation should 5384865Sobrien appear in the output .reloc section. */ 5484865Sobrien 55130561Sobrienstatic bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *)); 5689857Sobrien 57130561Sobrienstatic bfd_boolean 5884865Sobrienin_reloc_p(abfd, howto) 5984865Sobrien bfd * abfd ATTRIBUTE_UNUSED; 6084865Sobrien reloc_howto_type *howto ATTRIBUTE_UNUSED; 6184865Sobrien{ 62130561Sobrien return FALSE; /* We don't do relocs for now... */ 6384865Sobrien} 6484865Sobrien#endif 6584865Sobrien 6684865Sobrien#include "coffcode.h" 6784865Sobrien 6889857Sobrienstatic const bfd_target *ia64coff_object_p PARAMS ((bfd *)); 6989857Sobrien 7084865Sobrienstatic const bfd_target * 7184865Sobrienia64coff_object_p (abfd) 7284865Sobrien bfd *abfd; 7384865Sobrien{ 7484865Sobrien#ifdef COFF_IMAGE_WITH_PE 7584865Sobrien { 7684865Sobrien struct external_PEI_DOS_hdr dos_hdr; 7784865Sobrien struct external_PEI_IMAGE_hdr image_hdr; 7884865Sobrien file_ptr offset; 7984865Sobrien 8089857Sobrien if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 8189857Sobrien || (bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd) 8289857Sobrien != sizeof (dos_hdr))) 8384865Sobrien { 8484865Sobrien if (bfd_get_error () != bfd_error_system_call) 8584865Sobrien bfd_set_error (bfd_error_wrong_format); 8684865Sobrien return NULL; 8784865Sobrien } 8884865Sobrien 8984865Sobrien /* There are really two magic numbers involved; the magic number 9084865Sobrien that says this is a NT executable (PEI) and the magic number 9184865Sobrien that determines the architecture. The former is DOSMAGIC, 9284865Sobrien stored in the e_magic field. The latter is stored in the 9384865Sobrien f_magic field. If the NT magic number isn't valid, the 9484865Sobrien architecture magic number could be mimicked by some other 9584865Sobrien field (specifically, the number of relocs in section 3). Since 9684865Sobrien this routine can only be called correctly for a PEI file, check 9784865Sobrien the e_magic number here, and, if it doesn't match, clobber the 9884865Sobrien f_magic number so that we don't get a false match. */ 9989857Sobrien if (H_GET_16 (abfd, dos_hdr.e_magic) != DOSMAGIC) 10084865Sobrien { 10184865Sobrien bfd_set_error (bfd_error_wrong_format); 10284865Sobrien return NULL; 10384865Sobrien } 10484865Sobrien 10589857Sobrien offset = H_GET_32 (abfd, dos_hdr.e_lfanew); 10689857Sobrien if (bfd_seek (abfd, offset, SEEK_SET) != 0 10789857Sobrien || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd) 10889857Sobrien != sizeof (image_hdr))) 10984865Sobrien { 11084865Sobrien if (bfd_get_error () != bfd_error_system_call) 11184865Sobrien bfd_set_error (bfd_error_wrong_format); 11284865Sobrien return NULL; 11384865Sobrien } 11484865Sobrien 11589857Sobrien if (H_GET_32 (abfd, image_hdr.nt_signature) 11684865Sobrien != 0x4550) 11784865Sobrien { 11884865Sobrien bfd_set_error (bfd_error_wrong_format); 11984865Sobrien return NULL; 12084865Sobrien } 12184865Sobrien 12284865Sobrien /* Here is the hack. coff_object_p wants to read filhsz bytes to 12384865Sobrien pick up the COFF header for PE, see "struct external_PEI_filehdr" 12484865Sobrien in include/coff/pe.h. We adjust so that that will work. */ 12589857Sobrien if (bfd_seek (abfd, offset - sizeof (dos_hdr), SEEK_SET) != 0) 12684865Sobrien { 12784865Sobrien if (bfd_get_error () != bfd_error_system_call) 12884865Sobrien bfd_set_error (bfd_error_wrong_format); 12984865Sobrien return NULL; 13084865Sobrien } 13184865Sobrien } 13284865Sobrien#endif 13384865Sobrien 13484865Sobrien return coff_object_p (abfd); 13584865Sobrien} 13684865Sobrien 13784865Sobrienconst bfd_target 13884865Sobrien#ifdef TARGET_SYM 13984865Sobrien TARGET_SYM = 14084865Sobrien#else 14184865Sobrien ia64coff_vec = 14284865Sobrien#endif 14384865Sobrien{ 14484865Sobrien#ifdef TARGET_NAME 14584865Sobrien TARGET_NAME, 14684865Sobrien#else 14784865Sobrien "coff-ia64", /* name */ 14884865Sobrien#endif 14984865Sobrien bfd_target_coff_flavour, 15084865Sobrien BFD_ENDIAN_LITTLE, /* data byte order is little */ 15184865Sobrien BFD_ENDIAN_LITTLE, /* header byte order is little */ 15284865Sobrien 15384865Sobrien (HAS_RELOC | EXEC_P | /* object flags */ 15484865Sobrien HAS_LINENO | HAS_DEBUG | 15584865Sobrien HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), 15684865Sobrien 15784865Sobrien#ifndef COFF_WITH_PE 15884865Sobrien (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */ 15984865Sobrien | SEC_CODE | SEC_DATA), 16084865Sobrien#else 16184865Sobrien (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */ 16284865Sobrien | SEC_CODE | SEC_DATA 16384865Sobrien | SEC_LINK_ONCE | SEC_LINK_DUPLICATES), 16484865Sobrien#endif 16584865Sobrien 16684865Sobrien#ifdef TARGET_UNDERSCORE 16784865Sobrien TARGET_UNDERSCORE, /* leading underscore */ 16884865Sobrien#else 16984865Sobrien 0, /* leading underscore */ 17084865Sobrien#endif 17184865Sobrien '/', /* ar_pad_char */ 17284865Sobrien 15, /* ar_max_namelen */ 17384865Sobrien 17484865Sobrien bfd_getl64, bfd_getl_signed_64, bfd_putl64, 17584865Sobrien bfd_getl32, bfd_getl_signed_32, bfd_putl32, 17684865Sobrien bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ 17784865Sobrien bfd_getl64, bfd_getl_signed_64, bfd_putl64, 17884865Sobrien bfd_getl32, bfd_getl_signed_32, bfd_putl32, 17984865Sobrien bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ 18084865Sobrien 18184865Sobrien/* Note that we allow an object file to be treated as a core file as well. */ 18284865Sobrien {_bfd_dummy_target, ia64coff_object_p, /* bfd_check_format */ 18384865Sobrien bfd_generic_archive_p, ia64coff_object_p}, 18484865Sobrien {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ 18584865Sobrien bfd_false}, 18684865Sobrien {bfd_false, coff_write_object_contents, /* bfd_write_contents */ 18784865Sobrien _bfd_write_archive_contents, bfd_false}, 18884865Sobrien 18984865Sobrien BFD_JUMP_TABLE_GENERIC (coff), 19084865Sobrien BFD_JUMP_TABLE_COPY (coff), 19184865Sobrien BFD_JUMP_TABLE_CORE (_bfd_nocore), 19284865Sobrien BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), 19384865Sobrien BFD_JUMP_TABLE_SYMBOLS (coff), 19484865Sobrien BFD_JUMP_TABLE_RELOCS (coff), 19584865Sobrien BFD_JUMP_TABLE_WRITE (coff), 19684865Sobrien BFD_JUMP_TABLE_LINK (coff), 19784865Sobrien BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 19884865Sobrien 19984865Sobrien NULL, 20084865Sobrien 20184865Sobrien COFF_SWAP_TABLE 20284865Sobrien}; 203