diff mbox

target-openrisc: Fix exception handling status registers

Message ID 20170208140120.GI32144@lianli.shorne-pla.net (mailing list archive)
State New, archived
Headers show

Commit Message

Stafford Horne Feb. 8, 2017, 2:01 p.m. UTC
On Mon, Feb 06, 2017 at 09:53:26PM -0800, Richard Henderson wrote:
> On 02/01/2017 02:04 AM, Stafford Horne wrote:
> > For kernel builds I have created toolchain binaries here:
> > 
> >   http://shorne.noip.me/crosstool/files/bin/x86_64/5.4.0/
> > 
> > These should work.
> 
> This gdb crashes on the first "stepi" that I issue.  To reproduce,
> 
> $ cat z.c
> int main() { return 0; }
> $ or1k-musl-linux-gcc -g z.c
> $ qemu-or32 -g 10001 ./a.out
> 
> // another window
> 
> $ or1k-musl-linux-gdb ./a.out
> (gdb) target remote localhost:10001
> // should see that the pc is at _start
> (gdb) stepi
> // crash
> 
> I won't be able to debug this myself until I can build my own gdb.

Hello,

The gdb branch I use is the following, it is tracking very close to
upsstream:

  git@github.com:stffrdhrn/binutils-gdb.git or1k-upstream

I have sent this for review to the gdb list and currently waiting on
comments for version 4.  Most of the code is the same as in openrisc
github. However, I have just rebased and cleaned up for upstreaming.

Note, I can get basic programs running fine on your qemu branch using
linux-user i.e.

 $ cat main.c
   #include <stdio.h>

   int main() {
     printf("hello");
     return 0;
   }
 $ or1k-linux-musl-gcc -g -static main.c
 $ ./qemu/build/or32-linux-user/qemu-or32 ./a.out
   hello

However, when debugging I ran into a few errors.

  1. qemu aborts the program and sends SIGILL to gdb, this is caused by
     the openrisc loop in linux-user missing handlers for EXCP_INTERRUPT
     and EXCP_DEBUG, I patched that see below:
  2. After patching I got 1 step to work then gdb crashes with SIGSEGV
     Currently looking at it, Interestingly the code that is failing is

       in gdb/or1k-tdep.c: or1k_single_step_through_delay()
       cgen_lookup_insn() - returns NULL (shouldnt happen though)
       then NULL is dereferenced

     Interesting because it seems you wrote cgen_lookup_insn :)
     I am investigating more, but it seems like gdb issue.

Notes on the debugger:
  - The support for linux user processes is not implemented.  Eventually
    I think it will crash somewhere.  But it shouldnt crash where it is.
  - I tested the same program with the baremetal (newlib) toolchain
     * gdb native sim - OK can debug
     * or1ksim (via target remote) - Crashes same as QEMU

-Stafford


Patch for qemu issue mentioned in (1) above.

From 777bd1c6641ea919799579dfbc99db4338db11bf Mon Sep 17 00:00:00 2001
From: Stafford Horne <shorne@gmail.com>
Date: Wed, 8 Feb 2017 22:20:01 +0900
Subject: [PATCH] linux-user: openrisc: Implement EXCP_INTERRUPT and EXCP_DEBUG

These were not implemented.  They are required escpecially if we
want to debug user processes in openrisc.

Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 linux-user/main.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Stafford Horne Feb. 8, 2017, 4:38 p.m. UTC | #1
Hello,

On Wed, Feb 08, 2017 at 11:01:20PM +0900, Stafford Horne wrote:
> On Mon, Feb 06, 2017 at 09:53:26PM -0800, Richard Henderson wrote:
> > On 02/01/2017 02:04 AM, Stafford Horne wrote:
> > > For kernel builds I have created toolchain binaries here:
> > > 
> > >   http://shorne.noip.me/crosstool/files/bin/x86_64/5.4.0/
> > > 
> > > These should work.
> > 
> > This gdb crashes on the first "stepi" that I issue.  To reproduce,
> > 
> > $ cat z.c
> > int main() { return 0; }
> > $ or1k-musl-linux-gcc -g z.c
> > $ qemu-or32 -g 10001 ./a.out
> > 
> > // another window
> > 
> > $ or1k-musl-linux-gdb ./a.out
> > (gdb) target remote localhost:10001
> > // should see that the pc is at _start
> > (gdb) stepi
> > // crash
> > 
> > I won't be able to debug this myself until I can build my own gdb.
> 
> Hello,
> 
> The gdb branch I use is the following, it is tracking very close to
> upsstream:
> 
>   git@github.com:stffrdhrn/binutils-gdb.git or1k-upstream
> 
> I have sent this for review to the gdb list and currently waiting on
> comments for version 4.  Most of the code is the same as in openrisc
> github. However, I have just rebased and cleaned up for upstreaming.
> 
> Note, I can get basic programs running fine on your qemu branch using
> linux-user i.e.
> 
>  $ cat main.c
>    #include <stdio.h>
> 
>    int main() {
>      printf("hello");
>      return 0;
>    }
>  $ or1k-linux-musl-gcc -g -static main.c
>  $ ./qemu/build/or32-linux-user/qemu-or32 ./a.out
>    hello
> 
> However, when debugging I ran into a few errors.
> 
>   1. qemu aborts the program and sends SIGILL to gdb, this is caused by
>      the openrisc loop in linux-user missing handlers for EXCP_INTERRUPT
>      and EXCP_DEBUG, I patched that see below:
>   2. After patching I got 1 step to work then gdb crashes with SIGSEGV
>      Currently looking at it, Interestingly the code that is failing is
> 
>        in gdb/or1k-tdep.c: or1k_single_step_through_delay()
>        cgen_lookup_insn() - returns NULL (shouldnt happen though)
>        then NULL is dereferenced
> 
>      Interesting because it seems you wrote cgen_lookup_insn :)
>      I am investigating more, but it seems like gdb issue.

