mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-09 21:22:20 +08:00
Fixes for iWMMXt contribution.
This commit is contained in:
@ -1,3 +1,27 @@
|
||||
2003-04-01 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* archures.c (bfd_mach_arm_unknown): Define.
|
||||
* bfd-in.h (bfd_arm_merge_machines, bfd_arm+update_notes,
|
||||
bfd_arm_get_mach_from_notes): Prototype.
|
||||
* bfd-in2.h: Regenerate.
|
||||
* coff-arm.c (coff_arm_merge_private_bfd_data): Call
|
||||
bfd_arm_merge_machines.
|
||||
(coff_arm_final_link_postscript): Call bfd_arm_update_notes.
|
||||
* coffcode.h (coff_set_arch_mach_hook): Call
|
||||
bfd_arm_get_mach_from_notes.
|
||||
* coffgen.c (coff_real_object_p): Revert previous delta.
|
||||
* cpu_arm.c (arm_check_note): New function. Examine a note in a
|
||||
.note section.
|
||||
(bfd_arm_merge_machines): New function: Handle the merging of ARM
|
||||
binaries compiled for different architectures..
|
||||
(bfd_arm_update_notes): New function: Update an ARM note section.
|
||||
(bfd_arm_get_mach_from_notes): New function: Extract a bfd machine
|
||||
number from an ARM note section.
|
||||
* elf32-arm.h (elf32_arm_object_p): Use
|
||||
bfd_arm_get_mach_from_notes.
|
||||
(elf32_arm_merge_private_bfd_data): Use bfd_arm_merge_machines.
|
||||
(elf32_arm_final_write_processing): Use bfd_arm_update_notes.
|
||||
|
||||
2003-04-01 Ben Elliston <bje@wasabisystems.com>
|
||||
|
||||
* dwarf2.c (read_attribute_value): Correct typo in comment.
|
||||
|
@ -224,6 +224,7 @@ DESCRIPTION
|
||||
.#define bfd_mach_alpha_ev5 0x20
|
||||
.#define bfd_mach_alpha_ev6 0x30
|
||||
. bfd_arch_arm, {* Advanced Risc Machines ARM. *}
|
||||
.#define bfd_mach_arm_unknown 0
|
||||
.#define bfd_mach_arm_2 1
|
||||
.#define bfd_mach_arm_2a 2
|
||||
.#define bfd_mach_arm_3 3
|
||||
|
10
bfd/bfd-in.h
10
bfd/bfd-in.h
@ -835,6 +835,16 @@ extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
|
||||
extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
|
||||
/* ARM Note section processing. */
|
||||
extern bfd_boolean bfd_arm_merge_machines
|
||||
PARAMS ((bfd *, bfd *));
|
||||
|
||||
extern bfd_boolean bfd_arm_update_notes
|
||||
PARAMS ((bfd *, const char *));
|
||||
|
||||
extern unsigned int bfd_arm_get_mach_from_notes
|
||||
PARAMS ((bfd *, const char *));
|
||||
|
||||
/* TI COFF load page support. */
|
||||
extern void bfd_ticoff_set_section_load_page
|
||||
PARAMS ((struct sec *, int));
|
||||
|
@ -842,6 +842,16 @@ extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
|
||||
extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
|
||||
/* ARM Note section processing. */
|
||||
extern bfd_boolean bfd_arm_merge_machines
|
||||
PARAMS ((bfd *, bfd *));
|
||||
|
||||
extern bfd_boolean bfd_arm_update_notes
|
||||
PARAMS ((bfd *, const char *));
|
||||
|
||||
extern unsigned int bfd_arm_get_mach_from_notes
|
||||
PARAMS ((bfd *, const char *));
|
||||
|
||||
/* TI COFF load page support. */
|
||||
extern void bfd_ticoff_set_section_load_page
|
||||
PARAMS ((struct sec *, int));
|
||||
@ -1680,6 +1690,7 @@ enum bfd_architecture
|
||||
#define bfd_mach_alpha_ev5 0x20
|
||||
#define bfd_mach_alpha_ev6 0x30
|
||||
bfd_arch_arm, /* Advanced Risc Machines ARM. */
|
||||
#define bfd_mach_arm_unknown 0
|
||||
#define bfd_mach_arm_2 1
|
||||
#define bfd_mach_arm_2a 2
|
||||
#define bfd_mach_arm_3 3
|
||||
|
@ -2240,25 +2240,6 @@ coff_arm_merge_private_bfd_data (ibfd, obfd)
|
||||
if (ibfd == obfd)
|
||||
return TRUE;
|
||||
|
||||
if (bfd_get_mach (obfd) && bfd_get_mach (obfd) != bfd_get_mach (ibfd))
|
||||
{
|
||||
/* For now, allow an output file type of 'xscale' if the
|
||||
input file type is 'iWMMXt'. This means that we will
|
||||
not have to build an entire iWMMXt enabled set of libraries
|
||||
just to test a iWMMXt enabled binary. Change the output
|
||||
type to iWMMXt though. Similarly allow 'xscale' binaries
|
||||
to be linked into a 'iWMMXt' output binary. */
|
||||
if ( bfd_get_mach (obfd) == bfd_mach_arm_XScale
|
||||
&& bfd_get_mach (ibfd) == bfd_mach_arm_iWMMXt)
|
||||
bfd_set_arch_mach (obfd, bfd_get_arch (obfd), bfd_mach_arm_iWMMXt);
|
||||
else if ( bfd_get_mach (ibfd) != bfd_mach_arm_XScale
|
||||
|| bfd_get_mach (obfd) != bfd_mach_arm_iWMMXt)
|
||||
{
|
||||
bfd_set_error (bfd_error_wrong_format);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the two formats are different we cannot merge anything.
|
||||
This is not an error, since it is permissable to change the
|
||||
input and output formats. */
|
||||
@ -2266,7 +2247,12 @@ coff_arm_merge_private_bfd_data (ibfd, obfd)
|
||||
|| obfd->xvec->flavour != bfd_target_coff_flavour)
|
||||
return TRUE;
|
||||
|
||||
/* Verify that the APCS is the same for the two BFDs */
|
||||
/* Determine what should happen if the input ARM architecture
|
||||
does not match the output ARM architecture. */
|
||||
if (! bfd_arm_merge_machines (ibfd, obfd))
|
||||
return FALSE;
|
||||
|
||||
/* Verify that the APCS is the same for the two BFDs. */
|
||||
if (APCS_SET (ibfd))
|
||||
{
|
||||
if (APCS_SET (obfd))
|
||||
@ -2603,45 +2589,7 @@ coff_arm_final_link_postscript (abfd, pfinfo)
|
||||
globals->bfd_of_glue_owner->output_has_begun = TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
asection * arm_arch_section;
|
||||
|
||||
/* Look for a .note section. If one is present check
|
||||
the machine number encoded in it, and set it to the current
|
||||
machine number if it is different. This allows XScale and
|
||||
iWMMXt binaries to be merged and the resulting output to be set
|
||||
to iWMMXt, even if the first input file had an XScale .note. */
|
||||
|
||||
arm_arch_section = bfd_get_section_by_name (abfd, ".note");
|
||||
|
||||
if (arm_arch_section != NULL)
|
||||
{
|
||||
char buffer [4];
|
||||
|
||||
if (bfd_get_section_contents (abfd, arm_arch_section, buffer,
|
||||
(file_ptr) 0, sizeof buffer))
|
||||
{
|
||||
unsigned long arm_mach;
|
||||
|
||||
/* We have to extract the value this way to allow for a
|
||||
host whose endian-ness is different from the target. */
|
||||
arm_mach = bfd_get_32 (abfd, buffer);
|
||||
|
||||
if (arm_mach != bfd_get_mach (abfd))
|
||||
{
|
||||
bfd_put_32 (abfd, bfd_get_mach (abfd), buffer);
|
||||
|
||||
if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
|
||||
(file_ptr) 0, sizeof buffer))
|
||||
(*_bfd_error_handler)
|
||||
(_("warning: unable to update contents of .note section in %s"),
|
||||
bfd_get_filename (abfd));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
|
||||
}
|
||||
|
||||
#include "coffcode.h"
|
||||
|
@ -1883,43 +1883,26 @@ coff_set_arch_mach_hook (abfd, filehdr)
|
||||
case ARMPEMAGIC:
|
||||
case THUMBPEMAGIC:
|
||||
arch = bfd_arch_arm;
|
||||
switch (internal_f->f_flags & F_ARM_ARCHITECTURE_MASK)
|
||||
machine = bfd_arm_get_mach_from_notes (abfd, ARM_NOTE_SECTION);
|
||||
if (machine == bfd_mach_arm_unknown)
|
||||
{
|
||||
case F_ARM_2: machine = bfd_mach_arm_2; break;
|
||||
case F_ARM_2a: machine = bfd_mach_arm_2a; break;
|
||||
case F_ARM_3: machine = bfd_mach_arm_3; break;
|
||||
default:
|
||||
case F_ARM_3M: machine = bfd_mach_arm_3M; break;
|
||||
case F_ARM_4: machine = bfd_mach_arm_4; break;
|
||||
case F_ARM_4T: machine = bfd_mach_arm_4T; break;
|
||||
/* The COFF header does not have enough bits available
|
||||
to cover all the different ARM architectures. So
|
||||
we interpret F_ARM_5, the highest flag value to mean
|
||||
"the highest ARM architecture known to BFD" which is
|
||||
currently the XScale. */
|
||||
case F_ARM_5: machine = bfd_mach_arm_XScale; break;
|
||||
switch (internal_f->f_flags & F_ARM_ARCHITECTURE_MASK)
|
||||
{
|
||||
case F_ARM_2: machine = bfd_mach_arm_2; break;
|
||||
case F_ARM_2a: machine = bfd_mach_arm_2a; break;
|
||||
case F_ARM_3: machine = bfd_mach_arm_3; break;
|
||||
default:
|
||||
case F_ARM_3M: machine = bfd_mach_arm_3M; break;
|
||||
case F_ARM_4: machine = bfd_mach_arm_4; break;
|
||||
case F_ARM_4T: machine = bfd_mach_arm_4T; break;
|
||||
/* The COFF header does not have enough bits available
|
||||
to cover all the different ARM architectures. So
|
||||
we interpret F_ARM_5, the highest flag value to mean
|
||||
"the highest ARM architecture known to BFD" which is
|
||||
currently the XScale. */
|
||||
case F_ARM_5: machine = bfd_mach_arm_XScale; break;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
asection * arm_arch_section;
|
||||
|
||||
arm_arch_section = bfd_get_section_by_name (abfd, ".note");
|
||||
|
||||
if (arm_arch_section)
|
||||
{
|
||||
bfd_byte buffer [4];
|
||||
|
||||
if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
|
||||
(file_ptr) 0, sizeof buffer))
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: warning: unable to retrieve .note section from %s"),
|
||||
bfd_get_filename (abfd));
|
||||
|
||||
/* We have to extract the value this way to allow for a
|
||||
host whose endian-ness is different from the target. */
|
||||
machine = bfd_get_32 (abfd, buffer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef MC68MAGIC
|
||||
|
@ -241,9 +241,6 @@ coff_real_object_p (abfd, nscns, internal_f, internal_a)
|
||||
}
|
||||
}
|
||||
|
||||
bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f);
|
||||
/* make_abs_section (abfd); */
|
||||
|
||||
return abfd->xvec;
|
||||
|
||||
fail:
|
||||
|
278
bfd/cpu-arm.c
278
bfd/cpu-arm.c
@ -1,5 +1,5 @@
|
||||
/* BFD support for the ARM processor
|
||||
Copyright 1994, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
Copyright 1994, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
|
||||
Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
@ -21,11 +21,14 @@
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
#include "libiberty.h"
|
||||
|
||||
static const bfd_arch_info_type * compatible
|
||||
PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *));
|
||||
static bfd_boolean scan
|
||||
PARAMS ((const struct bfd_arch_info *, const char *));
|
||||
static bfd_boolean arm_check_note
|
||||
PARAMS ((bfd *, char *, bfd_size_type, const char *, char **));
|
||||
|
||||
/* This routine is provided two arch_infos and works out which ARM
|
||||
machine which would be compatible with both and returns a pointer
|
||||
@ -149,3 +152,276 @@ static const bfd_arch_info_type arch_info_struct[] =
|
||||
|
||||
const bfd_arch_info_type bfd_arm_arch =
|
||||
N (0, "arm", TRUE, & arch_info_struct[0]);
|
||||
|
||||
/* Support functions used by both the COFF and ELF versions of the ARM port. */
|
||||
|
||||
/* Handle the mergeing of the 'machine' settings of input file IBFD
|
||||
and an output file OBFD. These values actually represent the
|
||||
different possible ARM architecture variants.
|
||||
Returns TRUE if they were merged successfully or FALSE otherwise. */
|
||||
|
||||
bfd_boolean
|
||||
bfd_arm_merge_machines (ibfd, obfd)
|
||||
bfd * ibfd;
|
||||
bfd * obfd;
|
||||
{
|
||||
unsigned int in = bfd_get_mach (ibfd);
|
||||
unsigned int out = bfd_get_mach (obfd);
|
||||
|
||||
/* If the output architecture is unknown, we now have a value to set. */
|
||||
if (out == bfd_mach_arm_unknown)
|
||||
bfd_set_arch_mach (obfd, bfd_arch_arm, in);
|
||||
|
||||
/* If the input architecure is unknown,
|
||||
then so must be the output architecture. */
|
||||
else if (in == bfd_mach_arm_unknown)
|
||||
/* FIXME: We ought to have some way to
|
||||
override this on the command line. */
|
||||
bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown);
|
||||
|
||||
/* If they are the same then nothing needs to be done. */
|
||||
else if (out == in)
|
||||
;
|
||||
|
||||
/* Otherwise the general principle that a earlier architecture can be
|
||||
linked with a later architecure to produce a binary that will execute
|
||||
on the later architecture.
|
||||
|
||||
We fail however if we attempt to link a Cirrus EP9312 binary with an
|
||||
Intel XScale binary, since these architecture have co-processors which
|
||||
will not both be present on the same physical hardware. */
|
||||
else if (in == bfd_mach_arm_ep9312
|
||||
&& (out == bfd_mach_arm_XScale || out == bfd_mach_arm_iWMMXt))
|
||||
{
|
||||
_bfd_error_handler (_("\
|
||||
ERROR: %s is compiled for the EP9312, whereas %s is compiled for XScale"),
|
||||
bfd_archive_filename (ibfd),
|
||||
bfd_get_filename (obfd));
|
||||
bfd_set_error (bfd_error_wrong_format);
|
||||
return FALSE;
|
||||
}
|
||||
else if (out == bfd_mach_arm_ep9312
|
||||
&& (in == bfd_mach_arm_XScale || in == bfd_mach_arm_iWMMXt))
|
||||
{
|
||||
_bfd_error_handler (_("\
|
||||
ERROR: %s is compiled for the EP9312, whereas %s is compiled for XScale"),
|
||||
bfd_archive_filename (obfd),
|
||||
bfd_get_filename (ibfd));
|
||||
bfd_set_error (bfd_error_wrong_format);
|
||||
return FALSE;
|
||||
}
|
||||
else if (in > out)
|
||||
bfd_set_arch_mach (obfd, bfd_arch_arm, in);
|
||||
/* else
|
||||
Nothing to do. */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char namesz[4]; /* Size of entry's owner string. */
|
||||
unsigned char descsz[4]; /* Size of the note descriptor. */
|
||||
unsigned char type[4]; /* Interpretation of the descriptor. */
|
||||
char name[1]; /* Start of the name+desc data. */
|
||||
} arm_Note;
|
||||
|
||||
static bfd_boolean
|
||||
arm_check_note (abfd, buffer, buffer_size, expected_name, description_return)
|
||||
bfd * abfd;
|
||||
char * buffer;
|
||||
bfd_size_type buffer_size;
|
||||
const char * expected_name;
|
||||
char ** description_return;
|
||||
{
|
||||
unsigned long namesz;
|
||||
unsigned long descsz;
|
||||
unsigned long type;
|
||||
char * descr;
|
||||
|
||||
if (buffer_size < offsetof (arm_Note, name))
|
||||
return FALSE;
|
||||
|
||||
/* We have to extract the values this way to allow for a
|
||||
host whose endian-ness is different from the target. */
|
||||
namesz = bfd_get_32 (abfd, buffer);
|
||||
descsz = bfd_get_32 (abfd, buffer + offsetof (arm_Note, descsz));
|
||||
type = bfd_get_32 (abfd, buffer + offsetof (arm_Note, type));
|
||||
descr = buffer + offsetof (arm_Note, name);
|
||||
|
||||
/* Check for buffer overflow. */
|
||||
if (namesz + descsz + offsetof (arm_Note, name) > buffer_size)
|
||||
return FALSE;
|
||||
|
||||
if (expected_name == NULL)
|
||||
{
|
||||
if (namesz != 0)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (namesz != (strlen (expected_name) + 1 + 3) & ~3)
|
||||
return FALSE;
|
||||
|
||||
if (strcmp (descr, expected_name) != 0)
|
||||
return FALSE;
|
||||
|
||||
descr += (namesz + 3) & ~3;
|
||||
}
|
||||
|
||||
/* FIXME: We should probably check the type as well. */
|
||||
|
||||
if (description_return != NULL)
|
||||
* description_return = descr;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define NOTE_ARCH_STRING "arch: "
|
||||
|
||||
bfd_boolean
|
||||
bfd_arm_update_notes (abfd, note_section)
|
||||
bfd * abfd;
|
||||
const char * note_section;
|
||||
{
|
||||
asection * arm_arch_section;
|
||||
bfd_size_type buffer_size;
|
||||
char * buffer;
|
||||
char * arch_string;
|
||||
char * expected;
|
||||
|
||||
/* Look for a note section. If one is present check the architecture
|
||||
string encoded in it, and set it to the current architecture if it is
|
||||
different. */
|
||||
arm_arch_section = bfd_get_section_by_name (abfd, note_section);
|
||||
|
||||
if (arm_arch_section == NULL)
|
||||
return TRUE;
|
||||
|
||||
buffer_size = arm_arch_section->_raw_size;
|
||||
if (buffer_size == 0)
|
||||
return FALSE;
|
||||
|
||||
buffer = bfd_malloc (buffer_size);
|
||||
if (buffer == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
|
||||
(file_ptr) 0, buffer_size))
|
||||
goto FAIL;
|
||||
|
||||
/* Parse the note. */
|
||||
if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
|
||||
goto FAIL;
|
||||
|
||||
/* Check the architecture in the note against the architecture of the bfd. */
|
||||
switch (bfd_get_mach (abfd))
|
||||
{
|
||||
default:
|
||||
case bfd_mach_arm_unknown: expected = "unknown"; break;
|
||||
case bfd_mach_arm_2: expected = "armv2"; break;
|
||||
case bfd_mach_arm_2a: expected = "armv2a"; break;
|
||||
case bfd_mach_arm_3: expected = "armv3"; break;
|
||||
case bfd_mach_arm_3M: expected = "armv3M"; break;
|
||||
case bfd_mach_arm_4: expected = "armv4"; break;
|
||||
case bfd_mach_arm_4T: expected = "armv4t"; break;
|
||||
case bfd_mach_arm_5: expected = "armv5"; break;
|
||||
case bfd_mach_arm_5T: expected = "armv5t"; break;
|
||||
case bfd_mach_arm_5TE: expected = "armv5te"; break;
|
||||
case bfd_mach_arm_XScale: expected = "XScale"; break;
|
||||
case bfd_mach_arm_ep9312: expected = "ep9312"; break;
|
||||
case bfd_mach_arm_iWMMXt: expected = "iWMMXt"; break;
|
||||
}
|
||||
|
||||
if (strcmp (arch_string, expected) != 0)
|
||||
{
|
||||
strcpy (buffer + offsetof (arm_Note, name) + ((strlen (NOTE_ARCH_STRING) + 3) & ~3), expected);
|
||||
|
||||
if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
|
||||
(file_ptr) 0, buffer_size))
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("warning: unable to update contents of %s section in %s"),
|
||||
note_section, bfd_get_filename (abfd));
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
free (buffer);
|
||||
return TRUE;
|
||||
|
||||
FAIL:
|
||||
free (buffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static struct
|
||||
{
|
||||
const char * string;
|
||||
unsigned int mach;
|
||||
}
|
||||
architectures[] =
|
||||
{
|
||||
{ "armv2", bfd_mach_arm_2 },
|
||||
{ "armv2a", bfd_mach_arm_2a },
|
||||
{ "armv3", bfd_mach_arm_3 },
|
||||
{ "armv3M", bfd_mach_arm_3M },
|
||||
{ "armv4", bfd_mach_arm_4 },
|
||||
{ "armv4t", bfd_mach_arm_4T },
|
||||
{ "armv5", bfd_mach_arm_5 },
|
||||
{ "armv5t", bfd_mach_arm_5T },
|
||||
{ "armv5te", bfd_mach_arm_5TE },
|
||||
{ "XScale", bfd_mach_arm_XScale },
|
||||
{ "ep9312", bfd_mach_arm_ep9312 },
|
||||
{ "iWMMXt", bfd_mach_arm_iWMMXt }
|
||||
};
|
||||
|
||||
/* Extract the machine number stored in a note section. */
|
||||
unsigned int
|
||||
bfd_arm_get_mach_from_notes (abfd, note_section)
|
||||
bfd * abfd;
|
||||
const char * note_section;
|
||||
{
|
||||
asection * arm_arch_section;
|
||||
bfd_size_type buffer_size;
|
||||
char * buffer;
|
||||
char * arch_string;
|
||||
int i;
|
||||
|
||||
/* Look for a note section. If one is present check the architecture
|
||||
string encoded in it, and set it to the current architecture if it is
|
||||
different. */
|
||||
arm_arch_section = bfd_get_section_by_name (abfd, note_section);
|
||||
|
||||
if (arm_arch_section == NULL)
|
||||
return bfd_mach_arm_unknown;
|
||||
|
||||
buffer_size = arm_arch_section->_raw_size;
|
||||
if (buffer_size == 0)
|
||||
return bfd_mach_arm_unknown;
|
||||
|
||||
buffer = bfd_malloc (buffer_size);
|
||||
if (buffer == NULL)
|
||||
return bfd_mach_arm_unknown;
|
||||
|
||||
if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
|
||||
(file_ptr) 0, buffer_size))
|
||||
goto FAIL;
|
||||
|
||||
/* Parse the note. */
|
||||
if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
|
||||
goto FAIL;
|
||||
|
||||
/* Interpret the architecture string. */
|
||||
for (i = ARRAY_SIZE (architectures); i--;)
|
||||
if (strcmp (arch_string, architectures[i].string) == 0)
|
||||
{
|
||||
free (buffer);
|
||||
return architectures[i].mach;
|
||||
}
|
||||
|
||||
FAIL:
|
||||
free (buffer);
|
||||
return bfd_mach_arm_unknown;
|
||||
}
|
||||
|
100
bfd/elf32-arm.h
100
bfd/elf32-arm.h
@ -2119,43 +2119,18 @@ static bfd_boolean
|
||||
elf32_arm_object_p (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
asection * arm_arch_section;
|
||||
unsigned int mach;
|
||||
|
||||
mach = bfd_arm_get_mach_from_notes (abfd, ARM_NOTE_SECTION);
|
||||
|
||||
arm_arch_section = bfd_get_section_by_name (abfd, ARM_NOTE_SECTION);
|
||||
if (mach != bfd_mach_arm_unknown)
|
||||
bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach);
|
||||
|
||||
if (arm_arch_section)
|
||||
{
|
||||
char buffer [4];
|
||||
unsigned long arm_mach;
|
||||
else if (elf_elfheader (abfd)->e_flags & EF_ARM_MAVERICK_FLOAT)
|
||||
bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_ep9312);
|
||||
|
||||
if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
|
||||
(file_ptr) 0, sizeof buffer))
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: warning: unable to retrieve %s section from %s"),
|
||||
ARM_NOTE_SECTION, bfd_get_filename (abfd));
|
||||
else
|
||||
{
|
||||
/* We have to extract the value this way to allow for a
|
||||
host whose endian-ness is different from the target. */
|
||||
arm_mach = bfd_get_32 (abfd, buffer);
|
||||
bfd_default_set_arch_mach (abfd, bfd_arch_arm, arm_mach);
|
||||
|
||||
if (bfd_get_arch (abfd) == bfd_arch_arm)
|
||||
return TRUE;
|
||||
|
||||
/* If the set failed for some reason, do not leave the architecture
|
||||
type as 0 (unknown), but issue a warning message and force it to
|
||||
be set to bfd_arch_arm. */
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: warning: unrecognized ARM machine number: %x"),
|
||||
bfd_get_filename (abfd), arm_mach);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (elf_elfheader (abfd)->e_flags & EF_ARM_MAVERICK_FLOAT)
|
||||
bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_ep9312);
|
||||
}
|
||||
bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -2296,24 +2271,10 @@ elf32_arm_merge_private_bfd_data (ibfd, obfd)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (bfd_get_mach (obfd) && bfd_get_mach (obfd) != bfd_get_mach (ibfd))
|
||||
{
|
||||
/* For now, allow an output file type of 'xscale' if the
|
||||
input file type is 'iWMMXt'. This means that we will
|
||||
not have to build an entire iWMMXt enabled set of libraries
|
||||
just to test a iWMMXt enabled binary. Change the output
|
||||
type to iWMMXt though. Similarly allow 'xscale' binaries
|
||||
to be linked into a 'iWMMXt' output binary. */
|
||||
if ( bfd_get_mach (obfd) == bfd_mach_arm_XScale
|
||||
&& bfd_get_mach (ibfd) == bfd_mach_arm_iWMMXt)
|
||||
bfd_set_arch_mach (obfd, bfd_get_arch (obfd), bfd_mach_arm_iWMMXt);
|
||||
else if ( bfd_get_mach (ibfd) != bfd_mach_arm_XScale
|
||||
|| bfd_get_mach (obfd) != bfd_mach_arm_iWMMXt)
|
||||
{
|
||||
bfd_set_error (bfd_error_wrong_format);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* Determine what should happen if the input ARM architecture
|
||||
does not match the output ARM architecture. */
|
||||
if (! bfd_arm_merge_machines (ibfd, obfd))
|
||||
return FALSE;
|
||||
|
||||
/* Identical flags must be compatible. */
|
||||
if (in_flags == out_flags)
|
||||
@ -3733,42 +3694,7 @@ elf32_arm_final_write_processing (abfd, linker)
|
||||
bfd *abfd;
|
||||
bfd_boolean linker ATTRIBUTE_UNUSED;
|
||||
{
|
||||
asection * arm_arch_section;
|
||||
char buffer [4];
|
||||
unsigned long arm_mach;
|
||||
|
||||
/* Look for a .note.arm.ident section. If one is present check
|
||||
the machine number encoded in it, and set it to the current
|
||||
machine number if it is different. This allows XScale and
|
||||
iWMMXt binaries to be merged and the resulting output to be set
|
||||
to iWMMXt, even if the first input file had an XScale .note. */
|
||||
|
||||
arm_arch_section = bfd_get_section_by_name (abfd, ARM_NOTE_SECTION);
|
||||
|
||||
if (arm_arch_section == NULL)
|
||||
return;
|
||||
|
||||
if (! bfd_get_section_contents (abfd, arm_arch_section, buffer,
|
||||
(file_ptr) 0, sizeof buffer))
|
||||
/* If the ident section does not exist then just skip this check. */
|
||||
return;
|
||||
|
||||
/* We have to extract the value this way to allow for a
|
||||
host whose endian-ness is different from the target. */
|
||||
arm_mach = bfd_get_32 (abfd, buffer);
|
||||
|
||||
if (arm_mach == bfd_get_mach (abfd))
|
||||
return;
|
||||
|
||||
bfd_put_32 (abfd, bfd_get_mach (abfd), buffer);
|
||||
|
||||
if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
|
||||
(file_ptr) 0, sizeof buffer))
|
||||
(*_bfd_error_handler)
|
||||
(_("warning: unable to update contents of %s section in %s"),
|
||||
ARM_NOTE_SECTION, bfd_get_filename (abfd));
|
||||
|
||||
return;
|
||||
bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
|
||||
}
|
||||
|
||||
#define ELF_ARCH bfd_arch_arm
|
||||
|
Reference in New Issue
Block a user