diff options
author | Nick Clifton <nickc@redhat.com> | 2003-03-25 20:56:01 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2003-03-25 20:56:01 +0000 |
commit | e16bb312f5bec8b2305f400898523122a6fdad63 (patch) | |
tree | d38f34bda5d46ce027935e978a6b0ce042cc5b3c /bfd | |
parent | 4183d8120459822e219461c82c295e7571eee4f5 (diff) | |
download | gdb-e16bb312f5bec8b2305f400898523122a6fdad63.zip gdb-e16bb312f5bec8b2305f400898523122a6fdad63.tar.gz gdb-e16bb312f5bec8b2305f400898523122a6fdad63.tar.bz2 |
Add iWMMXt support
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 23 | ||||
-rw-r--r-- | bfd/archures.c | 1 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 2 | ||||
-rw-r--r-- | bfd/coff-arm.c | 57 | ||||
-rw-r--r-- | bfd/coffcode.h | 21 | ||||
-rw-r--r-- | bfd/coffgen.c | 3 | ||||
-rw-r--r-- | bfd/cpu-arm.c | 6 | ||||
-rw-r--r-- | bfd/elf32-arm.h | 119 | ||||
-rw-r--r-- | bfd/libbfd.h | 1 | ||||
-rw-r--r-- | bfd/reloc.c | 2 |
10 files changed, 229 insertions, 6 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index e0f41fd..a29b48a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,26 @@ +2003-03-25 Stan Cox <scox@redhat.com> + Nick Clifton <nickc@redhat.com> + + Contribute support for Intel's iWMMXt chip - an ARM variant: + + * archures.c: Add bfd_mach_arm_iWMMXt. + * reloc.c: Add BFD_RELOC_ARM_CP_OFF_IMM_S2. + * bfd-in2.h: Regenerate. + * libbfd.h: Regenerate. + * coff-arm.c (coff_arm_merge_private_bfd_data): Allow iWMMXt + object files to be linked with XScale ones. + (coff_arm_final_link_postscript): Update note section. + * coffcode.h (coff_set_arch_mach_hook): Handle note section. + * coffgen.c (coff_real_object_p): Call bfd_coff_set_arch_mach_hook + after identifying a coff binary. + * cpu-arm.c (processors): Add iWMMXt. + (arch_inf): Likewise. + * elf32-arm.h (arm_object_p): Handle note section. + (elf32_arm_merge_private_bfd_data): Allow iWMMXt object files to + be linked with XScale ones. + (elf32_arm_section_flags): New function: Set flags on note section. + (elf32_arm_final_write_processing): Handle note section. + 2003-03-21 DJ Delorie <dj@redhat.com> * elf32-xstormy16.c (elf32_xstormy16_relocate_section): Call diff --git a/bfd/archures.c b/bfd/archures.c index 62edda1..18ebb83 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -235,6 +235,7 @@ DESCRIPTION .#define bfd_mach_arm_5TE 9 .#define bfd_mach_arm_XScale 10 .#define bfd_mach_arm_ep9312 11 +.#define bfd_mach_arm_iWMMXt 12 . bfd_arch_ns32k, {* National Semiconductors ns32000 *} . bfd_arch_w65, {* WDC 65816 *} . bfd_arch_tic30, {* Texas Instruments TMS320C30 *} diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 2385c40..8960f66 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1691,6 +1691,7 @@ enum bfd_architecture #define bfd_mach_arm_5TE 9 #define bfd_mach_arm_XScale 10 #define bfd_mach_arm_ep9312 11 +#define bfd_mach_arm_iWMMXt 12 bfd_arch_ns32k, /* National Semiconductors ns32000 */ bfd_arch_w65, /* WDC 65816 */ bfd_arch_tic30, /* Texas Instruments TMS320C30 */ @@ -2563,6 +2564,7 @@ field in the instruction. */ BFD_RELOC_ARM_SWI, BFD_RELOC_ARM_MULTI, BFD_RELOC_ARM_CP_OFF_IMM, + BFD_RELOC_ARM_CP_OFF_IMM_S2, BFD_RELOC_ARM_ADR_IMM, BFD_RELOC_ARM_LDR_IMM, BFD_RELOC_ARM_LITERAL, diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index 2fadcbe..2401504 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -2240,6 +2240,25 @@ 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. */ @@ -2584,6 +2603,44 @@ 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; } diff --git a/bfd/coffcode.h b/bfd/coffcode.h index ee50a10..da8121f 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -1899,6 +1899,27 @@ coff_set_arch_mach_hook (abfd, filehdr) 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 c905ab1..a3e3eec 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -226,7 +226,7 @@ coff_real_object_p (abfd, nscns, internal_f, internal_a) if (! bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f)) goto fail; - /* Now copy data as required; construct all asections etc */ + /* Now copy data as required; construct all asections etc. */ if (nscns != 0) { unsigned int i; @@ -241,6 +241,7 @@ 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; diff --git a/bfd/cpu-arm.c b/bfd/cpu-arm.c index 923c250..eb3011d 100644 --- a/bfd/cpu-arm.c +++ b/bfd/cpu-arm.c @@ -96,7 +96,8 @@ processors[] = { bfd_mach_arm_4, "strongarm110" }, { bfd_mach_arm_4, "strongarm1100" }, { bfd_mach_arm_XScale, "xscale" }, - { bfd_mach_arm_ep9312, "ep9312" } + { bfd_mach_arm_ep9312, "ep9312" }, + { bfd_mach_arm_iWMMXt, "iwmmxt" } }; static bfd_boolean @@ -142,7 +143,8 @@ static const bfd_arch_info_type arch_info_struct[] = N (bfd_mach_arm_5T, "armv5t", FALSE, & arch_info_struct[8]), N (bfd_mach_arm_5TE, "armv5te", FALSE, & arch_info_struct[9]), N (bfd_mach_arm_XScale, "xscale", FALSE, & arch_info_struct[10]), - N (bfd_mach_arm_ep9312, "ep9312", FALSE, NULL) + N (bfd_mach_arm_ep9312, "ep9312", FALSE, & arch_info_struct[11]), + N (bfd_mach_arm_iWMMXt,"iwmmxt", FALSE, NULL) }; const bfd_arch_info_type bfd_arm_arch = diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index 509b481..417284b 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -2119,10 +2119,43 @@ static bfd_boolean elf32_arm_object_p (abfd) bfd *abfd; { - /* XXX - we ought to examine a .note section here. */ + asection * arm_arch_section; - if (elf_elfheader (abfd)->e_flags & EF_ARM_MAVERICK_FLOAT) - bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_ep9312); + arm_arch_section = bfd_get_section_by_name (abfd, ARM_NOTE_SECTION); + + 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); + } return TRUE; } @@ -2263,6 +2296,25 @@ 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; + } + } + /* Identical flags must be compatible. */ if (in_flags == out_flags) return TRUE; @@ -3660,6 +3712,65 @@ elf32_arm_reloc_type_class (rela) } } +static bfd_boolean elf32_arm_section_flags PARAMS ((flagword *, Elf_Internal_Shdr *)); +static void elf32_arm_final_write_processing PARAMS ((bfd *, bfd_boolean)); + +/* Set the right machine number for an Arm ELF file. */ + +static bfd_boolean +elf32_arm_section_flags (flags, hdr) + flagword *flags; + Elf_Internal_Shdr *hdr; +{ + if (hdr->sh_type == SHT_NOTE) + *flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_CONTENTS; + + return TRUE; +} + +void +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; +} + #define ELF_ARCH bfd_arch_arm #define ELF_MACHINE_CODE EM_ARM #define ELF_MAXPAGESIZE 0x8000 @@ -3685,6 +3796,8 @@ elf32_arm_reloc_type_class (rela) #define elf_backend_post_process_headers elf32_arm_post_process_headers #define elf_backend_reloc_type_class elf32_arm_reloc_type_class #define elf_backend_object_p elf32_arm_object_p +#define elf_backend_section_flags elf32_arm_section_flags +#define elf_backend_final_write_processing elf32_arm_final_write_processing #define elf_backend_can_gc_sections 1 #define elf_backend_plt_readonly 1 diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 222b23d..df2ba3e 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1043,6 +1043,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_ARM_SWI", "BFD_RELOC_ARM_MULTI", "BFD_RELOC_ARM_CP_OFF_IMM", + "BFD_RELOC_ARM_CP_OFF_IMM_S2", "BFD_RELOC_ARM_ADR_IMM", "BFD_RELOC_ARM_LDR_IMM", "BFD_RELOC_ARM_LITERAL", diff --git a/bfd/reloc.c b/bfd/reloc.c index 9f8a952..f4a3321 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2519,6 +2519,8 @@ ENUMX ENUMX BFD_RELOC_ARM_CP_OFF_IMM ENUMX + BFD_RELOC_ARM_CP_OFF_IMM_S2 +ENUMX BFD_RELOC_ARM_ADR_IMM ENUMX BFD_RELOC_ARM_LDR_IMM |