From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1386) id DD50A3858C83; Fri, 21 Apr 2023 10:10:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DD50A3858C83 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Jan Beulich To: bfd-cvs@sourceware.org Subject: [binutils-gdb] x86: change fetch error handling in top-level function X-Act-Checkin: binutils-gdb X-Git-Author: Jan Beulich X-Git-Refname: refs/heads/master X-Git-Oldrev: 4bcbe86c25a61afd70106af466e73e4462c25d0b X-Git-Newrev: 06173b5d0926a76c9d1af832d76636f80fc04413 Message-Id: <20230421101040.DD50A3858C83@sourceware.org> Date: Fri, 21 Apr 2023 10:10:40 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Apr 2023 10:10:41 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D06173b5d0926= a76c9d1af832d76636f80fc04413 commit 06173b5d0926a76c9d1af832d76636f80fc04413 Author: Jan Beulich Date: Fri Apr 21 12:07:53 2023 +0200 x86: change fetch error handling in top-level function =20 ... 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. =20 Also introduce a fetch_modrm() helper, for subsequent re-use. Diff: --- opcodes/i386-dis.c | 72 ++++++++++++++++++++++++++++++++++++++++++++------= ---- 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index d731175cab6..393522f37ac 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -329,6 +329,49 @@ fetch_data (struct disassemble_info *info, bfd_byte *a= ddr) return 1; } =20 +static bool +fetch_code (struct disassemble_info *info, bfd_byte *until) +{ + int status =3D -1; + struct dis_private *priv =3D info->private_data; + bfd_vma start =3D priv->insn_start + (priv->max_fetched - priv->the_buff= er); + + if (until <=3D priv->max_fetched) + return true; + + if (until <=3D priv->the_buffer + MAX_MNEM_SIZE) + status =3D (*info->read_memory_func) (start, + priv->max_fetched, + until - priv->max_fetched, + info); + if (status !=3D 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 =3D=3D priv->the_buffer) + (*info->memory_error_func) (status, start, info); + return false; + } + + priv->max_fetched =3D until; + return true; +} + +static bool +fetch_modrm (instr_info *ins) +{ + if (!fetch_code (ins->info, ins->codep + 1)) + return false; + + ins->modrm.mod =3D (*ins->codep >> 6) & 3; + ins->modrm.reg =3D (*ins->codep >> 3) & 7; + ins->modrm.rm =3D *ins->codep & 7; + + return true; +} + static int fetch_error (const instr_info *ins) { @@ -9605,7 +9648,7 @@ get_valid_dis386 (const struct dis386 *dp, instr_info= *ins) return get_valid_dis386 (dp, ins); } =20 -static void +static bool get_sib (instr_info *ins, int sizeflag) { /* If modrm.mod =3D=3D 3, operand must be register. */ @@ -9614,7 +9657,8 @@ get_sib (instr_info *ins, int sizeflag) && ins->modrm.mod !=3D 3 && ins->modrm.rm =3D=3D 4) { - FETCH_DATA (ins->info, ins->codep + 2); + if (!fetch_code (ins->info, ins->codep + 2)) + return false; ins->sib.index =3D (ins->codep[1] >> 3) & 7; ins->sib.scale =3D (ins->codep[1] >> 6) & 3; ins->sib.base =3D ins->codep[1] & 7; @@ -9622,6 +9666,8 @@ get_sib (instr_info *ins, int sizeflag) } else ins->has_sib =3D false; + + return true; } =20 /* Like oappend (below), but S is a string starting with '%'. In @@ -9886,7 +9932,9 @@ print_insn (bfd_vma pc, disassemble_info *info, int i= ntel_syntax) =20 ins.insn_codep =3D ins.codep; =20 - FETCH_DATA (info, ins.codep + 1); + if (!fetch_code (info, ins.codep + 1)) + return fetch_error (&ins); + ins.two_source_ops =3D (*ins.codep =3D=3D 0x62) || (*ins.codep =3D=3D 0x= c8); =20 if (((ins.prefixes & PREFIX_FWAIT) @@ -9906,7 +9954,8 @@ print_insn (bfd_vma pc, disassemble_info *info, int i= ntel_syntax) unsigned char threebyte; =20 ins.codep++; - FETCH_DATA (info, ins.codep + 1); + if (!fetch_code (info, ins.codep + 1)) + return fetch_error (&ins); threebyte =3D *ins.codep; dp =3D &dis386_twobyte[threebyte]; ins.need_modrm =3D twobyte_has_modrm[threebyte]; @@ -9929,17 +9978,13 @@ print_insn (bfd_vma pc, disassemble_info *info, int= intel_syntax) sizeflag ^=3D DFLAG; =20 ins.end_codep =3D ins.codep; - if (ins.need_modrm) - { - FETCH_DATA (info, ins.codep + 1); - ins.modrm.mod =3D (*ins.codep >> 6) & 3; - ins.modrm.reg =3D (*ins.codep >> 3) & 7; - ins.modrm.rm =3D *ins.codep & 7; - } + if (ins.need_modrm && !fetch_modrm (&ins)) + return fetch_error (&ins); =20 if (dp->name =3D=3D NULL && dp->op[0].bytemode =3D=3D FLOATCODE) { - get_sib (&ins, sizeflag); + if (!get_sib (&ins, sizeflag)) + return fetch_error (&ins); dofloat (&ins, sizeflag); } else @@ -9947,7 +9992,8 @@ print_insn (bfd_vma pc, disassemble_info *info, int i= ntel_syntax) dp =3D get_valid_dis386 (dp, &ins); if (dp !=3D NULL && putop (&ins, dp->name, sizeflag) =3D=3D 0) { - get_sib (&ins, sizeflag); + if (!get_sib (&ins, sizeflag)) + return fetch_error (&ins); for (i =3D 0; i < MAX_OPERANDS; ++i) { ins.obufp =3D ins.op_out[i];