/* BFD back-end for Intel 386 COFF files.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
-#include "obstack.h"
#include "coff/i386.h"
if (output_bfd == (bfd *) NULL)
return bfd_reloc_continue;
-
if (bfd_is_com_section (symbol->section))
{
/* We are relocating a common symbol. The current value in the
diff = reloc_entry->addend;
}
-
#ifdef COFF_WITH_PE
- if (reloc_entry->howto->type == 7)
- {
-/* diff -= coff_data(output_bfd)->link_info->pe_info.image_base.value;*/
- exit(1);
- }
+ /* FIXME: How should this case be handled? */
+ if (reloc_entry->howto->type == R_IMAGEBASE && diff != 0)
+ abort ();
#endif
#define DOIT(x) \
return bfd_reloc_continue;
}
+#ifdef COFF_WITH_PE
+/* Return true if this relocation should
+ appear in the output .reloc section. */
+static boolean in_reloc_p(abfd, howto)
+ bfd * abfd;
+ reloc_howto_type *howto;
+{
+ return ! howto->pc_relative && howto->type != R_IMAGEBASE;
+}
+#endif
#ifndef PCRELOFFSET
#define PCRELOFFSET false
#define RTYPE2HOWTO(cache_ptr, dst) \
(cache_ptr)->howto = howto_table + (dst)->r_type;
-/* On SCO Unix 3.2.2 the native assembler generates two .data
- sections. We handle that by renaming the second one to .data2. It
- does no harm to do this for any 386 COFF target. */
-#define TWO_DATA_SECS
-
/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
library. On some other COFF targets STYP_BSS is normally
STYP_NOLOAD. */
return howto;
}
+
+#define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup
+
+
+static reloc_howto_type *
+coff_i386_reloc_type_lookup (abfd, code)
+ bfd *abfd;
+ bfd_reloc_code_real_type code;
+{
+ switch (code)
+ {
+ case BFD_RELOC_RVA:
+ return howto_table +R_IMAGEBASE;
+ case BFD_RELOC_32:
+ return howto_table + R_DIR32;
+ case BFD_RELOC_32_PCREL:
+ return howto_table + R_PCRLONG;
+ default:
+ BFD_FAIL ();
+ return 0;
+ }
+}
+
+
+
#define coff_rtype_to_howto coff_i386_rtype_to_howto
#include "coffcode.h"
static const bfd_target *
-i3coff_object_p(a)
- bfd *a;
+i3coff_object_p (abfd)
+ bfd *abfd;
{
- return coff_object_p(a);
+#ifdef COFF_IMAGE_WITH_PE
+ /* We need to hack badly to handle a PE image correctly. In PE
+ images created by the GNU linker, the offset to the COFF header
+ is always the size. However, this is not the case in images
+ generated by other PE linkers. The PE format stores a four byte
+ offset to the PE signature just before the COFF header at
+ location 0x3c of the file. We pick up that offset, verify that
+ the PE signature is there, and then set ourselves up to read in
+ the COFF header. */
+ {
+ bfd_byte ext_offset[4];
+ file_ptr offset;
+ bfd_byte ext_signature[4];
+ unsigned long signature;
+
+ if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0
+ || bfd_read (ext_offset, 1, 4, abfd) != 4)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ offset = bfd_h_get_32 (abfd, ext_offset);
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0
+ || bfd_read (ext_signature, 1, 4, abfd) != 4)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ signature = bfd_h_get_32 (abfd, ext_signature);
+
+ if (signature != 0x4550)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Here is the hack. coff_object_p wants to read filhsz bytes to
+ pick up the COFF header. We adjust so that that will work. 20
+ is the size of the i386 COFF filehdr. */
+
+ if (bfd_seek (abfd,
+ (bfd_tell (abfd)
+ - bfd_coff_filhsz (abfd)
+ + 20),
+ SEEK_SET)
+ != 0)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ }
+#endif
+
+ return coff_object_p (abfd);
}
const bfd_target
"coff-i386", /* name */
#endif
bfd_target_coff_flavour,
- false, /* data byte order is little */
- false, /* header byte order is little */
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little */
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+#ifndef COFF_WITH_PE
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+#else
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+#endif
+
#ifdef TARGET_UNDERSCORE
TARGET_UNDERSCORE, /* leading underscore */
#else