+Tue May 26 19:37:47 1998 Stan Cox <scox@equinox.cygnus.com>
+
+ * elf32-sparc.c (_bfd_sparc_elf_howto_table, sparc_reloc_map,
+ elf32_sparc_relocate_section): Added R_SPARC_32LE for little
+ endian data 32 bit relocations.
+ (elf32_sparc_merge_private_bfd_data): Check if linking little
+ endian objects with big endian objects.
+ (elf32_sparc_object_p): Set bfd_mach_sparc_sparclite_le.
+ (elf32_sparc_final_write_processing): Set EF_SPARC_LEDATA in e_flags.
+
+ * libbfd.h (bfd_reloc_code_real_names): Added BFD_RELOC_SPARC_32LE.
+ * reloc.c: Same.
+
+ * cpu-sparc.c (arch_info_struct): Added sparc:sparclite_le
+
+ * archures.c (bfd_mach_sparc_sparclite_le): New.
+
Thu May 21 16:59:28 1998 Nick Clifton <nickc@cygnus.com>
* peicode.h (add_data_entry): Fix precedence of operators in if ()
extern int target_big_endian;
+static int target_little_endian_data;
+
/* V9 and 86x have big and little endian data, but instructions are always big
endian. The sparclet has bi-endian support but both data and insns have
the same endianness. Global `target_big_endian' is used for data.
#endif
#define OPTION_ENFORCE_ALIGNED_DATA (OPTION_MD_BASE + 10)
{"enforce-aligned-data", no_argument, NULL, OPTION_ENFORCE_ALIGNED_DATA},
+#define OPTION_LITTLE_ENDIAN_DATA (OPTION_MD_BASE + 11)
+ {"little-endian-data", no_argument, NULL, OPTION_LITTLE_ENDIAN_DATA},
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof(md_longopts);
#ifdef SPARC_BIENDIAN
case OPTION_LITTLE_ENDIAN:
+ target_big_endian = 0;
+ if (default_arch_type != sparclet)
+ as_fatal ("This target does not support -EL");
+ break;
+ case OPTION_LITTLE_ENDIAN_DATA:
+ target_little_endian_data = 1;
target_big_endian = 0;
if (default_arch_type != sparc86x
- && default_arch_type != sparclet
&& default_arch_type != v9)
- as_fatal ("This target does not support -EL");
+ as_fatal ("This target does not support --little-endian-data");
break;
case OPTION_BIG_ENDIAN:
target_big_endian = 1;
#ifdef SPARC_BIENDIAN
fprintf (stream, _("\
-EL generate code for a little endian machine\n\
--EB generate code for a big endian machine\n"));
+-EB generate code for a big endian machine\n\
+--little-endian-data generate code for a machine having big endian
+ instructions and little endian data."));
#endif
}
\f
bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_v8plusa);
else if (current_architecture == SPARC_OPCODE_ARCH_SPARCLET)
bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_sparclet);
+ else if (default_arch_type == sparc86x && target_little_endian_data)
+ bfd_set_arch_mach (stdoutput, bfd_arch_sparc, bfd_mach_sparc_sparclite_le);
else
{
/* The sparclite is treated like a normal sparc. Perhaps it shouldn't
{
md_number_to_chars (buf, val, 2);
}
- else if (fixP->fx_r_type == BFD_RELOC_32)
+ else if (fixP->fx_r_type == BFD_RELOC_32
+ || fixP->fx_r_type == BFD_RELOC_SPARC_32LE)
{
md_number_to_chars (buf, val, 4);
}
case BFD_RELOC_SPARC_L44:
case BFD_RELOC_SPARC_HIX22:
case BFD_RELOC_SPARC_LOX10:
+ case BFD_RELOC_SPARC_32LE:
code = fixp->fx_r_type;
break;
default:
elf_elfheader (stdoutput)->e_flags |= EF_SPARC_SUN_US1;
}
#endif
+
+/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
+ reloc for a cons. We could use the definition there, except that
+ we want to handle little endian relocs specially. */
+
+void
+cons_fix_new_sparc (frag, where, nbytes, exp)
+ fragS *frag;
+ int where;
+ unsigned int nbytes;
+ expressionS *exp;
+{
+ bfd_reloc_code_real_type r;
+
+ r = (nbytes == 1 ? BFD_RELOC_8 :
+ (nbytes == 2 ? BFD_RELOC_16 :
+ (nbytes == 4 ? BFD_RELOC_32 : BFD_RELOC_64)));
+
+#ifdef OBJ_ELF
+ if (target_little_endian_data && nbytes == 4)
+ r = BFD_RELOC_SPARC_32LE;
+#endif
+ fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
+}