This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] bfd/elfxx-target.h and rx: multi-targets ?


This patch is in two parts; the first (elfxx-target.h) part I'm asking
about, the RX part goes along with it if the first part is OK.

The problem here is that big-endian RX has a different on-disk format
than in-memory, with conversions during get/set section memory.
However, this breaks objcopy when one of the two formats is not
elf-rx, such as srec, where the in-memory format is written to disk,
not the on-disk format.  The patch adds a third RX target that does
not do the swap, so that the in-memory format matches the on-disk
format and the srec/ihex output is "correct".  The user could then
choose the non-swapping target via -I.

However, I need to modify elfxx-target.h to allow multiple inclusion,
in order to define more than the two common targets.  Is that part OK?

	* elfxx-target.h: Protect elfNN_bed against multiple
	definition.

	* config.bfd: Add bfd_elf32_rx_be_ns_vec.
	* target.c: Likewise.
	* configure.in: Likewise.
	* configure.in: Regenerate.
	* elf32-rx.c: Add elf32-rx-be-ns target.
	(rx_elf_object_p): Never allow the be-ns target by default,
	only allow it if the user requests it.

Index: bfd/elfxx-target.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-target.h,v
retrieving revision 1.124
diff -p -U5 -r1.124  bfd/elfxx-target.h
--- bfd/elfxx-target.h	4 Nov 2010 11:35:01 -0000	1.124
+++ bfd/elfxx-target.h	1 Jun 2011 21:07:37 -0000
@@ -643,10 +643,17 @@
 #define elf_backend_is_function_type _bfd_elf_is_function_type
 #endif
 
 extern const struct elf_size_info _bfd_elfNN_size_info;
 
+/* It is possible for a target to include this header twice, providing
+   it's careful about the differences between the two inclusions, as
+   long as we only define this static variable once.  See elf32-rx.c
+   for an example.  */
+#ifndef ELFNN_BED_DEFINED
+#define ELFNN_BED_DEFINED 1
+
 static struct elf_backend_data elfNN_bed =
 {
   ELF_ARCH,			/* arch */
   ELF_TARGET_ID,		/* target_id */
   ELF_MACHINE_CODE,		/* elf_machine_code */
@@ -765,10 +772,12 @@ static struct elf_backend_data elfNN_bed
   elf_backend_want_dynbss,
   elf_backend_want_p_paddr_set_to_zero,
   elf_backend_default_execstack
 };
 
+#endif /* ELFNN_BED_DEFINED */
+
 /* Forward declaration for use when initialising alternative_target field.  */
 #ifdef TARGET_LITTLE_SYM
 extern const bfd_target TARGET_LITTLE_SYM;
 #endif
 


Index: bfd/config.bfd
===================================================================
RCS file: /cvs/src/src/bfd/config.bfd,v
retrieving revision 1.280
diff -p -U5 -r1.280  bfd/config.bfd
--- bfd/config.bfd	13 May 2011 18:15:29 -0000	1.280
+++ bfd/config.bfd	1 Jun 2011 21:07:33 -0000
@@ -1187,11 +1187,11 @@ case "${targ}" in
     targ_selvecs="bfd_powerpcle_pei_vec bfd_powerpc_pei_vec bfd_powerpcle_pe_vec bfd_powerpc_pe_vec"
     ;;
 
   rx-*-elf)
     targ_defvec=bfd_elf32_rx_le_vec
-    targ_selvecs="bfd_elf32_rx_be_vec bfd_elf32_rx_le_vec"
+    targ_selvecs="bfd_elf32_rx_be_vec bfd_elf32_rx_le_vec bfd_elf32_rx_be_ns_vec"
     ;;
 
   s390-*-linux*)
     targ_defvec=bfd_elf32_s390_vec
     targ64_selvecs=bfd_elf64_s390_vec
Index: bfd/configure.in
===================================================================
RCS file: /cvs/src/src/bfd/configure.in,v
retrieving revision 1.294
diff -p -U5 -r1.294  bfd/configure.in
--- bfd/configure.in	25 May 2011 12:02:16 -0000	1.294
+++ bfd/configure.in	1 Jun 2011 21:07:37 -0000
@@ -761,10 +761,11 @@ do
     bfd_elf32_powerpc_vec)	tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_powerpcle_vec)	tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_powerpc_vxworks_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_rx_le_vec)        tb="$tb elf32-rx.lo elf32.lo $elf" ;;
     bfd_elf32_rx_be_vec)        tb="$tb elf32-rx.lo elf32.lo $elf" ;;
