PATCH: Fix .lsb/.msb

H. J. Lu hjl@lucon.org
Wed Apr 30 21:01:00 GMT 2003


On Wed, Apr 30, 2003 at 12:43:19PM -0400, Jim Wilson wrote:
> 
> > But the whole .lsb/.msb directives are broken. 
> > I am working on a patch for that.
> 

Here is the patch. It depends on

http://sources.redhat.com/ml/binutils/2003-04/msg00644.html


H.J.
-------------- next part --------------
gas/

2003-04-30  H.J. Lu <hjl@gnu.org>

	* config/tc-ia64.c (ia64_number_to_chars): New function pointer.
	(ia64_float_to_chars): Likewise.
	(dot_byteorder): Set target_big_endian, ia64_number_to_chars
	and ia64_float_to_chars by tc_segment_info_data.endian from
	the current segment if byteorder == -1.
	(md_begin): Call dot_byteorder to set target_big_endian.
	(md_atof): Call ia64_float_to_chars to convert floating point.
	(ia64_float_to_chars_bigendian): New function.
	(ia64_float_to_chars_littleendian): Likewise.
	(ia64_elf_section_change_hook): Likewise.

	* config/tc-ia64.h (ia64_number_to_chars): New.
	(md_number_to_chars): Changed to (*ia64_number_to_chars)
	(ia64_elf_section_change_hook): New.
	(md_elf_section_change_hook): Defined.
	(ia64_segment_info_type): New struct.
	(TC_SEGMENT_INFO_TYPE): Defined.
	.
gas/testsuite/

2003-04-30  H.J. Lu <hjl@gnu.org>

	* gas/ia64/ia64.exp: Add order.

	* gas/ia64/order.s: New file.
	* gas/ia64/order.d: Likewise.

--- gas/config/tc-ia64.c.order	2003-04-30 12:57:43.000000000 -0700
+++ gas/config/tc-ia64.c	2003-04-30 13:53:11.000000000 -0700
@@ -156,6 +156,15 @@ struct label_fix
 
 extern int target_big_endian;
 
+void (*ia64_number_to_chars) PARAMS ((char *, valueT, int));
+
+static void ia64_float_to_chars_bigendian
+  PARAMS ((char *, LITTLENUM_TYPE *, int));
+static void ia64_float_to_chars_littleendian
+  PARAMS ((char *, LITTLENUM_TYPE *, int));
+static void (*ia64_float_to_chars)
+  PARAMS ((char *, LITTLENUM_TYPE *, int));
+
 /* Characters which always start a comment.  */
 const char comment_chars[] = "";
 
@@ -4315,7 +4324,32 @@ static void
 dot_byteorder (byteorder)
      int byteorder;
 {
-  target_big_endian = byteorder;
+  segment_info_type *seginfo = seg_info (now_seg);
+
+  if (byteorder == -1)
+    {
+      if (seginfo->tc_segment_info_data.endian == 0)
+	seginfo->tc_segment_info_data.endian
+	  = TARGET_BYTES_BIG_ENDIAN ? 1 : 2;
+      byteorder = seginfo->tc_segment_info_data.endian == 1;
+    }
+  else
+    seginfo->tc_segment_info_data.endian = byteorder ? 1 : 2;
+
+  if (target_big_endian != byteorder)
+    {
+      target_big_endian = byteorder;
+      if (target_big_endian)
+	{
+	  ia64_number_to_chars = number_to_chars_bigendian;
+	  ia64_float_to_chars = ia64_float_to_chars_bigendian;
+	}
+      else
+	{
+	  ia64_number_to_chars = number_to_chars_littleendian;
+	  ia64_float_to_chars = ia64_float_to_chars_littleendian;
+	}
+    }
 }
 
 static void
@@ -6542,7 +6576,10 @@ md_begin ()
 
   bfd_set_section_alignment (stdoutput, text_section, 4);
 
