Line 1... |
Line 1... |
/* BFD back-end for ARM COFF files.
|
/* BFD back-end for ARM COFF files.
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
Written by Cygnus Support.
|
Written by Cygnus Support.
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
|
|
Line 1330... |
Line 1330... |
+ h_sec->output_section->vma
|
+ h_sec->output_section->vma
|
+ h_sec->output_offset);
|
+ h_sec->output_offset);
|
|
|
if (howto->type == ARM_26)
|
if (howto->type == ARM_26)
|
{
|
{
|
if ( h->class == C_THUMBSTATFUNC
|
if ( h->symbol_class == C_THUMBSTATFUNC
|
|| h->class == C_THUMBEXTFUNC)
|
|| h->symbol_class == C_THUMBEXTFUNC)
|
{
|
{
|
/* Arm code calling a Thumb function. */
|
/* Arm code calling a Thumb function. */
|
unsigned long int tmp;
|
unsigned long int tmp;
|
bfd_vma my_offset;
|
bfd_vma my_offset;
|
asection * s;
|
asection * s;
|
Line 1417... |
Line 1417... |
|
|
#ifndef ARM_WINCE
|
#ifndef ARM_WINCE
|
/* Note: We used to check for ARM_THUMB9 and ARM_THUMB12. */
|
/* Note: We used to check for ARM_THUMB9 and ARM_THUMB12. */
|
else if (howto->type == ARM_THUMB23)
|
else if (howto->type == ARM_THUMB23)
|
{
|
{
|
if ( h->class == C_EXT
|
if ( h->symbol_class == C_EXT
|
|| h->class == C_STAT
|
|| h->symbol_class == C_STAT
|
|| h->class == C_LABEL)
|
|| h->symbol_class == C_LABEL)
|
{
|
{
|
/* Thumb code calling an ARM function. */
|
/* Thumb code calling an ARM function. */
|
asection * s = 0;
|
asection * s = 0;
|
bfd_vma my_offset;
|
bfd_vma my_offset;
|
unsigned long int tmp;
|
unsigned long int tmp;
|
Line 1719... |
Line 1719... |
/* Determine if we need to set the bottom bit of a relocated address
|
/* Determine if we need to set the bottom bit of a relocated address
|
because the address is the address of a Thumb code symbol. */
|
because the address is the address of a Thumb code symbol. */
|
int patchit = FALSE;
|
int patchit = FALSE;
|
|
|
if (h != NULL
|
if (h != NULL
|
&& ( h->class == C_THUMBSTATFUNC
|
&& ( h->symbol_class == C_THUMBSTATFUNC
|
|| h->class == C_THUMBEXTFUNC))
|
|| h->symbol_class == C_THUMBEXTFUNC))
|
{
|
{
|
patchit = TRUE;
|
patchit = TRUE;
|
}
|
}
|
else if (sym != NULL
|
else if (sym != NULL
|
&& sym->n_scnum > N_UNDEF)
|
&& sym->n_scnum > N_UNDEF)
|
Line 1930... |
Line 1930... |
bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
|
bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
|
BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh);
|
BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh);
|
|
|
/* If we mark it 'thumb', the disassembler will do a better job. */
|
/* If we mark it 'thumb', the disassembler will do a better job. */
|
myh = (struct coff_link_hash_entry *) bh;
|
myh = (struct coff_link_hash_entry *) bh;
|
myh->class = C_THUMBEXTFUNC;
|
myh->symbol_class = C_THUMBEXTFUNC;
|
|
|
free (tmp_name);
|
free (tmp_name);
|
|
|
/* Allocate another symbol to mark where we switch to arm mode. */
|
/* Allocate another symbol to mark where we switch to arm mode. */
|
|
|
Line 2094... |
Line 2094... |
case ARM_26:
|
case ARM_26:
|
/* This one is a call from arm code. We need to look up
|
/* This one is a call from arm code. We need to look up
|
the target of the call. If it is a thumb target, we
|
the target of the call. If it is a thumb target, we
|
insert glue. */
|
insert glue. */
|
|
|
if (h->class == C_THUMBEXTFUNC)
|
if (h->symbol_class == C_THUMBEXTFUNC)
|
record_arm_to_thumb_glue (info, h);
|
record_arm_to_thumb_glue (info, h);
|
break;
|
break;
|
|
|
#ifndef ARM_WINCE
|
#ifndef ARM_WINCE
|
case ARM_THUMB23:
|
case ARM_THUMB23:
|
Line 2108... |
Line 2108... |
insert glue. If the symbol does not exist it will be
|
insert glue. If the symbol does not exist it will be
|
given a class of C_EXT and so we will generate a stub
|
given a class of C_EXT and so we will generate a stub
|
for it. This is not really a problem, since the link
|
for it. This is not really a problem, since the link
|
is doomed anyway. */
|
is doomed anyway. */
|
|
|
switch (h->class)
|
switch (h->symbol_class)
|
{
|
{
|
case C_EXT:
|
case C_EXT:
|
case C_STAT:
|
case C_STAT:
|
case C_LABEL:
|
case C_LABEL:
|
record_thumb_to_arm_glue (info, h);
|
record_thumb_to_arm_glue (info, h);
|
Line 2206... |
Line 2206... |
/* If the src and dest have different APCS flag bits set, fail. */
|
/* If the src and dest have different APCS flag bits set, fail. */
|
if (APCS_26_FLAG (obfd) != APCS_26_FLAG (ibfd))
|
if (APCS_26_FLAG (obfd) != APCS_26_FLAG (ibfd))
|
{
|
{
|
_bfd_error_handler
|
_bfd_error_handler
|
/* xgettext: c-format */
|
/* 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,
|
ibfd, obfd,
|
APCS_26_FLAG (ibfd) ? 26 : 32,
|
APCS_26_FLAG (ibfd) ? 26 : 32,
|
APCS_26_FLAG (obfd) ? 26 : 32
|
APCS_26_FLAG (obfd) ? 26 : 32
|
);
|
);
|
|
|
Line 2222... |
Line 2222... |
{
|
{
|
const char *msg;
|
const char *msg;
|
|
|
if (APCS_FLOAT_FLAG (ibfd))
|
if (APCS_FLOAT_FLAG (ibfd))
|
/* xgettext: c-format */
|
/* xgettext: c-format */
|
msg = _("ERROR: %B passes floats in float registers, whereas %B passes them in integer registers");
|
msg = _("error: %B passes floats in float registers, whereas %B passes them in integer registers");
|
else
|
else
|
/* xgettext: c-format */
|
/* xgettext: c-format */
|
msg = _("ERROR: %B passes floats in integer registers, whereas %B passes them in float registers");
|
msg = _("error: %B passes floats in integer registers, whereas %B passes them in float registers");
|
|
|
_bfd_error_handler (msg, ibfd, obfd);
|
_bfd_error_handler (msg, ibfd, obfd);
|
|
|
bfd_set_error (bfd_error_wrong_format);
|
bfd_set_error (bfd_error_wrong_format);
|
return FALSE;
|
return FALSE;
|
Line 2239... |
Line 2239... |
{
|
{
|
const char * msg;
|
const char * msg;
|
|
|
if (PIC_FLAG (ibfd))
|
if (PIC_FLAG (ibfd))
|
/* xgettext: c-format */
|
/* xgettext: c-format */
|
msg = _("ERROR: %B is compiled as position independent code, whereas target %B is absolute position");
|
msg = _("error: %B is compiled as position independent code, whereas target %B is absolute position");
|
else
|
else
|
/* xgettext: c-format */
|
/* xgettext: c-format */
|
msg = _("ERROR: %B is compiled as absolute position code, whereas target %B is position independent");
|
msg = _("error: %B is compiled as absolute position code, whereas target %B is position independent");
|
_bfd_error_handler (msg, ibfd, obfd);
|
_bfd_error_handler (msg, ibfd, obfd);
|
|
|
bfd_set_error (bfd_error_wrong_format);
|
bfd_set_error (bfd_error_wrong_format);
|
return FALSE;
|
return FALSE;
|
}
|
}
|
Line 2526... |
Line 2526... |
}
|
}
|
|
|
return bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
|
return bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
|
}
|
}
|
|
|
|
#ifndef bfd_pe_print_pdata
|
|
#define bfd_pe_print_pdata NULL
|
|
#endif
|
|
|
#include "coffcode.h"
|
#include "coffcode.h"
|
|
|
#ifndef TARGET_LITTLE_SYM
|
#ifndef TARGET_LITTLE_SYM
|
#define TARGET_LITTLE_SYM armcoff_little_vec
|
#define TARGET_LITTLE_SYM armcoff_little_vec
|
#endif
|
#endif
|