diff options
author | Nick Clifton <nickc@redhat.com> | 2001-04-26 15:19:21 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2001-04-26 15:19:21 +0000 |
commit | 16a0c2d4eced24ba71a9df4e764819941af5df83 (patch) | |
tree | 095b99dd18e2365da217e6bf4f64d1486251e25e /gas | |
parent | 5ec3e74e112f12b369e671a0a147402736955a64 (diff) | |
download | gdb-16a0c2d4eced24ba71a9df4e764819941af5df83.zip gdb-16a0c2d4eced24ba71a9df4e764819941af5df83.tar.gz gdb-16a0c2d4eced24ba71a9df4e764819941af5df83.tar.bz2 |
Add ability to pad code alignment frags with no-ops.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 13 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 96 | ||||
-rw-r--r-- | gas/config/tc-arm.h | 18 |
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)); |