From patchwork Mon Nov 5 23:09:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 30031 Received: (qmail 13957 invoked by alias); 5 Nov 2018 23:10:13 -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 13832 invoked by uid 89); 5 Nov 2018 23:10:12 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=felt, placing, pc, $pc X-HELO: mail-wr1-f45.google.com Received: from mail-wr1-f45.google.com (HELO mail-wr1-f45.google.com) (209.85.221.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 05 Nov 2018 23:10:09 +0000 Received: by mail-wr1-f45.google.com with SMTP id o15-v6so7752738wrv.4 for ; Mon, 05 Nov 2018 15:10:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=/dB89eo6AvXwdLlh/3Wr5MHNEzZQeb9KDJkDl5Xolg0=; b=K1UyC1tOAQl8C+sYRUXVNRSXGCaQxgQAImuX1I88lh+F8hJjhZdytbK800Dz+HQuYC Y1Mhds1LRsX2fV590AFNh1gqy45M+Qq5UUM1TLVyHc8rHKc6ii4JCLtcaU7Yn/+mCWgQ aNXhc9FJ9Zpc1Dkjld2rWqY8ZSYYWwlIwigWb/ZOn2xNK5i78Xd5UHOTXRznA+jNCVXs poebSib6l8RhOCqM6G2TetPiLxbeHj37eMBs2YzLnoimYUdEr5r3KouWUoRY16gNm+id xETZ/gCa36ztdRLrBPW40JC7ud4WcZm5Rhit+FtVo4A8W6eMNTnCHhfeCCew5pHYkAP/ eBzA== Return-Path: Received: from localhost (host81-148-252-35.range81-148.btcentralplus.com. [81.148.252.35]) by smtp.gmail.com with ESMTPSA id k73-v6sm98105wmd.33.2018.11.05.15.10.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 05 Nov 2018 15:10:06 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: jimw@sifive.com, palmer@sifive.com, jhb@FreeBSD.org, Andrew Burgess Subject: [PATCH 1/2] gdb/riscv: Stop prologue scan if instruction fetch/decode fails Date: Mon, 5 Nov 2018 23:09:56 +0000 Message-Id: <1ab6341c3c73c6e0b501e7b25d6d64744d7cdbc0.1541459121.git.andrew.burgess@embecosm.com> In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes If an error is thrown from the instruction fetch/decode during a prologue scan then we should stop the prologue scan at that point rather than propagating the error. Propagating the error out of the prologue scan was causing unwanted behaviour when connecting to a remote target. When connecting to a remote target GDB will read the $pc value from the target and try to establish a frame-id, this can involve a prologue scan. If the target has not yet had a program loaded into it, and the $pc value is pointing an unreadable memory, then the prologue scan would throw an error, this would then cause GDB to abandon its attempt to connect to the target. It was in fact impossible to connect to the target at all. With this patch in place GDB simply stops the prologue scan at the point of the error, and GDB can now successfully connect. I did consider placing the error catch within riscv_insn::decode however, in the end I felt that catching and ignoring errors should be done on a case by case basis, the other users of riscv_insn::decode are currently all related to finding the next pc as part of software single step. If the user asks for a step and the contents of $pc can't be read then if feels like terminating that command with an error is the right thing to do. gdb/ChangeLog: * riscv-tdep.c (riscv_insn::decode): Update header comment. (riscv_scan_prologue): Catch errors thrown from riscv_insn::decode and stop prologue scan. --- gdb/ChangeLog | 6 ++++++ gdb/riscv-tdep.c | 27 ++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index db372e21632..aae93ea2fac 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -1256,7 +1256,9 @@ riscv_insn::fetch_instruction (struct gdbarch *gdbarch, return extract_unsigned_integer (buf, instlen, byte_order); } -/* Fetch from target memory an instruction at PC and decode it. */ +/* Fetch from target memory an instruction at PC and decode it. This can + throw an error if the memory access fails, callers are responsible for + handling this error if that is appropriate. */ void riscv_insn::decode (struct gdbarch *gdbarch, CORE_ADDR pc) @@ -1427,10 +1429,29 @@ riscv_scan_prologue (struct gdbarch *gdbarch, for (next_pc = cur_pc = start_pc; cur_pc < end_pc; cur_pc = next_pc) { struct riscv_insn insn; + bool decode_valid = false; /* Decode the current instruction, and decide where the next - instruction lives based on the size of this instruction. */ - insn.decode (gdbarch, cur_pc); + instruction lives based on the size of this instruction. If the + decode (which includes fetching from memory) fails then we stop + the prologue scan at this point. */ + TRY + { + insn.decode (gdbarch, cur_pc); + decode_valid = true; + } + CATCH (ex, RETURN_MASK_ERROR) + { + /* Ignore errors. */ + } + END_CATCH + + if (!decode_valid) + { + end_prologue_addr = cur_pc; + break; + } + gdb_assert (insn.length () > 0); next_pc = cur_pc + insn.length ();