/* BFD back-end for ARM COFF files.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
+ Copyright (C) 1990-2017 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "libbfd.h"
#include "coff/arm.h"
#include "coff/internal.h"
osect_vma = h->root.u.def.section->output_section->vma;
else
{
- asection *sec;
int i;
/* Sigh, the only way to get the section to offset against
bfd_reloc_status_type flag = bfd_reloc_ok;
/* If this is an undefined symbol, return error. */
- if (symbol->section == &bfd_und_section
+ if (bfd_is_und_section (symbol->section)
&& (symbol->flags & BSF_WEAK) == 0)
return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
}
/* If this is an undefined symbol, return error. */
- if (symbol->section == &bfd_und_section
+ if (bfd_is_und_section (symbol->section)
&& (symbol->flags & BSF_WEAK) == 0)
return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined;
#define ASTD(i,j) case i: return aoutarm_std_reloc_howto + j
if (code == BFD_RELOC_CTOR)
- switch (bfd_get_arch_info (abfd)->bits_per_address)
+ switch (bfd_arch_bits_per_address (abfd))
{
case 32:
code = BFD_RELOC_32;
}
}
+static reloc_howto_type *
+coff_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (aoutarm_std_reloc_howto)
+ / sizeof (aoutarm_std_reloc_howto[0]));
+ i++)
+ if (aoutarm_std_reloc_howto[i].name != NULL
+ && strcasecmp (aoutarm_std_reloc_howto[i].name, r_name) == 0)
+ return &aoutarm_std_reloc_howto[i];
+
+ return NULL;
+}
+
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
#define COFF_PAGE_SIZE 0x1000
struct coff_arm_link_hash_table * ret;
bfd_size_type amt = sizeof (struct coff_arm_link_hash_table);
- ret = bfd_malloc (amt);
+ ret = bfd_zmalloc (amt);
if (ret == NULL)
return NULL;
return NULL;
}
- ret->thumb_glue_size = 0;
- ret->arm_glue_size = 0;
- ret->bfd_of_glue_owner = NULL;
-
return & ret->root.root;
}
-static void
+static bfd_boolean
arm_emit_base_file_entry (struct bfd_link_info *info,
bfd *output_bfd,
asection *input_section,
bfd_vma reloc_offset)
{
- bfd_vma addr = reloc_offset
- - input_section->vma
- + input_section->output_offset
- + input_section->output_section->vma;
+ bfd_vma addr = (reloc_offset
+ - input_section->vma
+ + input_section->output_offset
+ + input_section->output_section->vma);
if (coff_data (output_bfd)->pe)
addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
- fwrite (& addr, 1, sizeof (addr), (FILE *) info->base_file);
+ if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
+ return TRUE;
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
}
\f
#ifndef ARM_WINCE
relocations to be reflected in section's data. */
if (rel->r_type == ARM_26
&& h != NULL
- && info->relocatable
+ && bfd_link_relocatable (info)
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& (h->root.u.def.section->output_section
#ifdef ARM_WINCE
/* MS ARM-CE makes the reloc relative to the opcode's pc, not
the next opcode's pc, so is off by one. */
- if (howto->pc_relative && !info->relocatable)
+ if (howto->pc_relative && !bfd_link_relocatable (info))
addend -= 8;
#endif
then we should ignore the symbol value. */
if (howto->pc_relative && howto->pcrel_offset)
{
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
continue;
/* FIXME - it is not clear which targets need this next test
and which do not. It is known that it is needed for the
stub generation to the final linker pass. If we fail to
verify that the name is defined, we'll try to build stubs
for an undefined name... */
- if (! info->relocatable
+ if (! bfd_link_relocatable (info)
&& ( h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak))
{
if (howto->type == ARM_26)
{
- if ( h->class == C_THUMBSTATFUNC
- || h->class == C_THUMBEXTFUNC)
+ if ( h->symbol_class == C_THUMBSTATFUNC
+ || h->symbol_class == C_THUMBEXTFUNC)
{
/* Arm code calling a Thumb function. */
unsigned long int tmp;
bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn,
s->contents + my_offset + 8);
- if (info->base_file)
- arm_emit_base_file_entry (info, output_bfd, s,
- my_offset + 8);
-
+ if (info->base_file
+ && !arm_emit_base_file_entry (info, output_bfd,
+ s, my_offset + 8))
+ return FALSE;
}
BFD_ASSERT (my_offset <= globals->arm_glue_size);
/* Note: We used to check for ARM_THUMB9 and ARM_THUMB12. */
else if (howto->type == ARM_THUMB23)
{
- if ( h->class == C_EXT
- || h->class == C_STAT
- || h->class == C_LABEL)
+ if ( h->symbol_class == C_EXT
+ || h->symbol_class == C_STAT
+ || h->symbol_class == C_LABEL)
{
/* Thumb code calling an ARM function. */
asection * s = 0;
bfd_put_32 (output_bfd, h_val,
s->contents + my_offset + 16);
- if (info->base_file)
- arm_emit_base_file_entry (info, output_bfd, s,
- my_offset + 16);
+ if (info->base_file
+ && !arm_emit_base_file_entry (info,
+ output_bfd, s,
+ my_offset + 16))
+ return FALSE;
}
else
{
+ sec->output_offset);
}
- else if (! info->relocatable)
- {
- if (! ((*info->callbacks->undefined_symbol)
- (info, h->root.root.string, input_bfd, input_section,
- rel->r_vaddr - input_section->vma, TRUE)))
- return FALSE;
- }
+ else if (! bfd_link_relocatable (info))
+ (*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma, TRUE);
}
- if (info->base_file)
- {
- /* Emit a reloc if the backend thinks it needs it. */
- if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
- arm_emit_base_file_entry (info, output_bfd, input_section,
- rel->r_vaddr);
- }
+ /* Emit a reloc if the backend thinks it needs it. */
+ if (info->base_file
+ && sym
+ && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)
+ && !arm_emit_base_file_entry (info, output_bfd, input_section,
+ rel->r_vaddr))
+ return FALSE;
if (done)
rstat = bfd_reloc_ok;
#ifndef ARM_WINCE
/* Only perform this fix during the final link, not a relocatable link. */
- else if (! info->relocatable
+ else if (! bfd_link_relocatable (info)
&& howto->type == ARM_THUMB23)
{
/* This is pretty much a copy of what the default
}
#endif
else
- if (info->relocatable && ! howto->partial_inplace)
+ if (bfd_link_relocatable (info) && ! howto->partial_inplace)
rstat = bfd_reloc_ok;
else
rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
rel->r_vaddr - input_section->vma,
val, addend);
/* Only perform this fix during the final link, not a relocatable link. */
- if (! info->relocatable
+ if (! bfd_link_relocatable (info)
&& (rel->r_type == ARM_32 || rel->r_type == ARM_RVA32))
{
/* Determine if we need to set the bottom bit of a relocated address
int patchit = FALSE;
if (h != NULL
- && ( h->class == C_THUMBSTATFUNC
- || h->class == C_THUMBEXTFUNC))
+ && ( h->symbol_class == C_THUMBSTATFUNC
+ || h->symbol_class == C_THUMBEXTFUNC))
{
patchit = TRUE;
}
case bfd_reloc_ok:
break;
case bfd_reloc_outofrange:
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: bad reloc address 0x%lx in section `%A'"),
input_bfd, input_section, (unsigned long) rel->r_vaddr);
return FALSE;
return FALSE;
}
- if (! ((*info->callbacks->reloc_overflow)
- (info, (h ? &h->root : NULL), name, howto->name,
- (bfd_vma) 0, input_bfd, input_section,
- rel->r_vaddr - input_section->vma)))
- return FALSE;
+ (*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma);
}
}
}
/* If we mark it 'thumb', the disassembler will do a better job. */
myh = (struct coff_link_hash_entry *) bh;
- myh->class = C_THUMBEXTFUNC;
+ myh->symbol_class = C_THUMBEXTFUNC;
free (tmp_name);
/* If we are only performing a partial link do not bother
getting a bfd to hold the glue. */
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
globals = coff_arm_hash_table (info);
/* If we are only performing a partial link do not bother
to construct any glue. */
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
return TRUE;
/* Here we have a bfd that is to be included on the link. We have a hook
/* If the index is outside of the range of our table, something has gone wrong. */
if (symndx >= obj_conv_table_size (abfd))
{
+ /* xgettext:c-format */
_bfd_error_handler (_("%B: illegal symbol index in reloc: %d"),
abfd, symndx);
continue;
the target of the call. If it is a thumb target, we
insert glue. */
- if (h->class == C_THUMBEXTFUNC)
+ if (h->symbol_class == C_THUMBEXTFUNC)
record_arm_to_thumb_glue (info, h);
break;
for it. This is not really a problem, since the link
is doomed anyway. */
- switch (h->class)
+ switch (h->symbol_class)
{
case C_EXT:
case C_STAT:
#endif /* ! defined (COFF_IMAGE_WITH_PE) */
#define coff_bfd_reloc_type_lookup coff_arm_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup coff_arm_reloc_name_lookup
#define coff_relocate_section coff_arm_relocate_section
#define coff_bfd_is_local_label_name coff_arm_is_local_label_name
#define coff_adjust_symndx coff_arm_adjust_symndx
targets, eg different CPUs or different APCS's. */
static bfd_boolean
-coff_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+coff_arm_merge_private_bfd_data (bfd * ibfd, struct bfd_link_info *info)
{
+ bfd *obfd = info->output_bfd;
BFD_ASSERT (ibfd != NULL && obfd != NULL);
if (ibfd == obfd)
{
_bfd_error_handler
/* xgettext: c-format */
- (_("ERROR: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"),
+ (_("error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"),
ibfd, obfd,
APCS_26_FLAG (ibfd) ? 26 : 32,
APCS_26_FLAG (obfd) ? 26 : 32
if (APCS_FLOAT_FLAG (obfd) != APCS_FLOAT_FLAG (ibfd))
{
- const char *msg;
-
if (APCS_FLOAT_FLAG (ibfd))
/* xgettext: c-format */
- msg = _("ERROR: %B passes floats in float registers, whereas %B passes them in integer registers");
+ _bfd_error_handler (_("\
+error: %B passes floats in float registers, whereas %B passes them in integer registers"),
+ ibfd, obfd);
else
/* xgettext: c-format */
- msg = _("ERROR: %B passes floats in integer registers, whereas %B passes them in float registers");
-
- _bfd_error_handler (msg, ibfd, obfd);
+ _bfd_error_handler (_("\
+error: %B passes floats in integer registers, whereas %B passes them in float registers"),
+ ibfd, obfd);
bfd_set_error (bfd_error_wrong_format);
return FALSE;
if (PIC_FLAG (obfd) != PIC_FLAG (ibfd))
{
- const char * msg;
-
if (PIC_FLAG (ibfd))
/* xgettext: c-format */
- msg = _("ERROR: %B is compiled as position independent code, whereas target %B is absolute position");
+ _bfd_error_handler (_("\
+error: %B is compiled as position independent code, whereas target %B is absolute position"),
+ ibfd, obfd);
else
/* xgettext: c-format */
- msg = _("ERROR: %B is compiled as absolute position code, whereas target %B is position independent");
- _bfd_error_handler (msg, ibfd, obfd);
+ _bfd_error_handler (_("\
+error: %B is compiled as absolute position code, whereas target %B is position independent"),
+ ibfd, obfd);
bfd_set_error (bfd_error_wrong_format);
return FALSE;
/* If the src and dest differ in their interworking issue a warning. */
if (INTERWORK_FLAG (obfd) != INTERWORK_FLAG (ibfd))
{
- const char * msg;
-
if (INTERWORK_FLAG (ibfd))
/* xgettext: c-format */
- msg = _("Warning: %B supports interworking, whereas %B does not");
+ _bfd_error_handler (_("\
+Warning: %B supports interworking, whereas %B does not"),
+ ibfd, obfd);
else
/* xgettext: c-format */
- msg = _("Warning: %B does not support interworking, whereas %B does");
-
- _bfd_error_handler (msg, ibfd, obfd);
+ _bfd_error_handler (_("\
+Warning: %B does not support interworking, whereas %B does"),
+ ibfd, obfd);
}
}
else
BFD_ASSERT (abfd != NULL && ptr != NULL);
- /* xgettext:c-format */
fprintf (file, _("private flags = %x:"), coff_data (abfd)->flags);
if (APCS_SET (abfd))
if (INTERWORK_SET (abfd) && (INTERWORK_FLAG (abfd) != flag))
{
if (flag)
- /* xgettext: c-format */
_bfd_error_handler (_("Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"),
abfd);
else
- /* xgettext: c-format */
_bfd_error_handler (_("Warning: Clearing the interworking flag of %B due to outside request"),
abfd);
flag = 0;
if (INTERWORK_FLAG (dest))
{
/* xgettext:c-format */
- _bfd_error_handler (("\
+ _bfd_error_handler (_("\
Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"),
dest, src);
}
return bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
}
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
#include "coffcode.h"
#ifndef TARGET_LITTLE_SYM
-#define TARGET_LITTLE_SYM armcoff_little_vec
+#define TARGET_LITTLE_SYM arm_coff_le_vec
#endif
#ifndef TARGET_LITTLE_NAME
#define TARGET_LITTLE_NAME "coff-arm-little"
#endif
#ifndef TARGET_BIG_SYM
-#define TARGET_BIG_SYM armcoff_big_vec
+#define TARGET_BIG_SYM arm_coff_be_vec
#endif
#ifndef TARGET_BIG_NAME
#define TARGET_BIG_NAME "coff-arm-big"