To those who maintain the GNU assembler, thank you.

I am currently working on a back-end implementation of the assembler to
an embedded system where OCTETS_PER_BYTE=4.  From a C standpoint, you
might think of it as a system where sizeof(char)==sizeof(int), and both
are 32-bits.

The embedded system is quite minimal in its support, therefore I don't
expect to run the assembler from the embedded system itself.  I'm just
building a cross-assembler to support this target from an i86_64
machine.  

The assembler support structure provided by the GNU assembler has worked
quite well for this circumstance, with only a couple minor changes that
I would like to propose.  Without these changes, the assembler would
crash with some strange bugs.  Therefore, I thought I'd push these
upstream.

Admittedly, my full implementation requires lots of other changes
elsewhere, such as in the testsuite, configuration files, and more.
These changes, though, should be applicable to anyone else working in
this type of situation.

Below is the diff for gas/read.c:

--- binutils-2.25-original/gas/read.c   2014-10-14 03:32:03.000000000
-0400
+++ binutils-2.25/gas/read.c    2016-02-05 06:48:11.911995367 -0500
@@ -684,7 +684,8 @@
   /* We do this every time rather than just in s_bundle_align_mode
      so that we catch any affected section without needing hooks all
      over for all paths that do section changes.  It's cheap enough.
*/
-  record_alignment (now_seg, bundle_align_p2 - OCTETS_PER_BYTE_POWER);
+  if (bundle_align_p2 > OCTETS_PER_BYTE_POWER)
+    record_alignment (now_seg, bundle_align_p2 -
OCTETS_PER_BYTE_POWER);
 }
 
 /* Assemble one instruction.  This takes care of the bundle features
@@ -1394,6 +1395,9 @@
 static void
 do_align (int n, char *fill, int len, int max)
 {
+  if (n < OCTETS_PER_BYTE_POWER)
+    n = OCTETS_PER_BYTE_POWER;
+
   if (now_seg == absolute_section)
     {
       if (fill != NULL)
@@ -1415,7 +1419,7 @@
 #endif
 
   /* Only make a frag if we HAVE to...  */
-  if (n != 0 && !need_pass_2)
+  if ((n >= OCTETS_PER_BYTE_POWER) && !need_pass_2)
     {
       if (fill == NULL)
        {
@@ -1434,7 +1438,8 @@
  just_record_alignment: ATTRIBUTE_UNUSED_LABEL
 #endif
 
-  record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
+  if (n > OCTETS_PER_BYTE_POWER)
+    record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
 }
 
 /* Handle the .align pseudo-op.  A positive ARG is a default alignment
@@ -4927,6 +4932,8 @@
   while (!(((value == 0) && ((byte & 0x40) == 0))
           || ((value == -1) && ((byte & 0x40) != 0))));
 
+  if (OCTETS_PER_BYTE_POWER > 0)
+    size = (size +
(1<<OCTETS_PER_BYTE_POWER))&((~0)<<OCTETS_PER_BYTE_POWER);
   return size;
 }
 
@@ -4942,6 +4949,8 @@
     }
   while (value != 0);
 
+  if (OCTETS_PER_BYTE_POWER > 0)
+    size = (size +
(1<<OCTETS_PER_BYTE_POWER))&((~0)<<OCTETS_PER_BYTE_POWER);
   return size;
 }
 
@@ -4960,7 +4969,7 @@
 output_sleb128 (char *p, offsetT value)
 {
   char *orig = p;
-  int more;
+  int more, size;
 
   do
     {
@@ -4980,13 +4989,17 @@
     }
   while (more);
 
-  return p - orig;
+  size = p - orig;
+  if (OCTETS_PER_BYTE_POWER > 0)
+    size = (size +
(1<<OCTETS_PER_BYTE_POWER))&((~0)<<OCTETS_PER_BYTE_POWER);
+  return size;
 }
 
 static inline int
 output_uleb128 (char *p, valueT value)
 {
   char *orig = p;
+  int size;
 
   do
     {
@@ -5000,7 +5013,10 @@
     }
   while (value != 0);
 
-  return p - orig;
+  size = p - orig;
+  if (OCTETS_PER_BYTE_POWER > 0)
+    size = (size +
(1<<OCTETS_PER_BYTE_POWER))&((~0)<<OCTETS_PER_BYTE_POWER);
+  return size;
 }
 
 int
_______________________________________________
bug-binutils mailing list
bug-binutils@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-binutils

Reply via email to