aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2003-04-01 13:08:06 +0000
committerNick Clifton <nickc@redhat.com>2003-04-01 13:08:06 +0000
commit5a6c681789fe44d0cfb3a3839aeb8a1060842c1f (patch)
tree71caa9c0f02720bfa21b4b77fcee77ef59cbdc22 /bfd
parent49634642a549784aaa0d26c1442a2580b697f49b (diff)
downloadgdb-5a6c681789fe44d0cfb3a3839aeb8a1060842c1f.zip
gdb-5a6c681789fe44d0cfb3a3839aeb8a1060842c1f.tar.gz
gdb-5a6c681789fe44d0cfb3a3839aeb8a1060842c1f.tar.bz2
Fixes for iWMMXt contribution.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog24
-rw-r--r--bfd/archures.c1
-rw-r--r--bfd/bfd-in.h10
-rw-r--r--bfd/bfd-in2.h11
-rw-r--r--bfd/coff-arm.c66
-rw-r--r--bfd/coffcode.h53
-rw-r--r--bfd/coffgen.c3
-rw-r--r--bfd/cpu-arm.c278
-rw-r--r--bfd/elf32-arm.h102
9 files changed, 362 insertions, 186 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 786e939..8ea9e6e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/archures.c b/bfd/archures.c
index 18ebb83..28e27df 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -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
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 917b46f..c39bfedd 100644
--- a/bfd/bfd-in.h
+++ b/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));
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 51e2a21..d15bcda 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c
index 2401504..f089a6c 100644
--- a/bfd/coff-arm.c
+++ b/bfd/coff-arm.c
@@ -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"
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index da8121f..5c6c286 100644
--- a/bfd/coffcode.h
+++ b/bfd/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
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index a3e3eec..fcb00fc 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -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:
diff --git a/bfd/cpu-arm.c b/bfd/cpu-arm.c
index eb3011d..66c3a46 100644
--- a/bfd/cpu-arm.c
+++ b/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;
+}
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h
index 417284b..631b2b9 100644
--- a/bfd/elf32-arm.h
+++ b/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);
+
+ 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 (arm_arch_section)
- {
- char buffer [4];
- unsigned long arm_mach;
-
- 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