From patchwork Mon Jan 18 21:14:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 10436 Received: (qmail 48599 invoked by alias); 18 Jan 2016 21:13:41 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 48588 invoked by uid 89); 18 Jan 2016 21:13:41 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=retrieved, remained, determination, examined X-HELO: mailapp01.imgtec.com Received: from Unknown (HELO mailapp01.imgtec.com) (195.59.15.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 18 Jan 2016 21:13:40 +0000 Received: from HHMAIL01.hh.imgtec.org (unknown [10.100.10.19]) by Websense Email Security Gateway with ESMTPS id 951FD588434F for ; Mon, 18 Jan 2016 21:13:33 +0000 (GMT) Received: from [10.100.200.15] (10.100.200.15) by HHMAIL01.hh.imgtec.org (10.100.10.21) with Microsoft SMTP Server id 14.3.235.1; Mon, 18 Jan 2016 21:13:36 +0000 Date: Mon, 18 Jan 2016 21:14:00 +0000 From: "Maciej W. Rozycki" To: Subject: [committed] MIPS: Fix microMIPS instruction size determination Message-ID: User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 Fix a bug in `micromips_insn_at_pc_has_delay_slot' in instruction size determination via `mips_insn_size'. In the microMIPS case the latter function expects a lone 16-bit instruction word containing the major opcode regardless of whether the opcode requires another 16-bit word to follow, to form a complete 32-bit instruction. Code however passes the 16-bit word previously retrieved shifted left by 16 bits. Consequently `mips_insn_size', which examines the low 16-bit only, always sees 0. By pure coincidence a major opcode of 0 denotes a 32-bit instruction in the microMIPS instruction set, so the size of 4 is always returned here, and the following 16-bit word is then merged in the low 16 bits of the instruction previously shifted by 16 bits. The resulting 32-bit value is then passed to `micromips_instruction_has_delay_slot' for delay slot presence determination. This function in turn first examines the high 16 bits of the instruction word received and ignores the low 16 bits for 16-bit instructions. Consequently the only effect of this bug is an extraneous memory read issued to retrieve a subsequent 16-bit word where a 16-bit instruction is being examined. Which in turn may fail if the instruction is located right at the end of a readable memory area, in which case the lack of a delay slot will be reported to the caller, which may be incorrect. This code is used in breakpoint maintenance, for delay slot avoidance, so the bug would only trigger for the unlikely case of someone placing a breakpoint in a delay slot of an instruction which is at the end of readable memory. Which explains why the bug remained unnoticed so long. gdb/ * mips-tdep.c (micromips_insn_at_pc_has_delay_slot): Pass unshifted 16-bit microMIPS instruction word to `mips_insn_size'. diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index ca17864..f787a6d 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -7376,12 +7376,14 @@ micromips_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, { ULONGEST insn; int status; + int size; insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status); if (status) return 0; + size = mips_insn_size (ISA_MICROMIPS, insn); insn <<= 16; - if (mips_insn_size (ISA_MICROMIPS, insn) == 2 * MIPS_INSN16_SIZE) + if (size == 2 * MIPS_INSN16_SIZE) { insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status); if (status)