aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorDr Philipp Tomsich <philipp.tomsich@theobroma-systems.com>2014-10-30 10:53:09 +0000
committerNick Clifton <nickc@redhat.com>2014-10-30 10:53:09 +0000
commitf803aa8eadb24ea7152057584c47648fb02e4716 (patch)
tree21f2c7a08b5e6faa1dac08dc88eb14e89ef4ea2e /gas
parent76ca31c09f629e670ffd57e79c0604db7ddecc9e (diff)
downloadgdb-f803aa8eadb24ea7152057584c47648fb02e4716.zip
gdb-f803aa8eadb24ea7152057584c47648fb02e4716.tar.gz
gdb-f803aa8eadb24ea7152057584c47648fb02e4716.tar.bz2
Remove the artificial limit on code alignment through the use of the
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.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-aarch64.c67
-rw-r--r--gas/config/tc-aarch64.h7
3 files changed, 35 insertions, 46 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index a7bd4c3..8ca1cc1 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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.
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 7483f30..9d5e1d9 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -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.
diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h
index 3d4ffc5..1fad6ce 100644
--- a/gas/config/tc-aarch64.h
+++ b/gas/config/tc-aarch64.h
@@ -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; \
}