+    bfd_elf32_rx_be_ns_vec)     tb="$tb elf32-rx.lo elf32.lo $elf" ;;
     bfd_elf32_s390_vec)		tb="$tb elf32-s390.lo elf32.lo $elf" ;;
     bfd_elf32_bigscore_vec)     tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64;;
     bfd_elf32_littlescore_vec)  tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64;;
     # FIXME: We include cofflink.lo not because it's needed for
     # bfd_elf32_sh64[l]_vec, but because we include bfd_elf32_sh[l]_vec
Index: bfd/elf32-rx.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-rx.c,v
retrieving revision 1.11
diff -p -U5 -r1.11  bfd/elf32-rx.c
--- bfd/elf32-rx.c	23 May 2011 19:50:19 -0000	1.11
+++ bfd/elf32-rx.c	1 Jun 2011 21:07:37 -0000
@@ -26,10 +26,15 @@
 #include "elf/rx.h"
 #include "libiberty.h"
 
 #define RX_OPCODE_BIG_ENDIAN 0
 
+/* This is a meta-target that's used only with objcopy, to avoid the
+   endian-swap we would otherwise get.  We check for this in
+   rx_elf_object_p().  */
+const bfd_target bfd_elf32_rx_be_ns_vec;
+
 #ifdef DEBUG
 char * rx_get_reloc (long);
 void rx_dump_symtab (bfd *, void *, void *);
 #endif
 
@@ -2958,10 +2963,17 @@ rx_elf_object_p (bfd * abfd)
   unsigned int u;
   Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr;
   int nphdrs = elf_elfheader (abfd)->e_phnum;
   sec_ptr bsec;
 
+  /* We never want to automatically choose the non-swapping big-endian
+     target.  The user can only get that explicitly, such as with -I
+     and objcopy.  */
+  if (abfd->xvec == &bfd_elf32_rx_be_ns_vec
+      && abfd->target_defaulted)
+    return FALSE;
+
   bfd_default_set_arch_mach (abfd, bfd_arch_rx,
 			     elf32_rx_machine (abfd));
 
   /* For each PHDR in the object, we must find some section that
      corresponds (based on matching file offsets) and use its VMA
@@ -3434,5 +3446,21 @@ elf32_rx_modify_program_headers (bfd * a
 #define bfd_elf32_set_section_contents		rx_set_section_contents
 #define bfd_elf32_bfd_final_link		rx_final_link
 #define bfd_elf32_bfd_relax_section		elf32_rx_relax_section_wrapper
 
 #include "elf32-target.h"
+
+/* We define a second big-endian target that doesn't have the custom
+   section get/set hooks, for times when we want to preserve the
+   pre-swapped .text sections (like objcopy).  */
+
+#undef  TARGET_BIG_SYM
+#define TARGET_BIG_SYM		bfd_elf32_rx_be_ns_vec
+#undef  TARGET_BIG_NAME
+#define TARGET_BIG_NAME		"elf32-rx-be-ns"
+#undef  TARGET_LITTLE_SYM
+
+#undef bfd_elf32_get_section_contents
+#undef bfd_elf32_set_section_contents
+
+
+#include "elf32-target.h"
Index: bfd/targets.c
===================================================================
RCS file: /cvs/src/src/bfd/targets.c,v
retrieving revision 1.199
diff -p -U5 -r1.199  bfd/targets.c
--- bfd/targets.c	13 May 2011 18:15:32 -0000	1.199
+++ bfd/targets.c	1 Jun 2011 21:07:37 -0000
@@ -655,10 +655,11 @@ extern const bfd_target bfd_elf32_pjl_ve
 extern const bfd_target bfd_elf32_powerpc_vec;
 extern const bfd_target bfd_elf32_powerpcle_vec;
 extern const bfd_target bfd_elf32_powerpc_vxworks_vec;
 extern const bfd_target bfd_elf32_rx_le_vec;
 extern const bfd_target bfd_elf32_rx_be_vec;
+extern const bfd_target bfd_elf32_rx_be_ns_vec;
 extern const bfd_target bfd_elf32_s390_vec;
 extern const bfd_target bfd_elf32_bigscore_vec;
 extern const bfd_target bfd_elf32_littlescore_vec;
 extern const bfd_target bfd_elf32_sh64_vec;
 extern const bfd_target bfd_elf32_sh64l_vec;
@@ -1012,10 +1013,11 @@ static const bfd_target * const _bfd_tar
 	&bfd_elf32_pjl_vec,
 	&bfd_elf32_powerpc_vec,
 	&bfd_elf32_powerpc_vxworks_vec,
 	&bfd_elf32_powerpcle_vec,
 	&bfd_elf32_rx_be_vec,
+	&bfd_elf32_rx_be_ns_vec,
 	&bfd_elf32_rx_le_vec,
 	&bfd_elf32_s390_vec,
 #ifdef BFD64
 	&bfd_elf32_bigscore_vec,
 	&bfd_elf32_littlescore_vec,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]