/* BFD back-end for Intel 386 COFF files.
- Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+ Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
#include "coff/pe.h"
#endif
+#ifdef COFF_GO32_EXE
+#include "coff/go32exe.h"
+#endif
+
#include "libcoff.h"
static bfd_reloc_status_type coff_i386_reloc
arelent *reloc_entry;
asymbol *symbol;
PTR data;
- asection *input_section;
+ asection *input_section ATTRIBUTE_UNUSED;
bfd *output_bfd;
- char **error_message;
+ char **error_message ATTRIBUTE_UNUSED;
{
symvalue diff;
if (bfd_is_com_section (symbol->section))
{
+#ifndef COFF_WITH_PE
/* We are relocating a common symbol. The current value in the
object file is ORIG + OFFSET, where ORIG is the value of the
common symbol as seen by the object file when it was compiled
the common symbol which we are going to put in the final
object file. NEW is symbol->value. */
diff = symbol->value + reloc_entry->addend;
+#else
+ /* In PE mode, we do not offset the common symbol. */
+ diff = reloc_entry->addend;
+#endif
}
else
{
appear in the output .reloc section. */
static boolean in_reloc_p(abfd, howto)
- bfd * abfd;
+ bfd * abfd ATTRIBUTE_UNUSED;
reloc_howto_type *howto;
{
return ! howto->pc_relative && howto->type != R_IMAGEBASE;
static reloc_howto_type howto_table[] =
{
- {0},
- {1},
- {2},
- {3},
- {4},
- {5},
+ EMPTY_HOWTO (0),
+ EMPTY_HOWTO (1),
+ EMPTY_HOWTO (2),
+ EMPTY_HOWTO (3),
+ EMPTY_HOWTO (4),
+ EMPTY_HOWTO (5),
HOWTO (R_DIR32, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
- {010},
- {011},
- {012},
- {013},
- {014},
- {015},
- {016},
+ EMPTY_HOWTO (010),
+ EMPTY_HOWTO (011),
+ EMPTY_HOWTO (012),
+ EMPTY_HOWTO (013),
+ EMPTY_HOWTO (014),
+ EMPTY_HOWTO (015),
+ EMPTY_HOWTO (016),
HOWTO (R_RELBYTE, /* type */
0, /* rightshift */
0, /* size (0 = byte, 1 = short, 2 = long) */
cache_ptr->addend += asect->vma; \
}
-/* We use the special COFF backend linker. */
+/* We use the special COFF backend linker. For normal i386 COFF, we
+ can use the generic relocate_section routine. For PE, we need our
+ own routine. */
+
+#ifndef COFF_WITH_PE
+
#define coff_relocate_section _bfd_coff_generic_relocate_section
+#else /* COFF_WITH_PE */
+
+/* The PE relocate section routine. The only difference between this
+ and the regular routine is that we don't want to do anything for a
+ relocateable link. */
+
+static boolean coff_pe_i386_relocate_section
+ PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **));
+
+static boolean
+coff_pe_i386_relocate_section (output_bfd, info, input_bfd,
+ input_section, contents, relocs, syms,
+ sections)
+ bfd *output_bfd;
+ struct bfd_link_info *info;
+ bfd *input_bfd;
+ asection *input_section;
+ bfd_byte *contents;
+ struct internal_reloc *relocs;
+ struct internal_syment *syms;
+ asection **sections;
+{
+ if (info->relocateable)
+ return true;
+
+ return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
+ input_section, contents,
+ relocs, syms, sections);
+}
+
+#define coff_relocate_section coff_pe_i386_relocate_section
+
+#endif /* COFF_WITH_PE */
+
+/* Convert an rtype to howto for the COFF backend linker. */
+
static reloc_howto_type *
coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
asection *sec;
struct internal_reloc *rel;
struct coff_link_hash_entry *h;
BFD_ASSERT (h != NULL);
-
#ifndef COFF_WITH_PE
- /* I think we *do* want to bypass this. If we don't, I have seen some data
- parameters get the wrong relcation address. If I link two versions
- with and without this section bypassed and then do a binary comparison,
- the addresses which are different can be looked up in the map. The
- case in which this section has been bypassed has addresses which correspond
- to values I can find in the map */
+ /* I think we *do* want to bypass this. If we don't, I have
+ seen some data parameters get the wrong relocation address.
+ If I link two versions with and without this section bypassed
+ and then do a binary comparison, the addresses which are
+ different can be looked up in the map. The case in which
+ this section has been bypassed has addresses which correspond
+ to values I can find in the map. */
*addendp -= sym->n_value;
#endif
}
+#ifndef COFF_WITH_PE
/* If the output symbol is common (in which case this must be a
relocateable link), we need to add in the final size of the
common symbol. */
if (h != NULL && h->root.type == bfd_link_hash_common)
*addendp += h->root.u.c.size;
-
+#endif
#ifdef COFF_WITH_PE
if (howto->pc_relative)
- *addendp -= 4;
+ {
+ *addendp -= 4;
+
+ /* If the symbol is defined, then the generic code is going to
+ add back the symbol value in order to cancel out an
+ adjustment it made to the addend. However, we set the addend
+ to 0 at the start of this function. We need to adjust here,
+ to avoid the adjustment the generic code will make. FIXME:
+ This is getting a bit hackish. */
+ if (sym != NULL && sym->n_scnum != 0)
+ *addendp -= sym->n_value;
+ }
if (rel->r_type == R_IMAGEBASE)
{
static reloc_howto_type *
coff_i386_reloc_type_lookup (abfd, code)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
bfd_reloc_code_real_type code;
{
switch (code)
}
}
+#define coff_rtype_to_howto coff_i386_rtype_to_howto
+#ifdef TARGET_UNDERSCORE
-#define coff_rtype_to_howto coff_i386_rtype_to_howto
+/* If i386 gcc uses underscores for symbol names, then it does not use
+ a leading dot for local labels, so if TARGET_UNDERSCORE is defined
+ we treat all symbols starting with L as local. */
+
+static boolean coff_i386_is_local_label_name PARAMS ((bfd *, const char *));
+
+static boolean
+coff_i386_is_local_label_name (abfd, name)
+ bfd *abfd;
+ const char *name;
+{
+ if (name[0] == 'L')
+ return true;
+
+ return _bfd_coff_is_local_label_name (abfd, name);
+}
+
+#define coff_bfd_is_local_label_name coff_i386_is_local_label_name
+
+#endif /* TARGET_UNDERSCORE */
#include "coffcode.h"
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
#ifndef COFF_WITH_PE
- (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+ | SEC_CODE | SEC_DATA),
#else
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+ | SEC_CODE | SEC_DATA
| SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
#endif