diff options
author | Nick Clifton <nickc@redhat.com> | 2003-04-01 13:08:06 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2003-04-01 13:08:06 +0000 |
commit | 5a6c681789fe44d0cfb3a3839aeb8a1060842c1f (patch) | |
tree | 71caa9c0f02720bfa21b4b77fcee77ef59cbdc22 /bfd | |
parent | 49634642a549784aaa0d26c1442a2580b697f49b (diff) | |
download | gdb-5a6c681789fe44d0cfb3a3839aeb8a1060842c1f.zip gdb-5a6c681789fe44d0cfb3a3839aeb8a1060842c1f.tar.gz gdb-5a6c681789fe44d0cfb3a3839aeb8a1060842c1f.tar.bz2 |
Fixes for iWMMXt contribution.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 24 | ||||
-rw-r--r-- | bfd/archures.c | 1 | ||||
-rw-r--r-- | bfd/bfd-in.h | 10 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 11 | ||||
-rw-r--r-- | bfd/coff-arm.c | 66 | ||||
-rw-r--r-- | bfd/coffcode.h | 53 | ||||
-rw-r--r-- | bfd/coffgen.c | 3 | ||||
-rw-r--r-- | bfd/cpu-arm.c | 278 | ||||
-rw-r--r-- | bfd/elf32-arm.h | 102 |
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 |