bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

OCTETS_PER_BYTE and Gas


From: Dan
Subject: OCTETS_PER_BYTE and Gas
Date: Fri, 05 Feb 2016 12:09:55 -0500

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
reply via email to

[Prev in Thread] Current Thread [Next in Thread]