public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Jan Beulich <jbeulich@suse.com>
To: Binutils <binutils@sourceware.org>
Cc: "H.J. Lu" <hjl.tools@gmail.com>, Alan Modra <amodra@gmail.com>
Subject: [PATCH 2/8] x86: change fetch error handling in top-level function
Date: Tue, 4 Apr 2023 08:58:37 +0200	[thread overview]
Message-ID: <39b50a10-ad10-aca0-2ef1-4d32be787762@suse.com> (raw)
In-Reply-To: <5dac45a8-cd5f-ee4d-52fc-7d283fc29ec4@suse.com>

... and its direct helper get_sib(). Using setjmp()/longjmp() for fetch
error handling is problematic, as per
https://sourceware.org/pipermail/binutils/2023-March/126687.html. Start
using more conventional error handling instead.

Also introduce a fetch_modrm() helper, for subsequent re-use.

--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -329,6 +329,49 @@ fetch_data (struct disassemble_info *inf
   return 1;
 }
 
+static bool
+fetch_code (struct disassemble_info *info, bfd_byte *until)
+{
+  int status = -1;
+  struct dis_private *priv = info->private_data;
+  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+  if (until <= priv->max_fetched)
+    return true;
+
+  if (until <= priv->the_buffer + MAX_MNEM_SIZE)
+    status = (*info->read_memory_func) (start,
+					priv->max_fetched,
+					until - priv->max_fetched,
+					info);
+  if (status != 0)
+    {
+      /* If we did manage to read at least one byte, then
+	 print_insn_i386 will do something sensible.  Otherwise, print
+	 an error.  We do that here because this is where we know
+	 STATUS.  */
+      if (priv->max_fetched == priv->the_buffer)
+	(*info->memory_error_func) (status, start, info);
+      return false;
+    }
+
+  priv->max_fetched = until;
+  return true;
+}
+
+static bool
+fetch_modrm (instr_info *ins)
+{
+  if (!fetch_code (ins->info, ins->codep + 1))
+    return false;
+
+  ins->modrm.mod = (*ins->codep >> 6) & 3;
+  ins->modrm.reg = (*ins->codep >> 3) & 7;
+  ins->modrm.rm = *ins->codep & 7;
+
+  return true;
+}
+
 static int
 fetch_error (const instr_info *ins)
 {
@@ -9573,7 +9616,7 @@ get_valid_dis386 (const struct dis386 *d
     return get_valid_dis386 (dp, ins);
 }
 
-static void
+static bool
 get_sib (instr_info *ins, int sizeflag)
 {
   /* If modrm.mod == 3, operand must be register.  */
@@ -9582,7 +9625,8 @@ get_sib (instr_info *ins, int sizeflag)
       && ins->modrm.mod != 3
       && ins->modrm.rm == 4)
     {
-      FETCH_DATA (ins->info, ins->codep + 2);
+      if (!fetch_code (ins->info, ins->codep + 2))
+	return false;
       ins->sib.index = (ins->codep[1] >> 3) & 7;
       ins->sib.scale = (ins->codep[1] >> 6) & 3;
       ins->sib.base = ins->codep[1] & 7;
@@ -9590,6 +9634,8 @@ get_sib (instr_info *ins, int sizeflag)
     }
   else
     ins->has_sib = false;
+
+  return true;
 }
 
 /* Like oappend (below), but S is a string starting with '%'.  In
@@ -9854,7 +9900,9 @@ print_insn (bfd_vma pc, disassemble_info
 
   ins.insn_codep = ins.codep;
 
-  FETCH_DATA (info, ins.codep + 1);
+  if (!fetch_code (info, ins.codep + 1))
+    return fetch_error (&ins);
+
   ins.two_source_ops = (*ins.codep == 0x62) || (*ins.codep == 0xc8);
 
   if (((ins.prefixes & PREFIX_FWAIT)
@@ -9874,7 +9922,8 @@ print_insn (bfd_vma pc, disassemble_info
       unsigned char threebyte;
 
       ins.codep++;
-      FETCH_DATA (info, ins.codep + 1);
+      if (!fetch_code (info, ins.codep + 1))
+	return fetch_error (&ins);
       threebyte = *ins.codep;
       dp = &dis386_twobyte[threebyte];
       ins.need_modrm = twobyte_has_modrm[threebyte];
@@ -9897,17 +9946,13 @@ print_insn (bfd_vma pc, disassemble_info
     sizeflag ^= DFLAG;
 
   ins.end_codep = ins.codep;
-  if (ins.need_modrm)
-    {
-      FETCH_DATA (info, ins.codep + 1);
-      ins.modrm.mod = (*ins.codep >> 6) & 3;
-      ins.modrm.reg = (*ins.codep >> 3) & 7;
-      ins.modrm.rm = *ins.codep & 7;
-    }
+  if (ins.need_modrm && !fetch_modrm (&ins))
+    return fetch_error (&ins);
 
   if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
     {
-      get_sib (&ins, sizeflag);
+      if (!get_sib (&ins, sizeflag))
+	return fetch_error (&ins);
       dofloat (&ins, sizeflag);
     }
   else
@@ -9915,7 +9960,8 @@ print_insn (bfd_vma pc, disassemble_info
       dp = get_valid_dis386 (dp, &ins);
       if (dp != NULL && putop (&ins, dp->name, sizeflag) == 0)
 	{
-	  get_sib (&ins, sizeflag);
+	  if (!get_sib (&ins, sizeflag))
+	    return fetch_error (&ins);
 	  for (i = 0; i < MAX_OPERANDS; ++i)
 	    {
 	      ins.obufp = ins.op_out[i];


  parent reply	other threads:[~2023-04-04  6:58 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-04  6:56 [PATCH 0/8] x86: do away with (ab)using setjmp/longjmp for error handling Jan Beulich
2023-04-04  6:58 ` [PATCH 1/8] x86: move fetch error handling into a helper function Jan Beulich
2023-04-04  6:58 ` Jan Beulich [this message]
2023-04-04  6:59 ` [PATCH 3/8] x86: change fetch error handling in ckprefix() Jan Beulich
2023-04-04  6:59 ` [PATCH 4/8] x86: change fetch error handling in get_valid_dis386() Jan Beulich
2023-04-04  7:00 ` [PATCH 5/8] x86: change fetch error handling when processing operands Jan Beulich
2023-04-04  7:00 ` [PATCH 6/8] x86: change fetch error handling for get<N>() Jan Beulich
2023-04-04  7:01 ` [PATCH 7/8] x86: drop use of setjmp() from disassembler Jan Beulich
2023-04-04  7:01 ` [PATCH 8/8] x86: drop (explicit) BFD64 dependency " Jan Beulich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=39b50a10-ad10-aca0-2ef1-4d32be787762@suse.com \
    --to=jbeulich@suse.com \
    --cc=amodra@gmail.com \
    --cc=binutils@sourceware.org \
    --cc=hjl.tools@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).