-  target_big_endian = TARGET_BYTES_BIG_ENDIAN;
+  /* Make sure fucntion pointers get initialized.  */
+  target_big_endian = -1;
+  dot_byteorder (TARGET_BYTES_BIG_ENDIAN);
+
   pseudo_func[FUNC_DTP_MODULE].u.sym =
     symbol_new (".<dtpmod>", undefined_section, FUNC_DTP_MODULE,
 		&zero_address_frag);
@@ -10561,7 +10598,6 @@ md_atof (type, lit, size)
      int *size;
 {
   LITTLENUM_TYPE words[MAX_LITTLENUMS];
-  LITTLENUM_TYPE *word;
   char *t;
   int prec;
 
@@ -10596,19 +10632,18 @@ md_atof (type, lit, size)
   t = atof_ieee (input_line_pointer, type, words);
   if (t)
     input_line_pointer = t;
-  *size = prec * sizeof (LITTLENUM_TYPE);
 
-  for (word = words + prec - 1; prec--;)
-    {
-      md_number_to_chars (lit, (long) (*word--), sizeof (LITTLENUM_TYPE));
-      lit += sizeof (LITTLENUM_TYPE);
-    }
+  (*ia64_float_to_chars) (lit, words, prec);
+
   if (type == 'X')
     {
       /* It is 10 byte floating point with 6 byte padding.  */
-      memset (lit, 0, 6);
+      memset (&lit [10], 0, 6);
       *size = 8 * sizeof (LITTLENUM_TYPE);
     }
+  else
+    *size = prec * sizeof (LITTLENUM_TYPE);
+
   return 0;
 }
 
@@ -10686,3 +10721,33 @@ ia64_check_label (symbolS *label)
       input_line_pointer++;
     }
 }
+
+static void
+ia64_float_to_chars_bigendian (char *lit, LITTLENUM_TYPE *words,
+			       int prec)
+{
+  while (prec--)
+    {
+      number_to_chars_bigendian (lit, (long) (*words++),
+				 sizeof (LITTLENUM_TYPE));
+      lit += sizeof (LITTLENUM_TYPE);
+    }
+}
+
+static void
+ia64_float_to_chars_littleendian (char *lit, LITTLENUM_TYPE *words,
+				  int prec)
+{
+  while (prec--)
+    {
+      number_to_chars_littleendian (lit, (long) (words[prec]),
+				    sizeof (LITTLENUM_TYPE));
+      lit += sizeof (LITTLENUM_TYPE);
+    }
+}
+
+void
+ia64_elf_section_change_hook  (void)
+{
+  dot_byteorder (-1);
+}
--- gas/config/tc-ia64.h.order	2003-04-30 12:57:43.000000000 -0700
+++ gas/config/tc-ia64.h	2003-04-30 13:53:11.000000000 -0700
@@ -26,15 +26,28 @@
 
 /* Linux is little endian by default.  HPUX is big endian by default.  */
 #ifdef TE_HPUX
-#define md_number_to_chars		number_to_chars_bigendian
 #define TARGET_BYTES_BIG_ENDIAN		1
 #define MD_FLAGS_DEFAULT		EF_IA_64_BE
 #else
-#define md_number_to_chars		number_to_chars_littleendian
 #define TARGET_BYTES_BIG_ENDIAN		0
 #define MD_FLAGS_DEFAULT		EF_IA_64_ABI64
 #endif /* TE_HPUX */
 
