x86: disassembling over-long insns
authorJan Beulich <jbeulich@suse.com>
Fri, 26 May 2023 07:53:25 +0000 (09:53 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 26 May 2023 07:53:25 +0000 (09:53 +0200)
The present way of dealing with them - misusing MAX_MNEM_SIZE, which has
nothing to do with insn length - leads to inconsistent results. Since we
allow for up to MAX_CODE_LENGTH - 1 prefix bytes (which then could be
followed by another MAX_CODE_LENGTH "normal" insn bytes until we're done
decoding), size the_buffer[] accordingly.

Move struct dis_private down to be able to use MAX_CODE_LENGTH without
moving its #define. While doing this also alter the order to have the
potentially large array last.

opcodes/i386-dis.c

index 398be8b20c5df2c0a03c45f2998eb61e93cbc960..55c70b6dd51ddab10b414094a4c0187a6438e8c2 100644 (file)
@@ -118,14 +118,6 @@ static void ATTRIBUTE_PRINTF_3 i386_dis_printf (const disassemble_info *,
 /* The maximum operand buffer size.  */
 #define MAX_OPERAND_BUFFER_SIZE 128
 
-struct dis_private {
-  /* Points to first byte not fetched.  */
-  uint8_t *max_fetched;
-  uint8_t the_buffer[MAX_MNEM_SIZE];
-  bfd_vma insn_start;
-  int orig_sizeflag;
-};
-
 enum address_mode
 {
   mode_16bit,
@@ -251,6 +243,15 @@ struct instr_info
   enum x86_64_isa isa64;
 };
 
+struct dis_private {
+  bfd_vma insn_start;
+  int orig_sizeflag;
+
+  /* Points to first byte not fetched.  */
+  uint8_t *max_fetched;
+  uint8_t the_buffer[2 * MAX_CODE_LENGTH - 1];
+};
+
 /* Mark parts used in the REX prefix.  When we are testing for
    empty prefix (for 8bit register REX extension), just mask it
    out.  Otherwise test for REX bit is excuse for existence of REX
@@ -297,7 +298,7 @@ fetch_code (struct disassemble_info *info, uint8_t *until)
   if (until <= priv->max_fetched)
     return true;
 
-  if (until <= priv->the_buffer + MAX_MNEM_SIZE)
+  if (until <= priv->the_buffer + ARRAY_SIZE (priv->the_buffer))
     status = (*info->read_memory_func) (start,
                                        priv->max_fetched,
                                        until - priv->max_fetched,