diff options
author | Sandra Loosemore <sandra@codesourcery.com> | 2019-03-28 09:29:22 -0700 |
---|---|---|
committer | Sandra Loosemore <sandra@codesourcery.com> | 2019-03-28 09:29:22 -0700 |
commit | f489207efde922e436b1b420d4de071927e3b9d5 (patch) | |
tree | d2c155fb7a9b7f4fec5fc0af7d18bbae11ee0d57 /gdb/nios2-linux-tdep.c | |
parent | c92df149c29518f6e1d4a3174b3e29162fcd3ad6 (diff) | |
download | gdb-f489207efde922e436b1b420d4de071927e3b9d5.zip gdb-f489207efde922e436b1b420d4de071927e3b9d5.tar.gz gdb-f489207efde922e436b1b420d4de071927e3b9d5.tar.bz2 |
Fix stepping past unwritable kernel helper on nios2-linux-gnu.
This patch fixes a problem on nios2-linux-gnu with stepping past the
kernel helper __kuser_cmpxchg, which was exposed by the testcase
gdb.threads/watchpoint-fork.exp. The kernel maps this function into
user space on an unwritable page. In this testcase, the cmpxchg
helper is invoked indirectly from the setbuf call in the test program.
Since this target lacks hardware breakpoint/watchpoint support, GDB
tries to single-step through the program by setting software
breakpoints, and was just giving an error when it reached the function
on the unwritable page.
The solution here is to always step over the call instead of stepping
into it; cmpxchg is supposed to be an atomic operation so this
behavior seems reasonable. The hook in nios2_get_next_pc is somewhat
generic, but at present cmpxchg is the only helper provided by the
Linux kernel that is invoked by an ordinary function call. (Signal
return trampolines also go through the unwritable page but not by a
function call.)
Fixing this issue also revealed that the testcase needs a much larger
timeout factor when software single-stepping is used. That has also
been fixed in this patch.
gdb/ChangeLog
2019-03-28 Sandra Loosemore <sandra@codesourcery.com>
* nios2-tdep.h (struct gdbarch_tdep): Add is_kernel_helper.
* nios2-tdep.c (nios2_get_next_pc): Skip over kernel helpers.
* nios2-linux-tdep.c (nios2_linux_is_kernel_helper): New.
(nios2_linux_init_abi): Install it.
gdb/testsuite/ChangeLog
2019-03-28 Sandra Loosemore <sandra@codesourcery.com>
* gdb.threads/watchpoint-fork.exp (test): Use large timeout
factor when no hardware watchpoint support.
Diffstat (limited to 'gdb/nios2-linux-tdep.c')
-rw-r--r-- | gdb/nios2-linux-tdep.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/gdb/nios2-linux-tdep.c b/gdb/nios2-linux-tdep.c index e4482d7..2d38e60 100644 --- a/gdb/nios2-linux-tdep.c +++ b/gdb/nios2-linux-tdep.c @@ -200,6 +200,17 @@ nios2_linux_syscall_next_pc (struct frame_info *frame, return pc + op->size; } +/* Return true if PC is a kernel helper, a function mapped by the kernel + into user space on an unwritable page. Currently the only such function + is __kuser_cmpxchg at 0x1004. See arch/nios2/kernel/entry.S in the Linux + kernel sources and sysdeps/unix/sysv/linux/nios2/atomic-machine.h in + GLIBC. */ +static bool +nios2_linux_is_kernel_helper (CORE_ADDR pc) +{ + return pc == 0x1004; +} + /* Hook function for gdbarch_register_osabi. */ static void @@ -230,6 +241,7 @@ nios2_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) &nios2_r1_linux_rt_sigreturn_tramp_frame); tdep->syscall_next_pc = nios2_linux_syscall_next_pc; + tdep->is_kernel_helper = nios2_linux_is_kernel_helper; /* Index of target address word in glibc jmp_buf. */ tdep->jb_pc = 10; |