aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2019-07-01 08:24:57 +0200
committerJan Beulich <jbeulich@suse.com>2019-07-01 08:24:57 +0200
commit9c33702be70a7db648414775faa4850e7cf53034 (patch)
tree98134d3f024fc2aace411ec6e89a32d50116aa23 /gas/config
parent36cc073ef40f2cb9cb834cdb5d543fbb284f2b32 (diff)
downloadgdb-9c33702be70a7db648414775faa4850e7cf53034.zip
gdb-9c33702be70a7db648414775faa4850e7cf53034.tar.gz
gdb-9c33702be70a7db648414775faa4850e7cf53034.tar.bz2
x86: warn about insns exceeding the 15-byte limit
Such insns will cause #UD when an attempt to execute them is made. See also http://www.sandpile.org/x86/opc_enc.htm.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-i386.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 4e55188..84c4bc5 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -8123,6 +8123,25 @@ x86_cleanup (void)
}
#endif
+static unsigned int
+encoding_length (const fragS *start_frag, offsetT start_off,
+ const char *frag_now_ptr)
+{
+ unsigned int len = 0;
+
+ if (start_frag != frag_now)
+ {
+ const fragS *fr = start_frag;
+
+ do {
+ len += fr->fr_fix;
+ fr = fr->fr_next;
+ } while (fr && fr != frag_now);
+ }
+
+ return len - start_off + (frag_now_ptr - frag_now->fr_literal);
+}
+
static void
output_insn (void)
{
@@ -8400,6 +8419,19 @@ output_insn (void)
if (i.imm_operands)
output_imm (insn_start_frag, insn_start_off);
+
+ /*
+ * frag_now_fix () returning plain abs_section_offset when we're in the
+ * absolute section, and abs_section_offset not getting updated as data
+ * gets added to the frag breaks the logic below.
+ */
+ if (now_seg != absolute_section)
+ {
+ j = encoding_length (insn_start_frag, insn_start_off, frag_more (0));
+ if (j > 15)
+ as_warn (_("instruction length of %u bytes exceeds the limit of 15"),
+ j);
+ }
}
#ifdef DEBUG386