diff options
author | Yao Qi <yao@codesourcery.com> | 2012-03-09 03:47:15 +0000 |
---|---|---|
committer | Yao Qi <yao@codesourcery.com> | 2012-03-09 03:47:15 +0000 |
commit | f4647387fe3182beb6a30539d4339b85a48fc14e (patch) | |
tree | 2873bd931b2ca36f6a0dc78ec043bc6e9d240771 /gdb/gdbserver | |
parent | 6f5e93622126860eaa9c57ae1bd889c803f13168 (diff) | |
download | gdb-f4647387fe3182beb6a30539d4339b85a48fc14e.zip gdb-f4647387fe3182beb6a30539d4339b85a48fc14e.tar.gz gdb-f4647387fe3182beb6a30539d4339b85a48fc14e.tar.bz2 |
2012-03-08 Yao Qi <yao@codesourcery.com>
Pedro Alves <palves@redhat.com>
Fix PR server/13392.
* linux-x86-low.c (amd64_install_fast_tracepoint_jump_pad): Check
offset of JMP insn.
* tracepoint.c (remove_tracepoint): New.
(cmd_qtdp): Call remove_tracepoint when failed to install.
2012-03-08 Yao Qi <yao@codesourcery.com>
Pedro Alves <palves@redhat.com>
Fix PR server/13392.
* gdb.trace/change-loc.exp (tracepoint_change_loc_1): Remove kfail.
(tracepoint_change_loc_2): Remove kfail. Return if failed to
download tracepoints.
* gdb.trace/pending.exp (pending_tracepoint_works): Likewise.
(pending_tracepoint_resolved_during_trace): Likewise.
(pending_tracepoint_installed_during_trace): Likewise.
(pending_tracepoint_with_action_resolved): Likewise.
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/gdbserver/linux-x86-low.c | 27 | ||||
-rw-r--r-- | gdb/gdbserver/tracepoint.c | 24 |
3 files changed, 58 insertions, 2 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 521866d..04c0709 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,12 @@ +2012-03-08 Yao Qi <yao@codesourcery.com> + Pedro Alves <palves@redhat.com> + + Fix PR server/13392. + * linux-x86-low.c (amd64_install_fast_tracepoint_jump_pad): Check + offset of JMP insn. + * tracepoint.c (remove_tracepoint): New. + (cmd_qtdp): Call remove_tracepoint when failed to install. + 2012-03-07 Pedro Alves <palves@redhat.com> * linux-low.c (get_detach_signal): New. diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c index 58aaf9a..ed1f8a8 100644 --- a/gdb/gdbserver/linux-x86-low.c +++ b/gdb/gdbserver/linux-x86-low.c @@ -20,6 +20,7 @@ #include <stddef.h> #include <signal.h> #include <limits.h> +#include <inttypes.h> #include "server.h" #include "linux-low.h" #include "i387-fp.h" @@ -1200,6 +1201,8 @@ amd64_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint, CORE_ADDR tpaddr, { unsigned char buf[40]; int i, offset; + int64_t loffset; + CORE_ADDR buildaddr = *jump_entry; /* Build the jump pad. */ @@ -1323,7 +1326,17 @@ amd64_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint, CORE_ADDR tpaddr, *adjusted_insn_addr_end = buildaddr; /* Finally, write a jump back to the program. */ - offset = (tpaddr + orig_size) - (buildaddr + sizeof (jump_insn)); + + loffset = (tpaddr + orig_size) - (buildaddr + sizeof (jump_insn)); + if (loffset > INT_MAX || loffset < INT_MIN) + { + sprintf (err, + "E.Jump back from jump pad too far from tracepoint " + "(offset 0x%" PRIx64 " > int32).", loffset); + return 1; + } + + offset = (int) loffset; memcpy (buf, jump_insn, sizeof (jump_insn)); memcpy (buf + 1, &offset, 4); append_insns (&buildaddr, sizeof (jump_insn), buf); @@ -1332,7 +1345,17 @@ amd64_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint, CORE_ADDR tpaddr, is always done last (by our caller actually), so that we can install fast tracepoints with threads running. This relies on the agent's atomic write support. */ - offset = *jump_entry - (tpaddr + sizeof (jump_insn)); + loffset = *jump_entry - (tpaddr + sizeof (jump_insn)); + if (loffset > INT_MAX || loffset < INT_MIN) + { + sprintf (err, + "E.Jump pad too far from tracepoint " + "(offset 0x%" PRIx64 " > int32).", loffset); + return 1; + } + + offset = (int) loffset; + memcpy (buf, jump_insn, sizeof (jump_insn)); memcpy (buf + 1, &offset, 4); memcpy (jjump_pad_insn, buf, sizeof (jump_insn)); diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index 21e58ff..7bf576b 100644 --- a/gdb/gdbserver/tracepoint.c +++ b/gdb/gdbserver/tracepoint.c @@ -1684,6 +1684,28 @@ find_tracepoint (int id, CORE_ADDR addr) return NULL; } +/* Remove TPOINT from global list. */ + +static void +remove_tracepoint (struct tracepoint *tpoint) +{ + struct tracepoint *tp, *tp_prev; + + for (tp = tracepoints, tp_prev = NULL; tp && tp != tpoint; + tp_prev = tp, tp = tp->next) + ; + + if (tp) + { + if (tp_prev) + tp_prev->next = tp->next; + else + tracepoints = tp->next; + + xfree (tp); + } +} + /* There may be several tracepoints with the same number (because they are "locations", in GDB parlance); return the next one after the given tracepoint, or search from the beginning of the list if the @@ -2391,6 +2413,8 @@ cmd_qtdp (char *own_buf) download_tracepoint (tpoint); install_tracepoint (tpoint, own_buf); + if (strcmp (own_buf, "OK") != 0) + remove_tracepoint (tpoint); unpause_all (1); return; |