aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2001-04-26 15:19:21 +0000
committerNick Clifton <nickc@redhat.com>2001-04-26 15:19:21 +0000
commit16a0c2d4eced24ba71a9df4e764819941af5df83 (patch)
tree095b99dd18e2365da217e6bf4f64d1486251e25e
parent5ec3e74e112f12b369e671a0a147402736955a64 (diff)
downloadgdb-16a0c2d4eced24ba71a9df4e764819941af5df83.zip
gdb-16a0c2d4eced24ba71a9df4e764819941af5df83.tar.gz
gdb-16a0c2d4eced24ba71a9df4e764819941af5df83.tar.bz2
Add ability to pad code alignment frags with no-ops.
-rw-r--r--gas/ChangeLog13
-rw-r--r--gas/config/tc-arm.c96
-rw-r--r--gas/config/tc-arm.h18
3 files changed, 127 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 6bdaec0..4354980 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,16 @@
+2001-04-26 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/tc-arm.c (arm_handle_align): New Function: Generate
+ no-op filled alignment frags.
+ (arm_frag_align_code): New Function: Create a code alignment frag.
+ (arm_init_frag): New Function: Initialse the target dependent
+ parts of a frag.
+
+ * config/tc-arm.h (TC_FRAG_TYPE): Define.
+ (TC_FRAG_INIT): Define.
+ (HANDLE_ALIGN): Define.
+ (md_do_align): Define.
+
2001-04-25 Nick Clifton <nickc@cambridge.redhat.com>
* config/obj-coff.c (do_linenos_for): Check to see if the filename
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index e5f0c13..ec51229 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -8780,3 +8780,99 @@ s_arm_elf_cons (nbytes)
}
#endif /* OBJ_ELF */
+
+/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
+ of an rs_align_code fragment. */
+
+void
+arm_handle_align (fragp)
+ fragS *fragp;
+{
+ static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
+ static char const thumb_noop[2] = { 0xc0, 0x46 };
+ static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
+ static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
+
+ 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 (fragp->tc_frag_data)
+ {
+ if (target_big_endian)
+ noop = thumb_bigend_noop;
+ else
+ noop = thumb_noop;
+ noop_size = sizeof (thumb_noop);
+ }
+ else
+ {
+ if (target_big_endian)
+ noop = arm_bigend_noop;
+ else
+ noop = arm_noop;
+ noop_size = sizeof (arm_noop);
+ }
+
+ if (bytes & (noop_size - 1))
+ {
+ fix = bytes & (noop_size - 1);
+ 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_var = noop_size;
+}
+
+/* Called from md_do_align. Used to create an alignment
+ frag in a code section. */
+
+void
+arm_frag_align_code (n, max)
+ int n;
+ int max;
+{
+ char * p;
+
+ /* We assume that there will never be a requirment
+ to support alignments greater than 32 bytes. */
+ if (max > 31)
+ as_fatal (_("alignments in code section > 32 not supported."));
+
+ p = frag_var (rs_align_code,
+ 31,
+ 1,
+ (relax_substateT) max,
+ (symbolS *) NULL,
+ (offsetT) n,
+ (char *) NULL);
+ *p = 0;
+
+}
+
+/* Perform target specific initialisation of a frag. */
+
+void
+arm_init_frag (fragp)
+ fragS *fragp;
+{
+ /* Record whether this frag is in an ARM or a THUMB area. */
+ fragp->tc_frag_data = thumb_mode;
+}
diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h
index 7060333..f955c44 100644
--- a/gas/config/tc-arm.h
+++ b/gas/config/tc-arm.h
@@ -214,3 +214,21 @@ void armelf_frob_symbol PARAMS ((symbolS *, int *));
#ifdef OBJ_ELF
#define DWARF2_LINE_MIN_INSN_LENGTH 2
#endif
+
+/* For frags in code sections we need to record whether they contain
+ ARM code or THUMB code. This is that if they have to be aligned,
+ they can contain the correct type of no-op instruction. */
+#define TC_FRAG_TYPE int
+#define TC_FRAG_INIT(fragp) arm_init_frag (fragp)
+extern void arm_init_frag PARAMS ((struct frag *));
+
+#define HANDLE_ALIGN(fragp) arm_handle_align (fragp)
+extern void arm_handle_align PARAMS ((struct frag *));
+
+#define md_do_align(N, FILL, LEN, MAX, LABEL) \
+ if (FILL == NULL && (N) != 0 && ! need_pass_2 && subseg_text_p (now_seg)) \
+ { \
+ arm_frag_align_code (N, MAX); \
+ goto LABEL; \
+ }
+extern void arm_frag_align_code PARAMS ((int, int));