+extern void (*ia64_number_to_chars) PARAMS ((char *, valueT, int));
+#define md_number_to_chars		(*ia64_number_to_chars)
+
+extern void ia64_elf_section_change_hook PARAMS ((void));
+#define md_elf_section_change_hook	ia64_elf_section_change_hook
+
+/* We record the endian for this section. 0 means default, 1 means
+   big endian and 2 means little endian.  */
+struct ia64_segment_info_type
+{
+  unsigned int endian : 2;
+};
+
+#define TC_SEGMENT_INFO_TYPE		struct ia64_segment_info_type
+
 /* We need to set the default object file format in ia64_init and not in
    md_begin.  This is because parse_args is called before md_begin, and we
    do not want md_begin to wipe out the flag settings set by options parsed in
--- gas/testsuite/gas/ia64/ia64.exp.order	2003-04-30 12:57:43.000000000 -0700
+++ gas/testsuite/gas/ia64/ia64.exp	2003-04-30 13:53:11.000000000 -0700
@@ -46,4 +46,5 @@ if [istarget "ia64-*"] then {
     run_dump_test "secname"
     run_dump_test "global"
     run_dump_test "real"
+    run_dump_test "order"
 }
--- gas/testsuite/gas/ia64/order.d.order	2003-04-30 12:57:43.000000000 -0700
+++ gas/testsuite/gas/ia64/order.d	2003-04-30 13:49:42.000000000 -0700
@@ -0,0 +1,36 @@
+#objdump: -j .foo -j .bar -rs
+#name: ia64 byte order
+
+.*: +file format .*
+
+RELOCATION RECORDS FOR \[.foo\]:
+OFFSET           TYPE              VALUE 
+0000000000000008 DIR64MSB          foo
+0000000000000018 DIR64MSB          foo
+0000000000000028 DIR64LSB          foo
+0000000000000038 DIR64LSB          foo
+
+
+RELOCATION RECORDS FOR \[.bar\]:
+OFFSET           TYPE              VALUE 
+0000000000000010 DIR64LSB          foo
+0000000000000040 DIR64LSB          foo
+0000000000000058 DIR64MSB          foo
+0000000000000080 DIR64MSB          foo
+
+
+Contents of section .foo:
+ 0000 12340000 12345678 00000000 00000000  ................
+ 0010 01234567 89abcdef 00000000 00000000  ................
+ 0020 34120000 78563412 00000000 00000000  ................
+ 0030 efcdab89 67452301 00000000 00000000  ................
+Contents of section .bar:
+ 0000 cdcccc3d 00000000 9a999999 9999c93f  ................
+ 0010 00000000 00000000 00000000 00000000  ................
+ 0020 cdcccccc cccccccc fd3f0000 00000000  ................
+ 0030 cdcccccc cccccccc fe3f0000 00000000  ................
+ 0040 00000000 00000000 3dcccccd 00000000  ................
+ 0050 3fc99999 9999999a 00000000 00000000  ................
+ 0060 3ffdcccc cccccccc cccd0000 00000000  ................
+ 0070 3ffecccc cccccccc cccd0000 00000000  ................
+ 0080 00000000 00000000                    ........        
--- gas/testsuite/gas/ia64/order.s.order	2003-04-30 12:57:43.000000000 -0700
+++ gas/testsuite/gas/ia64/order.s	2003-04-30 13:46:56.000000000 -0700
@@ -0,0 +1,37 @@
+	.global foo#
+	.section .foo,"aw","progbits"
+	.msb
+	data2 0x1234
+	data4 0x12345678
+	data8 foo#
+	.section .bar,"aw","progbits"
+	.lsb
+	real4 0.1
+	real8 0.2
+	data8 foo#
+	.section .foo,"aw","progbits"
+	data8 0x123456789abcdef
+//	data16 0x123456789abcdef
+	data8 foo#
+	.section .bar,"aw","progbits"
+	real10 0.4
+	real16 0.8
+	data8 foo#
+	.section .foo,"aw","progbits"
+	.lsb
+	data2 0x1234
+	data4 0x12345678
+	data8 foo#
+	.section .bar,"aw","progbits"
+	.msb
+	real4 0.1
+	real8 0.2
+	data8 foo#
+	.section .foo,"aw","progbits"
+	data8 0x123456789abcdef
+//	data16 0x123456789abcdef
+	data8 foo#
+	.section .bar,"aw","progbits"
+	real10 0.4
+	real16 0.8
+	data8 foo#


More information about the Binutils mailing list