Remove the artificial limit on code alignment through the use of the
authorDr Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Thu, 30 Oct 2014 10:53:09 +0000 (10:53 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 30 Oct 2014 10:53:09 +0000 (10:53 +0000)
fixed part of a fragment for output generation only, which required
MAX_MEM_FOR_RS_ALIGN_CODE to be large enough to hold the maximum pad.

* config/tc-aarch64.h (MAX_MEM_FOR_RS_ALIGN_CODE): Define to 7.
* config/tc-aarch64.c (aarch64_handle_align): Rewrite to handle
large alignments with a constant fragment size of
MAX_MEM_FOR_RS_ALIGN_CODE.

gas/ChangeLog
gas/config/tc-aarch64.c
gas/config/tc-aarch64.h

index a7bd4c3414797640548d80386c7fc5be3b164b4a..8ca1cc132f9e3d8764fa5cf75f61eeef3f8c6113 100644 (file)
@@ -1,3 +1,10 @@
+2014-10-30  Dr Philipp Tomsich  <philipp.tomsich@theobroma-systems.com>
+
+       * config/tc-aarch64.h (MAX_MEM_FOR_RS_ALIGN_CODE): Define to 7.
+       * config/tc-aarch64.c (aarch64_handle_align): Rewrite to handle
+       large alignments with a constant fragment size of
+       MAX_MEM_FOR_RS_ALIGN_CODE.
+
 2014-10-29  Nick Clifton  <nickc@redhat.com>
 
        * po/uk.po: New Ukranian translation.
index 7483f30fc1a68d7cc717e65c55c9f3a9017a8c93..9d5e1d9c79eed86fcd17735e5a47f0aa71880566 100644 (file)
@@ -5825,7 +5825,24 @@ md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
 }
 
 /* This is called from HANDLE_ALIGN in write.c.         Fill in the contents
-   of an rs_align_code fragment.  */
+   of an rs_align_code fragment.
+
+   Here we fill the frag with the appropriate info for padding the
+   output stream.  The resulting frag will consist of a fixed (fr_fix)
+   and of a repeating (fr_var) part.
+
+   The fixed content is always emitted before the repeating content and
+   these two parts are used as follows in constructing the output:
+   - the fixed part will be used to align to a valid instruction word
+     boundary, in case that we start at a misaligned address; as no
+     executable instruction can live at the misaligned location, we
+     simply fill with zeros;
+   - the variable part will be used to cover the remaining padding and
+     we fill using the AArch64 NOP instruction.
+
+   Note that the size of a RS_ALIGN_CODE fragment is always 7 to provide
+   enough storage space for up to 3 bytes for padding the back to a valid
+   instruction alignment and exactly 4 bytes to store the NOP pattern.  */
 
 void
 aarch64_handle_align (fragS * fragP)
@@ -5836,69 +5853,33 @@ aarch64_handle_align (fragS * fragP)
 
   int bytes, fix, noop_size;
   char *p;
-  const char *noop;
 
   if (fragP->fr_type != rs_align_code)
     return;
 
   bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
   p = fragP->fr_literal + fragP->fr_fix;
-  fix = 0;
-
-  if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
-    bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
 
 #ifdef OBJ_ELF
   gas_assert (fragP->tc_frag_data.recorded);
 #endif
 
-  noop = aarch64_noop;
   noop_size = sizeof (aarch64_noop);
-  fragP->fr_var = noop_size;
 
-  if (bytes & (noop_size - 1))
+  fix = bytes & (noop_size - 1);
+  if (fix)
     {
-      fix = bytes & (noop_size - 1);
 #ifdef OBJ_ELF
       insert_data_mapping_symbol (MAP_INSN, fragP->fr_fix, fragP, fix);
 #endif
       memset (p, 0, fix);
       p += fix;
-      bytes -= fix;
-    }
-
-  while (bytes >= noop_size)
-    {
-      memcpy (p, noop, noop_size);
-      p += noop_size;
-      bytes -= noop_size;
-      fix += noop_size;
+      fragP->fr_fix += fix;
     }
 
-  fragP->fr_fix += fix;
-}
-
-/* Called from md_do_align.  Used to create an alignment
-   frag in a code section.  */
-
-void
-aarch64_frag_align_code (int n, int max)
-{
-  char *p;
-
-  /* We assume that there will never be a requirement
-     to support alignments greater than x bytes.  */
-  if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
-    as_fatal (_
-             ("alignments greater than %d bytes not supported in .text sections"),
-             MAX_MEM_FOR_RS_ALIGN_CODE + 1);
-
-  p = frag_var (rs_align_code,
-               MAX_MEM_FOR_RS_ALIGN_CODE,
-               1,
-               (relax_substateT) max,
-               (symbolS *) NULL, (offsetT) n, (char *) NULL);
-  *p = 0;
+  if (noop_size)
+    memcpy (p, aarch64_noop, noop_size);
+  fragP->fr_var = noop_size;
 }
 
 /* Perform target specific initialisation of a frag.
index 3d4ffc57c6f7e8b88c70ea0f8c6fc35129587742..1fad6ce58b67f7594d58bc8a2aa27f6c5ff6a40c 100644 (file)
@@ -116,8 +116,9 @@ void aarch64_copy_symbol_attributes (symbolS *, symbolS *);
 
 #define TC_CONS_FIX_NEW(f,w,s,e,r) cons_fix_new_aarch64 ((f), (w), (s), (e))
 
-/* Max code alignment is 32 bytes */
-#define MAX_MEM_FOR_RS_ALIGN_CODE 31
+/* Max space for a rs_align_code fragment is 3 unaligned bytes
+   (fr_fix) plus 4 bytes to contain the repeating NOP (fr_var).  */
+#define MAX_MEM_FOR_RS_ALIGN_CODE 7
 
 /* For frags in code sections we need to record whether they contain
    code or data.  */
@@ -141,7 +142,7 @@ struct aarch64_frag_type
 #define md_do_align(N, FILL, LEN, MAX, LABEL)                                  \
   if (FILL == NULL && (N) != 0 && ! need_pass_2 && subseg_text_p (now_seg))    \
     {                                                                          \
-      aarch64_frag_align_code (N, MAX);                                                \
+      frag_align_code (N, MAX);                                                        \
       goto LABEL;                                                              \
     }