OK, I think I fixed this cgen_lookup_insn issue.

Now I can debug qemu user:

  $ ./qemu/build/or32-linux-user/qemu-or32 -g 10001 ./a.out
  $ or1k-linux-musl-gdb ./a.out \
    --eval-command='target remote localhost:10001'
   Remote debugging using localhost:10001
   0x000020e4 in _start ()
   (gdb) si
   0x000020e8 in _start ()
   (gdb)

A bug was added there by Nick Clifton last year when he did some memory
allocation cleanups in cgen_lookup_insn(). It seems not much code uses
this so perhaps it was not noticed.

Also, it looks like you didnt write it, you just imported the original
source?

I have now pushed the fix to my repo.  At the same time pushing to
gdb-patches list.

-Stafford

> Notes on the debugger:
>   - The support for linux user processes is not implemented.  Eventually
>     I think it will crash somewhere.  But it shouldnt crash where it is.
>   - I tested the same program with the baremetal (newlib) toolchain
>      * gdb native sim - OK can debug
>      * or1ksim (via target remote) - Crashes same as QEMU
>
Richard Henderson Feb. 8, 2017, 8:38 p.m. UTC | #2
On 02/08/2017 06:01 AM, Stafford Horne wrote:
> On Mon, Feb 06, 2017 at 09:53:26PM -0800, Richard Henderson wrote:
>> On 02/01/2017 02:04 AM, Stafford Horne wrote:
>>> For kernel builds I have created toolchain binaries here:
>>>
>>>   http://shorne.noip.me/crosstool/files/bin/x86_64/5.4.0/
>>>
>>> These should work.
>>
>> This gdb crashes on the first "stepi" that I issue.  To reproduce,
>>
>> $ cat z.c
>> int main() { return 0; }
>> $ or1k-musl-linux-gcc -g z.c
>> $ qemu-or32 -g 10001 ./a.out
>>
>> // another window
>>
>> $ or1k-musl-linux-gdb ./a.out
>> (gdb) target remote localhost:10001
>> // should see that the pc is at _start
>> (gdb) stepi
>> // crash
>>
>> I won't be able to debug this myself until I can build my own gdb.
>
> Hello,
>
> The gdb branch I use is the following, it is tracking very close to
> upsstream:
>
>   git@github.com:stffrdhrn/binutils-gdb.git or1k-upstream
>
> I have sent this for review to the gdb list and currently waiting on
> comments for version 4.  Most of the code is the same as in openrisc
> github. However, I have just rebased and cleaned up for upstreaming.

Thanks.  I can confirm that I have no problems building this branch.

> However, when debugging I ran into a few errors.
>
>   1. qemu aborts the program and sends SIGILL to gdb, this is caused by
>      the openrisc loop in linux-user missing handlers for EXCP_INTERRUPT
>      and EXCP_DEBUG, I patched that see below:

Yes, I fixed that on my or1k branch Monday.


r~
diff mbox

Patch

diff --git a/linux-user/main.c b/linux-user/main.c
index 94a636f..1c33378 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2468,6 +2468,7 @@  void cpu_loop(CPUOpenRISCState *env)
 {
     CPUState *cs = CPU(openrisc_env_get_cpu(env));
     int trapnr, gdbsig;
+    target_siginfo_t info;
     abi_long ret;
 
     for (;;) {
@@ -2542,6 +2543,23 @@  void cpu_loop(CPUOpenRISCState *env)
         case EXCP_ATOMIC:
             cpu_exec_step_atomic(cs);
             break;
+        case EXCP_INTERRUPT:
+            /* just indicate that signals should be handled asap */
+            break;
+        case EXCP_DEBUG:
+            {
+                int sig;
+
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
+                if (sig)
+                  {
+                    info.si_signo = sig;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_TRAP_BRKPT;
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+                  }
+            }
+            break;
         default:
             EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
                      trapnr);