summaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2003-03-25 20:56:01 +0000
committerNick Clifton <nickc@redhat.com>2003-03-25 20:56:01 +0000
commit5dc4c049c7a27688aeb3904c4e800c2020e02d93 (patch)
treec80b586ba7b2ea734cdb8f82753ee8634a545988 /bfd
parent4eb6360e89ca91dfd449364b146c2040db1ad01f (diff)
downloadbinutils-redhat-5dc4c049c7a27688aeb3904c4e800c2020e02d93.tar.gz
Add iWMMXt support
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog23
-rw-r--r--bfd/archures.c1
-rw-r--r--bfd/bfd-in2.h2
-rw-r--r--bfd/coff-arm.c57
-rw-r--r--bfd/coffcode.h21
-rw-r--r--bfd/coffgen.c3
-rw-r--r--bfd/cpu-arm.c6
-rw-r--r--bfd/elf32-arm.h119
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/reloc.c2
10 files changed, 229 insertions, 6 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e0f41fda6e..a29b48ace4 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 62edda109b..18ebb83511 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 2385c409a5..8960f66df3 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 2fadcbef55..2401504982 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 ee50a10993..da8121fd77 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 c905ab17ee..a3e3eecb41 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 923c2500af..eb3011d7d2 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 509b481557..417284b316 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 222b23dcb5..df2ba3e3f9 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 9f8a952c59..f4a3321802 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