15f210c2aSfgsch /* BFD back-end for HP/Intel IA-64 COFF files.
2*d2201f2fSdrahn Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
35f210c2aSfgsch Contributed by David Mosberger <davidm@hpl.hp.com>
45f210c2aSfgsch
55f210c2aSfgsch This file is part of BFD, the Binary File Descriptor library.
65f210c2aSfgsch
75f210c2aSfgsch This program is free software; you can redistribute it and/or modify
85f210c2aSfgsch it under the terms of the GNU General Public License as published by
95f210c2aSfgsch the Free Software Foundation; either version 2 of the License, or
105f210c2aSfgsch (at your option) any later version.
115f210c2aSfgsch
125f210c2aSfgsch This program is distributed in the hope that it will be useful,
135f210c2aSfgsch but WITHOUT ANY WARRANTY; without even the implied warranty of
145f210c2aSfgsch MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
155f210c2aSfgsch GNU General Public License for more details.
165f210c2aSfgsch
175f210c2aSfgsch You should have received a copy of the GNU General Public License
185f210c2aSfgsch along with this program; if not, write to the Free Software
195f210c2aSfgsch Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
205f210c2aSfgsch
215f210c2aSfgsch #include "bfd.h"
225f210c2aSfgsch #include "sysdep.h"
235f210c2aSfgsch #include "libbfd.h"
245f210c2aSfgsch #include "coff/ia64.h"
255f210c2aSfgsch #include "coff/internal.h"
265f210c2aSfgsch #include "coff/pe.h"
275f210c2aSfgsch #include "libcoff.h"
285f210c2aSfgsch
295f210c2aSfgsch #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
305f210c2aSfgsch /* The page size is a guess based on ELF. */
315f210c2aSfgsch
325f210c2aSfgsch #define COFF_PAGE_SIZE 0x1000
335f210c2aSfgsch
345f210c2aSfgsch static reloc_howto_type howto_table[] =
355f210c2aSfgsch {
365f210c2aSfgsch EMPTY_HOWTO (0),
375f210c2aSfgsch };
385f210c2aSfgsch
395f210c2aSfgsch #define BADMAG(x) IA64BADMAG(x)
405f210c2aSfgsch #define IA64 1 /* Customize coffcode.h */
415f210c2aSfgsch
425f210c2aSfgsch #ifdef COFF_WITH_pep
435f210c2aSfgsch # undef AOUTSZ
445f210c2aSfgsch # define AOUTSZ PEPAOUTSZ
455f210c2aSfgsch # define PEAOUTHDR PEPAOUTHDR
465f210c2aSfgsch #endif
475f210c2aSfgsch
485f210c2aSfgsch #define RTYPE2HOWTO(cache_ptr, dst) \
495f210c2aSfgsch (cache_ptr)->howto = howto_table + (dst)->r_type;
505f210c2aSfgsch
515f210c2aSfgsch #ifdef COFF_WITH_PE
52*d2201f2fSdrahn /* Return TRUE if this relocation should
535f210c2aSfgsch appear in the output .reloc section. */
545f210c2aSfgsch
55*d2201f2fSdrahn static bfd_boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));
56*d2201f2fSdrahn
57*d2201f2fSdrahn static bfd_boolean
in_reloc_p(abfd,howto)585f210c2aSfgsch in_reloc_p(abfd, howto)
595f210c2aSfgsch bfd * abfd ATTRIBUTE_UNUSED;
605f210c2aSfgsch reloc_howto_type *howto ATTRIBUTE_UNUSED;
615f210c2aSfgsch {
62*d2201f2fSdrahn return FALSE; /* We don't do relocs for now... */
635f210c2aSfgsch }
645f210c2aSfgsch #endif
655f210c2aSfgsch
665f210c2aSfgsch #include "coffcode.h"
675f210c2aSfgsch
68*d2201f2fSdrahn static const bfd_target *ia64coff_object_p PARAMS ((bfd *));
69*d2201f2fSdrahn
705f210c2aSfgsch static const bfd_target *
ia64coff_object_p(abfd)715f210c2aSfgsch ia64coff_object_p (abfd)
725f210c2aSfgsch bfd *abfd;
735f210c2aSfgsch {
745f210c2aSfgsch #ifdef COFF_IMAGE_WITH_PE
755f210c2aSfgsch {
765f210c2aSfgsch struct external_PEI_DOS_hdr dos_hdr;
775f210c2aSfgsch struct external_PEI_IMAGE_hdr image_hdr;
785f210c2aSfgsch file_ptr offset;
795f210c2aSfgsch
80*d2201f2fSdrahn if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
81*d2201f2fSdrahn || (bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd)
82*d2201f2fSdrahn != sizeof (dos_hdr)))
835f210c2aSfgsch {
845f210c2aSfgsch if (bfd_get_error () != bfd_error_system_call)
855f210c2aSfgsch bfd_set_error (bfd_error_wrong_format);
865f210c2aSfgsch return NULL;
875f210c2aSfgsch }
885f210c2aSfgsch
895f210c2aSfgsch /* There are really two magic numbers involved; the magic number
905f210c2aSfgsch that says this is a NT executable (PEI) and the magic number
915f210c2aSfgsch that determines the architecture. The former is DOSMAGIC,
925f210c2aSfgsch stored in the e_magic field. The latter is stored in the
935f210c2aSfgsch f_magic field. If the NT magic number isn't valid, the
945f210c2aSfgsch architecture magic number could be mimicked by some other
955f210c2aSfgsch field (specifically, the number of relocs in section 3). Since
965f210c2aSfgsch this routine can only be called correctly for a PEI file, check
975f210c2aSfgsch the e_magic number here, and, if it doesn't match, clobber the
985f210c2aSfgsch f_magic number so that we don't get a false match. */
99*d2201f2fSdrahn if (H_GET_16 (abfd, dos_hdr.e_magic) != DOSMAGIC)
1005f210c2aSfgsch {
1015f210c2aSfgsch bfd_set_error (bfd_error_wrong_format);
1025f210c2aSfgsch return NULL;
1035f210c2aSfgsch }
1045f210c2aSfgsch
105*d2201f2fSdrahn offset = H_GET_32 (abfd, dos_hdr.e_lfanew);
106*d2201f2fSdrahn if (bfd_seek (abfd, offset, SEEK_SET) != 0
107*d2201f2fSdrahn || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd)
108*d2201f2fSdrahn != sizeof (image_hdr)))
1095f210c2aSfgsch {
1105f210c2aSfgsch if (bfd_get_error () != bfd_error_system_call)
1115f210c2aSfgsch bfd_set_error (bfd_error_wrong_format);
1125f210c2aSfgsch return NULL;
1135f210c2aSfgsch }
1145f210c2aSfgsch
115*d2201f2fSdrahn if (H_GET_32 (abfd, image_hdr.nt_signature)
1165f210c2aSfgsch != 0x4550)
1175f210c2aSfgsch {
1185f210c2aSfgsch bfd_set_error (bfd_error_wrong_format);
1195f210c2aSfgsch return NULL;
1205f210c2aSfgsch }
1215f210c2aSfgsch
1225f210c2aSfgsch /* Here is the hack. coff_object_p wants to read filhsz bytes to
1235f210c2aSfgsch pick up the COFF header for PE, see "struct external_PEI_filehdr"
1245f210c2aSfgsch in include/coff/pe.h. We adjust so that that will work. */
125*d2201f2fSdrahn if (bfd_seek (abfd, offset - sizeof (dos_hdr), SEEK_SET) != 0)
1265f210c2aSfgsch {
1275f210c2aSfgsch if (bfd_get_error () != bfd_error_system_call)
1285f210c2aSfgsch bfd_set_error (bfd_error_wrong_format);
1295f210c2aSfgsch return NULL;
1305f210c2aSfgsch }
1315f210c2aSfgsch }
1325f210c2aSfgsch #endif
1335f210c2aSfgsch
1345f210c2aSfgsch return coff_object_p (abfd);
1355f210c2aSfgsch }
1365f210c2aSfgsch
1375f210c2aSfgsch const bfd_target
1385f210c2aSfgsch #ifdef TARGET_SYM
1395f210c2aSfgsch TARGET_SYM =
1405f210c2aSfgsch #else
1415f210c2aSfgsch ia64coff_vec =
1425f210c2aSfgsch #endif
1435f210c2aSfgsch {
1445f210c2aSfgsch #ifdef TARGET_NAME
1455f210c2aSfgsch TARGET_NAME,
1465f210c2aSfgsch #else
1475f210c2aSfgsch "coff-ia64", /* name */
1485f210c2aSfgsch #endif
1495f210c2aSfgsch bfd_target_coff_flavour,
1505f210c2aSfgsch BFD_ENDIAN_LITTLE, /* data byte order is little */
1515f210c2aSfgsch BFD_ENDIAN_LITTLE, /* header byte order is little */
1525f210c2aSfgsch
1535f210c2aSfgsch (HAS_RELOC | EXEC_P | /* object flags */
1545f210c2aSfgsch HAS_LINENO | HAS_DEBUG |
1555f210c2aSfgsch HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
1565f210c2aSfgsch
1575f210c2aSfgsch #ifndef COFF_WITH_PE
1585f210c2aSfgsch (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
1595f210c2aSfgsch | SEC_CODE | SEC_DATA),
1605f210c2aSfgsch #else
1615f210c2aSfgsch (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
1625f210c2aSfgsch | SEC_CODE | SEC_DATA
1635f210c2aSfgsch | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
1645f210c2aSfgsch #endif
1655f210c2aSfgsch
1665f210c2aSfgsch #ifdef TARGET_UNDERSCORE
1675f210c2aSfgsch TARGET_UNDERSCORE, /* leading underscore */
1685f210c2aSfgsch #else
1695f210c2aSfgsch 0, /* leading underscore */
1705f210c2aSfgsch #endif
1715f210c2aSfgsch '/', /* ar_pad_char */
1725f210c2aSfgsch 15, /* ar_max_namelen */
1735f210c2aSfgsch
1745f210c2aSfgsch bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1755f210c2aSfgsch bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1765f210c2aSfgsch bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
1775f210c2aSfgsch bfd_getl64, bfd_getl_signed_64, bfd_putl64,
1785f210c2aSfgsch bfd_getl32, bfd_getl_signed_32, bfd_putl32,
1795f210c2aSfgsch bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
1805f210c2aSfgsch
1815f210c2aSfgsch /* Note that we allow an object file to be treated as a core file as well. */
1825f210c2aSfgsch {_bfd_dummy_target, ia64coff_object_p, /* bfd_check_format */
1835f210c2aSfgsch bfd_generic_archive_p, ia64coff_object_p},
1845f210c2aSfgsch {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
1855f210c2aSfgsch bfd_false},
1865f210c2aSfgsch {bfd_false, coff_write_object_contents, /* bfd_write_contents */
1875f210c2aSfgsch _bfd_write_archive_contents, bfd_false},
1885f210c2aSfgsch
1895f210c2aSfgsch BFD_JUMP_TABLE_GENERIC (coff),
1905f210c2aSfgsch BFD_JUMP_TABLE_COPY (coff),
1915f210c2aSfgsch BFD_JUMP_TABLE_CORE (_bfd_nocore),
1925f210c2aSfgsch BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
1935f210c2aSfgsch BFD_JUMP_TABLE_SYMBOLS (coff),
1945f210c2aSfgsch BFD_JUMP_TABLE_RELOCS (coff),
1955f210c2aSfgsch BFD_JUMP_TABLE_WRITE (coff),
1965f210c2aSfgsch BFD_JUMP_TABLE_LINK (coff),
1975f210c2aSfgsch BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1985f210c2aSfgsch
1995f210c2aSfgsch NULL,
2005f210c2aSfgsch
2015f210c2aSfgsch COFF_SWAP_TABLE
2025f210c2aSfgsch };
203