From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 127995 invoked by alias); 11 Jul 2018 18:20:07 -0000 Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org Received: (qmail 127835 invoked by uid 89); 11 Jul 2018 18:20:06 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=states X-HELO: mail-wr1-f67.google.com Received: from mail-wr1-f67.google.com (HELO mail-wr1-f67.google.com) (209.85.221.67) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 11 Jul 2018 18:20:05 +0000 Received: by mail-wr1-f67.google.com with SMTP id s11-v6so19105390wra.13 for ; Wed, 11 Jul 2018 11:20:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=03WFBTEpLJDtRzAScFxyOrSAz+xZOI/EJLtoypl2yfY=; b=jb10xEgcpm0GvwcawkFYE/9OltoD18cVr7fg27n34U1ZX04CfsE6hBK+QzxZGMTUZ/ cRmHDemokXmmD8dG8duvSqcWwvQfaujCjRymFP1Q7lIijYKeBqS/c9wAiRQYDQX5N0gT e6RRUfdSXKarOakzR+p/l/OCLmJh+uWCUjBkOBOvV3QVFUJI6fBkRBmfaWNTDoFi024d JHt+1Wlu9xmTXeLbSToqOA/4v+AeSfVGolaiMOJyLBMkCqEF1fLyO1Jkkg1zFhDpi+v+ 8uH/RVBNllQ1caEz64uTPm0ZpAdH+WM53VPk+mrbSvs/8N9AhT3BSwDPt75YhOqVkWmX C7dw== MIME-Version: 1.0 Received: by 2002:adf:85d3:0:0:0:0:0 with HTTP; Wed, 11 Jul 2018 11:20:02 -0700 (PDT) In-Reply-To: <20180711174659.GA6398@embecosm.com> References: <20180711174659.GA6398@embecosm.com> From: Jim Wilson Date: Wed, 11 Jul 2018 18:20:00 -0000 Message-ID: Subject: Re: RISC-V: decr_pc_after_break causing problems To: Andrew Burgess Cc: gdb@sourceware.org Content-Type: text/plain; charset="UTF-8" X-SW-Source: 2018-07/txt/msg00029.txt.bz2 On Wed, Jul 11, 2018 at 10:46 AM, Andrew Burgess wrote: > * Jim Wilson [2018-06-25 19:54:14 -0700]: > >> The RISC-V port in the riscv-tdep.c file has >> set_gdbarch_decr_pc_after_break (gdbarch, (has_compressed_isa ? 2 : 4)); >> >> The privileged architecture spec v1.10 states in section 3.2.1 that >> the ebreak instruction causes the receiving privilege mode's epc >> register to be set to the address of the ebreak instruction, not the >> address of the following instruction. So gdb should not be >> decrementing from the pc after a breakpoint is hit. > > Maybe I'm going to look completely silly here, but.... > > ....aren't epc and pc different registers? When you take a trap in linux, pc gets copied to sepc, and pc is set to the linux kernel trap handler code. The trap handler then stores sepc into the process context, as it is the application pc. When gdb uses ptrace to get the pc, it is given the sepc, because that is the application pc value. So as far as gdb is concerned, there is only one program counter. The kernel just happens to call it sepc instead of pc because that is where the application pc lives in the kernel. When the kernel returns from a trap, executing the sret instruction, the sepc is copied back into the pc thus returning us to the original user code. In the linux kernel sources, in arch/riscv/include/asm/ptrace.h, it has struct pt_regs { unsigned long sepc; unsigned long ra; unsigned long sp; unsigned long gp; ... }; so the kernel stores the pc where x0 would go, because we don't need to save x0, and calls it sepc. > The epc is really many register, right? one for each privilege level, > uepc, sepc, and mepc. Yes, but since linux runs at supervisor level, there is only sepc that is interesting in this case. > The spec is clear that when an ebreak or c.ebreak is hit the contents > of *epc are the contents of the breaking instruction, but nothing is > said about the contents of pc. pc gets set to the trap handler address specified in the trap vector table. For linux, the address of that is presumably held in the stvec CSR, and then either you go to a default offset from stvec, or it is vectored by the exception number, or whatever, I haven't really looked at that code. > Assuming that my above observations are correct, then when we hit a > breakpoint *epc is defined, but pc is not, an implementation could do > anything, right? The two obvious choices are not increment pc, or > increment pc. No, the pc has to be the address of a trap handler in the kernel, because we took a trap. > Right now my understanding is that GDB doesn't have special support > for fetching the program counter from different places depending on > the current inferior state (stopped at breakpoint, not stopped at > breakpoint). So, somehow the value in *epc needs to be passed back > into the pc register (I guess). The kernel takes care of sepc. Gdb only needs to worry about the pc. At least, that is how it works when running an OS like linux. I don't know how this is going to work in an embedded system. Perhaps it is OpenOCD that takes care of mapping the appropriate xepc to pc depending on processor mode, and maybe OpenOCD also sets the appropriate xtvec register to point at its trap handler code. At no point in this process do we need to add or subtract anything from the pc. Jim