|
From: <sv...@va...> - 2009-05-27 23:14:07
|
Author: njn
Date: 2009-05-28 00:14:00 +0100 (Thu, 28 May 2009)
New Revision: 10154
Log:
Remove the debugstub removal diffs, just note the revisions they were
removed in Darwin-notes.txt.
Removed:
branches/DARWIN/docs/internals/debugstub_removed_at_r10012.diff
branches/DARWIN/docs/internals/debugstub_removed_at_r9477.diff
branches/DARWIN/docs/internals/debugstub_removed_at_r9711.diff
branches/DARWIN/docs/internals/debugstub_removed_at_r9759.diff
Modified:
branches/DARWIN/docs/internals/Darwin-notes.txt
branches/DARWIN/docs/internals/Makefile.am
Modified: branches/DARWIN/docs/internals/Darwin-notes.txt
===================================================================
--- branches/DARWIN/docs/internals/Darwin-notes.txt 2009-05-26 19:05:11 UTC (rev 10153)
+++ branches/DARWIN/docs/internals/Darwin-notes.txt 2009-05-27 23:14:00 UTC (rev 10154)
@@ -45,6 +45,14 @@
+Valgrind-developer notes, things removed from the original MacOSX port
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+There was a broken debugstub implementation. It was removed over several
+commits: r9477, which removed most of it, and r9711, r9759, and r10012,
+which cleaned up remaining bits.
+
+
+
Valgrind-developer notes, todos re the MacOSX port
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: branches/DARWIN/docs/internals/Makefile.am
===================================================================
--- branches/DARWIN/docs/internals/Makefile.am 2009-05-26 19:05:11 UTC (rev 10153)
+++ branches/DARWIN/docs/internals/Makefile.am 2009-05-27 23:14:00 UTC (rev 10154)
@@ -4,10 +4,6 @@
3_4_BUGSTATUS.txt \
BIG_APP_NOTES.txt \
Darwin-notes.txt \
- debugstub_removed_at_r9477.diff \
- debugstub_removed_at_r9711.diff \
- debugstub_removed_at_r9759.diff \
- debugstub_removed_at_r10012.diff \
directory-structure.txt \
howto_BUILD_KDE42.txt \
howto_oprofile.txt \
Deleted: branches/DARWIN/docs/internals/debugstub_removed_at_r10012.diff
===================================================================
--- branches/DARWIN/docs/internals/debugstub_removed_at_r10012.diff 2009-05-26 19:05:11 UTC (rev 10153)
+++ branches/DARWIN/docs/internals/debugstub_removed_at_r10012.diff 2009-05-27 23:14:00 UTC (rev 10154)
@@ -1,16 +0,0 @@
-Index: include/vki/vki-linux.h
-===================================================================
---- include/vki/vki-linux.h (revision 10011)
-+++ include/vki/vki-linux.h (working copy)
-@@ -157,11 +157,6 @@
-
- typedef unsigned int vki_uint;
-
--// [[Other OSes (eg. Darwin) have a socklen_t type used in bind(), accept(),
--// etc, but Linux just uses 'int'. So we use this typedef, which is *not*
--// present in the Linux kernel. --njn]]
--typedef int vki_socklen_t;
--
- //----------------------------------------------------------------------
- // Now the rest of the arch-specific stuff
- //----------------------------------------------------------------------
Deleted: branches/DARWIN/docs/internals/debugstub_removed_at_r9477.diff
===================================================================
--- branches/DARWIN/docs/internals/debugstub_removed_at_r9477.diff 2009-05-26 19:05:11 UTC (rev 10153)
+++ branches/DARWIN/docs/internals/debugstub_removed_at_r9477.diff 2009-05-27 23:14:00 UTC (rev 10154)
@@ -1,2218 +0,0 @@
-Index: memcheck/mc_main.c
-===================================================================
---- memcheck/mc_main.c (revision 9475)
-+++ memcheck/mc_main.c (working copy)
-@@ -43,7 +43,6 @@
- #include "pub_tool_replacemalloc.h"
- #include "pub_tool_tooliface.h"
- #include "pub_tool_threadstate.h"
--#include "pub_tool_debugstub.h"
-
- #include "mc_include.h"
- #include "memcheck.h" /* for client requests */
-@@ -5131,106 +5130,6 @@
-
-
- /*------------------------------------------------------------*/
--/*--- Remote debugger commands ---*/
--/*------------------------------------------------------------*/
--
--
--// qvalgrind.Memcheck.defined:<addr>,<len> => XX..
--// like gdb protocol's "m" command, but reads V bits instead of memory
--// fixme should be qXfer command (mac os x gdb doesn't have qXfer)
--static Bool handle_defined_command(Int sock, Char *cmd)
--{
-- Long addr, len;
-- Char *vbits;
-- Char *outbuf;
-- Long i;
--
-- addr = VG_(strtoll16)(cmd, NULL);
-- cmd = VG_(strchr)(cmd, ',');
-- if (!cmd) return False;
--
-- len = VG_(strtoll16)(cmd+1, NULL);
-- if (len > 65536) len = 65536; // sanity
--
-- vbits = VG_(malloc)("mc.gdb.vbits", len);
-- outbuf = VG_(malloc)("mc.gdb.outbuf", 2*len+1);
--
-- tl_assert(V_BIT_DEFINED == 0);
-- for (i = 0; i < len; i++) {
-- UChar v;
-- if (get_vbits8(addr+i, &v)) {
-- // Invert returned bits: uninitialized=0, initialized=1
-- vbits[i] = ~v;
-- } else {
-- // Report unaddressable memory as undefined (unlike get_vbits8)
-- vbits[i] = 0;
-- }
-- }
--
-- VG_(debugstub_tohex)(outbuf, vbits, len);
-- VG_(free)(vbits);
--
-- VG_(debugstub_write_reply)(sock, outbuf);
-- VG_(free)(outbuf);
--
-- return True;
--}
--
--
--// qvalgrind.Memcheck.register-defined:<regnum> => XX..
--// like gdb protocol's "p" command, but reads V bits instead of register value
--// fixme should be qXfer command (mac os x gdb doesn't have qXfer)
--static Bool handle_register_defined_command(Int sock, Char *cmd)
--{
-- Char vbits[16];
-- Char outbuf[16*2+1];
-- Long i;
-- Int size, regnum;
--
-- regnum = VG_(strtoll16)(cmd, NULL);
--
-- size = VG_(reg_for_regnum)(regnum, vbits, 1); // GrP fixme shadow1 or 2?
-- if (size < 0) {
-- VG_(debugstub_write_reply)(sock, "x");
-- return True;
-- }
--
-- // Invert returned bits: uninitialized=0, initialized=1
-- tl_assert(V_BIT_DEFINED == 0);
-- for (i = 0; i < size; i++) {
-- vbits[i] = ~vbits[i];
-- }
--
-- VG_(debugstub_tohex)(outbuf, vbits, size);
-- VG_(debugstub_write_reply)(sock, outbuf);
--
-- return True;
--}
--
--static Bool mc_handle_debugger_query(Int sock, Char* cmd)
--{
-- Bool handled = True;
--
-- if (0 == VG_(strncmp)(cmd, "defined:", 8)) {
-- handled = handle_defined_command(sock, cmd+8);
-- }
-- else if (0 == VG_(strncmp)(cmd, "register-defined:", 17)) {
-- handled = handle_register_defined_command(sock, cmd+17);
-- }
-- else {
-- handled = False;
-- }
--
-- return handled;
--}
--
--static Bool mc_handle_debugger_action(Int sock, Char* cmd)
--{
-- return False;
--}
--
--
--/*------------------------------------------------------------*/
- /*--- Crude profiling machinery. ---*/
- /*------------------------------------------------------------*/
-
-@@ -5821,8 +5720,6 @@
- mc_print_usage,
- mc_print_debug_usage);
- VG_(needs_client_requests) (mc_handle_client_request);
-- VG_(needs_debugger_commands) (mc_handle_debugger_query,
-- mc_handle_debugger_action);
- VG_(needs_sanity_checks) (mc_cheap_sanity_check,
- mc_expensive_sanity_check);
- VG_(needs_malloc_replacement) (MC_(malloc),
-@@ -5942,34 +5839,6 @@
-
- VG_DETERMINE_INTERFACE_VERSION(mc_pre_clo_init)
-
--
--// GrP for debugging
--static void mc_print_word(Addr a)
--{
-- UChar abit[4] = {0,0,0,0};
-- UChar vbyte[4] = {0,0,0,0};
-- abit[0] = get_vbits8(a+0, vbyte+0);
-- abit[1] = get_vbits8(a+1, vbyte+1);
-- abit[2] = get_vbits8(a+2, vbyte+2);
-- abit[3] = get_vbits8(a+3, vbyte+3);
-- tl_assert(V_BIT_DEFINED == 0);
-- VG_(printf)("%#lx: a %d%d%d%d, v 0x%02x%02x%02x%02x\n",
-- a,
-- abit[0], abit[1], abit[2], abit[3],
-- ~vbyte[0], ~vbyte[1], ~vbyte[2], ~vbyte[3]);
--}
--
--// GrP for debugging
--__attribute__((unused))
--static void mc_describe_memory(Addr addr, SizeT size)
--{
-- Addr a;
-- for (a = addr; a < addr+size; a += 4) {
-- mc_print_word(a);
-- }
--}
--
--
- /*--------------------------------------------------------------------*/
- /*--- end mc_main.c ---*/
- /*--------------------------------------------------------------------*/
-Index: include/pub_tool_tooliface.h
-===================================================================
---- include/pub_tool_tooliface.h (revision 9475)
-+++ include/pub_tool_tooliface.h (working copy)
-@@ -383,23 +383,6 @@
- Bool (*handle_client_request)(ThreadId tid, UWord* arg_block, UWord* ret)
- );
-
--/* Tool defines its own debugger commands? */
--extern void VG_(needs_debugger_commands) (
-- // Debugger query command started with: "qvalgrind.<toolname>.".
-- // `arg` points to the rest of the query, if any. These commands
-- // should be used for data queries and the like.
-- // Return True if option was recognised. A reply must be sent using
-- // using VG_(debugger_write_command).
-- // Return False if the option was not recognized. Do not send a reply.
-- // See the GDB remote serial protocol for more command details.
-- Bool (*process_debugger_query)(Int sock, Char* arg),
--
-- // Like process_debugger_query, but prefix was "Qvalgrind.<toolname>.".
-- // These commands should be used for memory modifications and other
-- // process-manipulating actions.
-- Bool (*process_debugger_action)(Int sock, Char* arg)
--);
--
- /* Tool does stuff before and/or after system calls? */
- // Nb: If either of the pre_ functions malloc() something to return, the
- // corresponding post_ function had better free() it!
-Index: include/pub_tool_debugstub.h
-===================================================================
---- include/pub_tool_debugstub.h (revision 9476)
-+++ include/pub_tool_debugstub.h (working copy)
-@@ -1,52 +0,0 @@
--
--/*--------------------------------------------------------------------*/
--/*--- gdb remote debugging pub_tool_debugstub.h ---*/
--/*--------------------------------------------------------------------*/
--
--/*
-- This file is part of Valgrind, a dynamic binary instrumentation
-- framework.
--
-- Copyright (C) 2007 Apple Inc.
-- Greg Parker gp...@ap...
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
-- published by the Free Software Foundation; either version 2 of the
-- License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-- 02111-1307, USA.
--
-- The GNU General Public License is contained in the file COPYING.
--*/
--
--#ifndef __PUB_TOOL_DEBUGSTUB_H
--#define __PUB_TOOL_DEBUGSTUB_H
--
--// Send a reply packet to the gdb remote debugger.
--// Use this inside your handlers for VG_(needs_debugger_commands).
--extern void VG_(debugstub_write_reply)(Int sock, const Char* contents);
--
--// Encode binary data in gdb's hex format, with nul terminator.
--// len is the number of bytes in SRC; dst must be 2*len+1 bytes.
--extern void VG_(debugstub_tohex)(Char *dst, const void *src, Int len);
--
--// Decode binary data from gdb's hex format.
--// len is the number of bytes in DST; src must be 2*len bytes.
--extern void VG_(debugstub_fromhex)(void *dst, const Char *src, Int len);
--
--// Retrieve register contents (from the "current thread" as designated
--// by the remote debugger). Stores the register or vex_shadowN value in
--// *rbuf, and returns the number of bytes written.
--extern Int VG_(reg_for_regnum)(Int regnum, void *rbuf, Int shadow);
--
--#endif
--
-Index: include/vki/vki-darwin.h
-===================================================================
---- include/vki/vki-darwin.h (revision 9475)
-+++ include/vki/vki-darwin.h (working copy)
-@@ -778,6 +778,12 @@
- typedef struct eventreq vki_eventreq;
-
-
-+#include <sys/ptrace.h>
-+
-+#define VKI_PTRACE_TRACEME PT_TRACE_ME
-+#define VKI_PTRACE_DETACH PT_DETACH
-+
-+
- // sqlite/src/os_unix.c
-
- struct ByteRangeLockPB2
-Index: include/Makefile.am
-===================================================================
---- include/Makefile.am (revision 9475)
-+++ include/Makefile.am (working copy)
-@@ -11,7 +11,6 @@
- pub_tool_clreq.h \
- pub_tool_cpuid.h \
- pub_tool_debuginfo.h \
-- pub_tool_debugstub.h \
- pub_tool_errormgr.h \
- pub_tool_execontext.h \
- pub_tool_hashtable.h \
-Index: coregrind/pub_core_scheduler.h
-===================================================================
---- coregrind/pub_core_scheduler.h (revision 9475)
-+++ coregrind/pub_core_scheduler.h (working copy)
-@@ -104,11 +104,6 @@
- /* Sanity checks which may be done at any time. The scheduler decides when. */
- extern void VG_(sanity_check_general) ( Bool force_expensive );
-
--/* GrP fixme scheduler hacks for debugger */
--extern void VG_(lock)(void);
--extern void VG_(unlock)(void);
--extern void VG_(unlock_lwpid)(Int lwpid);
--
- #endif // __PUB_CORE_SCHEDULER_H
-
- /*--------------------------------------------------------------------*/
-Index: coregrind/pub_core_debugstub.h
-===================================================================
---- coregrind/pub_core_debugstub.h (revision 9476)
-+++ coregrind/pub_core_debugstub.h (working copy)
-@@ -1,44 +0,0 @@
--
--/*--------------------------------------------------------------------*/
--/*--- gdb remote debugging pub_core_debugstub.h ---*/
--/*--------------------------------------------------------------------*/
--
--/*
-- This file is part of Valgrind, a dynamic binary instrumentation
-- framework.
--
-- Copyright (C) 2007 Apple Inc.
-- Greg Parker gp...@ap...
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
-- published by the Free Software Foundation; either version 2 of the
-- License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-- 02111-1307, USA.
--
-- The GNU General Public License is contained in the file COPYING.
--*/
--
--#ifndef __PUB_CORE_DEBUGSTUB_H
--#define __PUB_CORE_DEBUGSTUB_H
--
--extern void VG_(debugstub_init) ( void );
--extern void VG_(debugstub_write_reply) ( Int sock, const Char* contents );
--extern void VG_(debugstub_tohex) ( Char *dst, const void *src, Int len );
--extern void VG_(debugstub_fromhex) ( void *dst, const Char *src, Int len );
--extern Int VG_(reg_for_regnum) ( Int regnum, void *rbuf, Int shadow );
--
--#endif // __PUB_CORE_DEBUGSTUB_H
--
--/*--------------------------------------------------------------------*/
--/*--- end ---*/
--/*--------------------------------------------------------------------*/
-Index: coregrind/m_tooliface.c
-===================================================================
---- coregrind/m_tooliface.c (revision 9475)
-+++ coregrind/m_tooliface.c (working copy)
-@@ -268,16 +268,6 @@
- VG_(tdict).tool_handle_client_request = handle;
- }
-
--void VG_(needs_debugger_commands)(
-- Bool (*query)(Int, Char*),
-- Bool (*action)(Int, Char*)
--)
--{
-- VG_(needs).debugger_commands = True;
-- VG_(tdict).tool_handle_debugger_query = query;
-- VG_(tdict).tool_handle_debugger_action = action;
--}
--
- void VG_(needs_syscall_wrapper)(
- void(*pre) (ThreadId, UInt),
- void(*post)(ThreadId, UInt, SysRes res)
-Index: coregrind/pub_core_tooliface.h
-===================================================================
---- coregrind/pub_core_tooliface.h (revision 9475)
-+++ coregrind/pub_core_tooliface.h (working copy)
-@@ -138,10 +138,6 @@
- // VG_(needs).client_requests
- Bool (*tool_handle_client_request)(ThreadId, UWord*, UWord*);
-
-- // VG_(needs).debugger_commands
-- Bool (*tool_handle_debugger_query)(Int, Char*);
-- Bool (*tool_handle_debugger_action)(Int, Char*);
--
- // VG_(needs).syscall_wrapper
- void (*tool_pre_syscall) (ThreadId, UInt);
- void (*tool_post_syscall)(ThreadId, UInt, SysRes);
-Index: coregrind/m_debugger.c
-===================================================================
---- coregrind/m_debugger.c (revision 9475)
-+++ coregrind/m_debugger.c (working copy)
-@@ -41,15 +41,7 @@
- #include "pub_core_libcassert.h"
- #include "pub_core_options.h"
-
--#if VGO_darwin
-
--/* External debugger not supported. Use gdb remote debug instead.
-- VG_(start_debugger) is in m_debugstub.c. */
-- // DDD: ugh, that's horrible. Should fix, probably by having
-- // VG_(start_debugger) and VG_(start_remote_debugger).
--
--#else
--
- #define WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
- #define WSTOPSIG(status) (((status) & 0xff00) >> 8)
-
-@@ -219,6 +211,12 @@
- #elif defined(VGP_ppc64_aix5)
- I_die_here;
-
-+#elif defined(VGP_x86_darwin)
-+ I_die_here;
-+
-+#elif defined(VGP_amd64_darwin)
-+ I_die_here;
-+
- #else
- # error Unknown arch
- #endif
-@@ -322,8 +320,8 @@
- # undef N_BUF
- }
-
--#endif
-
-+
- /*--------------------------------------------------------------------*/
- /*--- end ---*/
- /*--------------------------------------------------------------------*/
-Index: coregrind/m_main.c
-===================================================================
---- coregrind/m_main.c (revision 9475)
-+++ coregrind/m_main.c (working copy)
-@@ -37,7 +37,6 @@
- #include "pub_core_aspacemgr.h"
- #include "pub_core_commandline.h"
- #include "pub_core_debuglog.h"
--#include "pub_core_debugstub.h"
- #include "pub_core_errormgr.h"
- #include "pub_core_execontext.h"
- #include "pub_core_initimg.h"
-@@ -2031,22 +2030,6 @@
- VG_(sigstartup_actions)();
-
- //--------------------------------------------------------------
-- // Listen for remote debugger
-- // p: scheduler, process_cmd_line_options()
-- //--------------------------------------------------------------
--#if defined(VGO_darwin)
--#if 0
-- if (VG_(clo_db_listen) && VG_(clo_verbosity) > 0) {
-- VG_(debugLog)(1, "main", "Listening for debugger on port %d\n",
-- VG_(clo_db_listen_port));
-- VG_(debugstub_init)();
-- }
--#endif
--#else
-- // DDD: Only Darwin does this for the moment.
--#endif
--
-- //--------------------------------------------------------------
- // Read suppression file
- // p: main_process_cmd_line_options() [for VG_(clo_suppressions)]
- //--------------------------------------------------------------
-Index: coregrind/m_scheduler/scheduler.c
-===================================================================
---- coregrind/m_scheduler/scheduler.c (revision 9475)
-+++ coregrind/m_scheduler/scheduler.c (working copy)
-@@ -228,7 +228,6 @@
- VG_(printf)("tid %d found %d running\n", tid, VG_(running_tid));
- vg_assert(VG_(running_tid) == VG_INVALID_THREADID);
- VG_(running_tid) = tid;
-- VG_(last_running_tid) = tid;
-
- { Addr gsp = VG_(get_SP)(tid);
- VG_(unknown_SP_update)(gsp, gsp, 0/*unknown origin*/);
-@@ -289,28 +288,6 @@
- }
-
-
--void VG_(lock)(void)
--{
-- ML_(sema_down)(&the_BigLock);
-- if (VG_(clo_trace_sched)) {
-- print_sched_event(0, " acquired lock (DEBUGGER)");
-- }
--}
--
--void VG_(unlock)(void)
--{
-- if (VG_(clo_trace_sched)) {
-- print_sched_event(0, " releasing lock (DEBUGGER)");
-- }
-- ML_(sema_up)(&the_BigLock);
--}
--
--void VG_(unlock_lwpid)(Int lwpid)
--{
-- while (! ML_(sema_handoff)(&the_BigLock, lwpid))
-- ;
--}
--
- /* Clear out the ThreadState and release the semaphore. Leaves the
- ThreadState in VgTs_Zombie state, so that it doesn't get
- reallocated until the caller is really ready. */
-Index: coregrind/m_scheduler/sema.c
-===================================================================
---- coregrind/m_scheduler/sema.c (revision 9475)
-+++ coregrind/m_scheduler/sema.c (working copy)
-@@ -147,13 +147,6 @@
- ML_(sema_down)(sema);
- }
-
--Bool ML_(sema_handoff)(vg_sema_t *sema, Int lwpid)
--{
-- // XXX: This function is currently only used by VG_(unlock_lwpid), which
-- // is only used in debugstub-darwin.c.
-- I_die_here;
--}
--
- #elif defined(VGO_darwin)
-
- #include <mach/mach.h>
-@@ -201,11 +194,6 @@
- ML_(sema_down)(sema);
- }
-
--Bool ML_(sema_handoff)(vg_sema_t *sema, Int lwpid)
--{
-- return semaphore_signal_thread(sema->lock, (thread_act_t)lwpid) ? False : True;
--}
--
- #else
- # error Unknown OS
- #endif
-Index: coregrind/m_scheduler/priv_sema.h
-===================================================================
---- coregrind/m_scheduler/priv_sema.h (revision 9475)
-+++ coregrind/m_scheduler/priv_sema.h (working copy)
-@@ -54,7 +54,6 @@
- void ML_(sema_down) ( vg_sema_t *sema );
- void ML_(sema_up) ( vg_sema_t *sema );
- void ML_(sema_fork_child)(vg_sema_t *sema);
--Bool ML_(sema_handoff)( vg_sema_t *sema, Int lwpid );
-
- #endif // __PRIV_SEMA_H
-
-Index: coregrind/m_debugstub/debugstub-linux.c
-===================================================================
---- coregrind/m_debugstub/debugstub-linux.c (revision 9476)
-+++ coregrind/m_debugstub/debugstub-linux.c (working copy)
-@@ -1,60 +0,0 @@
--/*--------------------------------------------------------------------*/
--/*--- gdb remote debugging m_debugstub.c ---*/
--/*--------------------------------------------------------------------*/
--
--/*
-- This file is part of Valgrind, a dynamic binary instrumentation
-- framework.
--
-- Copyright (C) 2009 Nicholas Nethercote
-- nj...@va...
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
-- published by the Free Software Foundation; either version 2 of the
-- License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-- 02111-1307, USA.
--
-- The GNU General Public License is contained in the file COPYING.
--*/
--
--#include "pub_core_basics.h"
--#include "pub_core_libcassert.h"
--
--#include "pub_core_debugstub.h"
--
--
--void VG_(debugstub_init)(void)
--{
-- I_die_here;
--}
--
--void VG_(debugstub_write_reply)(Int sock, const Char* contents)
--{
-- I_die_here;
--}
--
--void VG_(debugstub_tohex)(Char *dst, const void *src, Int len)
--{
-- I_die_here;
--}
--
--void VG_(debugstub_fromhex)(void *dst, const Char *src, Int len)
--{
-- I_die_here;
--}
--
--Int VG_(reg_for_regnum)(Int regnum, void *rbuf, Int shadow)
--{
-- I_die_here;
--}
--
-Index: coregrind/m_debugstub/debugstub-darwin.c
-===================================================================
---- coregrind/m_debugstub/debugstub-darwin.c (revision 9476)
-+++ coregrind/m_debugstub/debugstub-darwin.c (working copy)
-@@ -1,1478 +0,0 @@
--/*--------------------------------------------------------------------*/
--/*--- gdb remote debugging m_debugstub.c ---*/
--/*--------------------------------------------------------------------*/
--
--/*
-- This file is part of Valgrind, a dynamic binary instrumentation
-- framework.
--
-- Copyright (C) 2007 Apple Inc.
-- Greg Parker gp...@ap...
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
-- published by the Free Software Foundation; either version 2 of the
-- License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-- 02111-1307, USA.
--
-- The GNU General Public License is contained in the file COPYING.
--*/
--
--#include "pub_core_basics.h"
--#include "pub_core_vki.h"
--#include "pub_core_aspacemgr.h"
--#include "pub_core_threadstate.h"
--#include "pub_core_libcbase.h"
--#include "pub_core_libcassert.h"
--#include "pub_core_libcfile.h"
--#include "pub_core_libcprint.h"
--#include "pub_core_xarray.h"
--#include "pub_core_clientstate.h"
--#include "pub_core_libcproc.h"
--#include "pub_core_mallocfree.h"
--#include "pub_core_options.h"
--#include "pub_core_tooliface.h"
--#include "pub_core_transtab.h"
--#include "pub_core_scheduler.h"
--#include "pub_core_debugger.h"
--#include "pub_core_debugstub.h"
--
--#include <mach/mach.h>
--#include <mach/mach_vm.h>
--
--#define msgbufsize 4096
--static char msgbuf[msgbufsize];
--static char outbuf[msgbufsize];
--static const char xdigit[] = "0123456789abcdef";
--
--static ThreadId query_tid = VG_INVALID_THREADID;
--static ThreadId control_tid = VG_INVALID_THREADID;
--
--static Bool debugger_running = False;
--static Int debugger_lwpid;
--static Int debugger_notify[2];
--static ThreadId stop_tid;
--static Int stop_sig;
--
--// GDB's register numbers for 'g', in order
--#if defined(VGA_x86)
--enum { rEAX = 0, rECX, rEDX, rEBX, rESP, rEBP, rESI, rEDI,
-- rEIP, rEFLAGS, rCS, rSS, rDS, rES, rFS, rGS,
-- rST0, rST1, rST2, rST3, rST4, rST5, rST6, rST7,
-- rFCTRL, rFSTAT, rFTAG, rFISEG, rFIOFF, rFOSEG, rFOOFF, rFOP,
-- rXMM0, rXMM1, rXMM2, rXMM3, rXMM4, rXMM5, rXMM6, rXMM7,
-- rMXCSR,
-- rcount, grcount = rST0 };
--#define rPC rEIP
--#define guest_PC guest_EIP
--
--#elif defined(VGA_amd64)
--// fixme check
--enum { rRAX = 0, rRBX, rRCX, rRDX, rRSI, rRDI, rRBP, rRSP,
-- rR8, rR9, rR10, rR11, rR12, rR13, rR14, rR15,
-- rRIP, rRFLAGS, rCS, rSS, rDS, rES, rFS, rGS,
-- rST0, rST1, rST2, rST3, rST4, rST5, rST6, rST7,
-- rFCTRL, rFSTAT, rFTAG, rFISEG, rFIOFF, rFOSEG, rFOOFF, rFOP,
-- rXMM0, rXMM1, rXMM2, rXMM3, rXMM4, rXMM5, rXMM6, rXMM7,
-- rXMM8, rXMM9, rXMM10, rXMM11, rXMM12, rXMM13, rXMM14, rXMM15,
-- rMXCSR,
-- rcount, grcount = rST0 };
--#define rPC rRIP
--#define guest_PC guest_RIP
--
--#else
--#error unknown architecture
--#endif
--
--#if defined(VGA_x86) || defined(VGA_amd64)
--// hack - functions from vex
--extern void convert_f64le_to_f80le ( const void *f64, void *f80 );
--extern void convert_f80le_to_f64le ( const void *f80, void *f64 );
--#endif
--
--static void debuglog(const HChar *format, ...)
--{
-- if (VG_(clo_verbosity) > 1) {
-- va_list vargs;
-- va_start(vargs,format);
-- VG_(vmessage) ( Vg_DebugMsg, format, vargs );
-- va_end(vargs);
-- }
--}
--
--static ThreadId first_valid_tid(void)
--{
-- ThreadId tid;
-- for (tid = 0; tid < VG_N_THREADS; tid++) {
-- if (VG_(is_valid_tid)(tid)) return tid;
-- }
-- return VG_INVALID_THREADID;
--}
--
--static void debugger_lock(Int sock)
--{
-- VG_(lock)();
--
-- if (stop_tid) {
-- query_tid = stop_tid;
-- control_tid = stop_tid;
-- } else {
-- if (! VG_(is_valid_tid)(query_tid)) {
-- query_tid = first_valid_tid();
-- }
-- if (! VG_(is_valid_tid)(control_tid)) {
-- control_tid = first_valid_tid();
-- }
-- }
--
-- // Flush commands already sent by gdb - it may have given up on
-- // them already and will be confused if we reply
-- // This should only happen on initial connect, where we may accept the
-- // connection but not reply until the user answers "Attach to debugger ?"
-- // On control-C or error report entry, gdb shouldn't say anything
-- // further until we send a stop reply.
-- {
-- int flags;
-- char c;
-- flags = VG_(fcntl)(sock, VKI_F_GETFL, 0);
-- VG_(fcntl)(sock, VKI_F_SETFL, flags | VKI_O_NONBLOCK);
-- while (1 == VG_(read)(sock, &c, 1))
-- ;
-- VG_(fcntl)(sock, VKI_F_SETFL, flags);
-- }
--}
--
--static void debugger_unlock(void)
--{
-- if (stop_tid) {
-- Int lwpid = VG_(threads)[stop_tid].os_state.lwpid;
-- stop_tid = 0;
-- stop_sig = 0;
-- VG_(unlock_lwpid)(lwpid);
-- } else {
-- VG_(unlock)();
-- }
--}
--
--static int reg_from_vex(ThreadId tid, Int regnum, void *rbuf, Int shadow)
--{
-- ThreadState *tst = &VG_(threads)[tid];
--
--#if defined(VGA_x86)
-- Addr w;
-- VexGuestX86State *state;
-- switch (shadow) {
-- case 0: state = &tst->arch.vex; break;
-- case 1: state = &tst->arch.vex_shadow1; break;
-- case 2: state = &tst->arch.vex_shadow2; break;
-- default: vg_assert(0);
-- }
--
-- switch (regnum) {
-- case rEAX: VG_(memcpy)(rbuf, &state->guest_EAX, 4); return 4;
-- case rECX: VG_(memcpy)(rbuf, &state->guest_ECX, 4); return 4;
-- case rEDX: VG_(memcpy)(rbuf, &state->guest_EDX, 4); return 4;
-- case rEBX: VG_(memcpy)(rbuf, &state->guest_EBX, 4); return 4;
-- case rESP: VG_(memcpy)(rbuf, &state->guest_ESP, 4); return 4;
-- case rEBP: VG_(memcpy)(rbuf, &state->guest_EBP, 4); return 4;
-- case rESI: VG_(memcpy)(rbuf, &state->guest_ESI, 4); return 4;
-- case rEDI: VG_(memcpy)(rbuf, &state->guest_EDI, 4); return 4;
--
-- case rEIP: VG_(memcpy)(rbuf, &state->guest_EIP, 4); return 4;
-- case rEFLAGS:
-- if (shadow) return 0; // fixme
-- w = LibVEX_GuestX86_get_eflags(state);
-- VG_(memcpy)(rbuf, &w, 4);
-- return 4;
-- case rCS: VG_(memcpy)(rbuf, &state->guest_CS, 2); return 2;
-- case rSS: VG_(memcpy)(rbuf, &state->guest_SS, 2); return 2;
-- case rDS: VG_(memcpy)(rbuf, &state->guest_DS, 2); return 2;
-- case rES: VG_(memcpy)(rbuf, &state->guest_ES, 2); return 2;
-- case rFS: VG_(memcpy)(rbuf, &state->guest_FS, 2); return 2;
-- case rGS: VG_(memcpy)(rbuf, &state->guest_GS, 2); return 2;
--
-- // vex does not simulate 80-bit precision
-- // fixme shift by FTOP?
-- case rST0:
-- case rST1:
-- case rST2:
-- case rST3:
-- case rST4:
-- case rST5:
-- case rST6:
-- case rST7:
-- convert_f64le_to_f80le(&state->guest_FPREG[regnum-rST0], rbuf);
-- return 10;
--
-- case rFCTRL: {
-- // vex only models the rounding bits (see libvex_guest_x86.h)
-- UWord value = 0x037f;
-- value |= state->guest_FPROUND << 10;
-- VG_(memcpy)(rbuf, &value, 4);
-- return 4;
-- }
-- case rFSTAT: {
-- UWord value = state->guest_FC3210;
-- value |= (state->guest_FTOP & 7) << 11;
-- VG_(memcpy)(rbuf, &value, 4);
-- return 4;
-- }
-- case rFTAG: {
-- // vex doesn't model these precisely
-- UWord value =
-- ((state->guest_FPTAG[0] ? 0 : 3) << 0) |
-- ((state->guest_FPTAG[1] ? 0 : 3) << 2) |
-- ((state->guest_FPTAG[2] ? 0 : 3) << 4) |
-- ((state->guest_FPTAG[3] ? 0 : 3) << 6) |
-- ((state->guest_FPTAG[4] ? 0 : 3) << 8) |
-- ((state->guest_FPTAG[5] ? 0 : 3) << 10) |
-- ((state->guest_FPTAG[6] ? 0 : 3) << 12) |
-- ((state->guest_FPTAG[7] ? 0 : 3) << 14);
-- VG_(memcpy)(rbuf, &value, 4);
-- return 4;
-- }
-- case rFISEG:
-- case rFIOFF:
-- case rFOSEG:
-- case rFOOFF:
-- case rFOP: {
-- // fixme lie
-- UWord value = 0;
-- VG_(memcpy)(rbuf, &value, 4);
-- return 4;
-- }
--
-- case rXMM0: VG_(memcpy)(rbuf, &state->guest_XMM0, 16); return 16;
-- case rXMM1: VG_(memcpy)(rbuf, &state->guest_XMM1, 16); return 16;
-- case rXMM2: VG_(memcpy)(rbuf, &state->guest_XMM2, 16); return 16;
-- case rXMM3: VG_(memcpy)(rbuf, &state->guest_XMM3, 16); return 16;
-- case rXMM4: VG_(memcpy)(rbuf, &state->guest_XMM4, 16); return 16;
-- case rXMM5: VG_(memcpy)(rbuf, &state->guest_XMM5, 16); return 16;
-- case rXMM6: VG_(memcpy)(rbuf, &state->guest_XMM6, 16); return 16;
-- case rXMM7: VG_(memcpy)(rbuf, &state->guest_XMM7, 16); return 16;
--
-- case rMXCSR: {
-- // vex only models the rounding bits (see libvex_guest_x86.h)
-- UWord value = 0x1f80;
-- value |= state->guest_SSEROUND << 13;
-- VG_(memcpy)(rbuf, &value, 4);
-- return 4;
-- }
--
-- default: vg_assert(0);
-- }
--
--#elif defined(VGA_amd64)
-- Addr w;
-- VexGuestAMD64State *state;
-- switch (shadow) {
-- case 0: state = &tst->arch.vex; break;
-- case 1: state = &tst->arch.vex_shadow1; break;
-- case 2: state = &tst->arch.vex_shadow2; break;
-- default: vg_assert(0);
-- }
--
-- switch (regnum) {
-- case rRAX: VG_(memcpy)(rbuf, &state->guest_RAX, 8); return 8;
-- case rRCX: VG_(memcpy)(rbuf, &state->guest_RCX, 8); return 8;
-- case rRDX: VG_(memcpy)(rbuf, &state->guest_RDX, 8); return 8;
-- case rRBX: VG_(memcpy)(rbuf, &state->guest_RBX, 8); return 8;
-- case rRSP: VG_(memcpy)(rbuf, &state->guest_RSP, 8); return 8;
-- case rRBP: VG_(memcpy)(rbuf, &state->guest_RBP, 8); return 8;
-- case rRSI: VG_(memcpy)(rbuf, &state->guest_RSI, 8); return 8;
-- case rRDI: VG_(memcpy)(rbuf, &state->guest_RDI, 8); return 8;
--
-- case rR8: VG_(memcpy)(rbuf, &state->guest_R8, 8); return 8;
-- case rR9: VG_(memcpy)(rbuf, &state->guest_R9, 8); return 8;
-- case rR10: VG_(memcpy)(rbuf, &state->guest_R10, 8); return 8;
-- case rR11: VG_(memcpy)(rbuf, &state->guest_R11, 8); return 8;
-- case rR12: VG_(memcpy)(rbuf, &state->guest_R12, 8); return 8;
-- case rR13: VG_(memcpy)(rbuf, &state->guest_R13, 8); return 8;
-- case rR14: VG_(memcpy)(rbuf, &state->guest_R14, 8); return 8;
-- case rR15: VG_(memcpy)(rbuf, &state->guest_R15, 8); return 8;
--
-- case rRIP: VG_(memcpy)(rbuf, &state->guest_RIP, 8); return 8;
-- case rRFLAGS:
-- if (shadow) return 0; // fixme
-- w = LibVEX_GuestAMD64_get_rflags(state);
-- VG_(memcpy)(rbuf, &w, 8);
-- return 8;
-- case rCS: return 0; // fixme state->guest_CS;
-- case rSS: return 0; // fixme state->guest_SS;
-- case rDS: return 0; // fixme state->guest_DS;
-- case rES: return 0; // fixme state->guest_ES;
-- case rFS: return 0; // fixme state->guest_FS;
-- case rGS:
-- VG_(memcpy)(rbuf, &state->guest_GS_0x60, 8); return 8; // fixme state->guest_GS;
--
-- // vex does not simulate 80-bit precision
-- // fixme shift by FTOP?
-- case rST0:
-- case rST1:
-- case rST2:
-- case rST3:
-- case rST4:
-- case rST5:
-- case rST6:
-- case rST7:
-- convert_f64le_to_f80le(&state->guest_FPREG[regnum-rST0], rbuf);
-- return 10;
--
-- case rFCTRL: {
-- // vex only models the rounding bits (see libvex_guest_x86.h)
-- UWord value = 0x037f;
-- value |= state->guest_FPROUND << 10;
-- VG_(memcpy)(rbuf, &value, 4);
-- return 4;
-- }
-- case rFSTAT: {
-- UWord value = state->guest_FC3210;
-- value |= (state->guest_FTOP & 7) << 11;
-- VG_(memcpy)(rbuf, &value, 4);
-- return 4;
-- }
-- case rFTAG: {
-- // vex doesn't model these precisely
-- UWord value =
-- ((state->guest_FPTAG[0] ? 0 : 3) << 0) |
-- ((state->guest_FPTAG[1] ? 0 : 3) << 2) |
-- ((state->guest_FPTAG[2] ? 0 : 3) << 4) |
-- ((state->guest_FPTAG[3] ? 0 : 3) << 6) |
-- ((state->guest_FPTAG[4] ? 0 : 3) << 8) |
-- ((state->guest_FPTAG[5] ? 0 : 3) << 10) |
-- ((state->guest_FPTAG[6] ? 0 : 3) << 12) |
-- ((state->guest_FPTAG[7] ? 0 : 3) << 14);
-- VG_(memcpy)(rbuf, &value, 4);
-- return 4;
-- }
-- case rFISEG:
-- case rFIOFF:
-- case rFOSEG:
-- case rFOOFF:
-- case rFOP: {
-- // fixme lie
-- UWord value = 0;
-- VG_(memcpy)(rbuf, &value, 4);
-- return 4;
-- }
--
-- case rXMM0: VG_(memcpy)(rbuf, &state->guest_XMM0, 16); return 16;
-- case rXMM1: VG_(memcpy)(rbuf, &state->guest_XMM1, 16); return 16;
-- case rXMM2: VG_(memcpy)(rbuf, &state->guest_XMM2, 16); return 16;
-- case rXMM3: VG_(memcpy)(rbuf, &state->guest_XMM3, 16); return 16;
-- case rXMM4: VG_(memcpy)(rbuf, &state->guest_XMM4, 16); return 16;
-- case rXMM5: VG_(memcpy)(rbuf, &state->guest_XMM5, 16); return 16;
-- case rXMM6: VG_(memcpy)(rbuf, &state->guest_XMM6, 16); return 16;
-- case rXMM7: VG_(memcpy)(rbuf, &state->guest_XMM7, 16); return 16;
-- case rXMM8: VG_(memcpy)(rbuf, &state->guest_XMM8, 16); return 16;
-- case rXMM9: VG_(memcpy)(rbuf, &state->guest_XMM9, 16); return 16;
-- case rXMM10: VG_(memcpy)(rbuf, &state->guest_XMM10, 16); return 16;
-- case rXMM11: VG_(memcpy)(rbuf, &state->guest_XMM11, 16); return 16;
-- case rXMM12: VG_(memcpy)(rbuf, &state->guest_XMM12, 16); return 16;
-- case rXMM13: VG_(memcpy)(rbuf, &state->guest_XMM13, 16); return 16;
-- case rXMM14: VG_(memcpy)(rbuf, &state->guest_XMM14, 16); return 16;
-- case rXMM15: VG_(memcpy)(rbuf, &state->guest_XMM15, 16); return 16;
--
-- case rMXCSR: {
-- // vex only models the rounding bits (see libvex_guest_x86.h)
-- UWord value = 0x1f80;
-- value |= state->guest_SSEROUND << 13;
-- VG_(memcpy)(rbuf, &value, 4);
-- return 4;
-- }
--
-- default: vg_assert(0);
-- }
--
--#else
--#error unknown architecture
--#endif
--}
--
--
--static void reg_to_vex(ThreadId tid, Int regnum, const void *rbuf)
--{
--#if defined(VGA_x86)
-- VexGuestX86State *state = &VG_(threads)[tid].arch.vex;
--
-- switch (regnum) {
-- case rEAX: VG_(memcpy)(&state->guest_EAX, rbuf, 4); break;
-- case rECX: VG_(memcpy)(&state->guest_ECX, rbuf, 4); break;
-- case rEDX: VG_(memcpy)(&state->guest_EDX, rbuf, 4); break;
-- case rEBX: VG_(memcpy)(&state->guest_EBX, rbuf, 4); break;
-- case rESP: VG_(memcpy)(&state->guest_ESP, rbuf, 4); break;
-- case rEBP: VG_(memcpy)(&state->guest_EBP, rbuf, 4); break;
-- case rESI: VG_(memcpy)(&state->guest_ESI, rbuf, 4); break;
-- case rEDI: VG_(memcpy)(&state->guest_EDI, rbuf, 4); break;
--
-- case rEIP: VG_(memcpy)(&state->guest_EIP, rbuf, 4); break;
-- case rEFLAGS: break;// fixme LibVEX_GuestX86_put_eflags(state, value);
-- case rCS: VG_(memcpy)(&state->guest_CS, rbuf, 2); break;
-- case rSS: VG_(memcpy)(&state->guest_SS, rbuf, 2); break;
-- case rDS: VG_(memcpy)(&state->guest_DS, rbuf, 2); break;
-- case rES: VG_(memcpy)(&state->guest_ES, rbuf, 2); break;
-- case rFS: VG_(memcpy)(&state->guest_FS, rbuf, 2); break;
-- case rGS: VG_(memcpy)(&state->guest_GS, rbuf, 2); break;
--
-- // vex does not simulate 80-bit precision
-- // fixme shift by FTOP?
-- case rST0:
-- case rST1:
-- case rST2:
-- case rST3:
-- case rST4:
-- case rST5:
-- case rST6:
-- case rST7:
-- convert_f80le_to_f64le(rbuf, &state->guest_FPREG[regnum-rST0]);
-- break;
--
-- case rXMM0: VG_(memcpy)(&state->guest_XMM0, rbuf, 16); break;
-- case rXMM1: VG_(memcpy)(&state->guest_XMM1, rbuf, 16); break;
-- case rXMM2: VG_(memcpy)(&state->guest_XMM2, rbuf, 16); break;
-- case rXMM3: VG_(memcpy)(&state->guest_XMM3, rbuf, 16); break;
-- case rXMM4: VG_(memcpy)(&state->guest_XMM4, rbuf, 16); break;
-- case rXMM5: VG_(memcpy)(&state->guest_XMM5, rbuf, 16); break;
-- case rXMM6: VG_(memcpy)(&state->guest_XMM6, rbuf, 16); break;
-- case rXMM7: VG_(memcpy)(&state->guest_XMM7, rbuf, 16); break;
--
-- default: vg_assert(0);
-- }
--
--#elif defined(VGA_amd64)
-- VexGuestAMD64State *state = &VG_(threads)[tid].arch.vex;
--
-- switch (regnum) {
-- case rRAX: VG_(memcpy)(&state->guest_RAX, rbuf, 8); break;
-- case rRCX: VG_(memcpy)(&state->guest_RCX, rbuf, 8); break;
-- case rRDX: VG_(memcpy)(&state->guest_RDX, rbuf, 8); break;
-- case rRBX: VG_(memcpy)(&state->guest_RBX, rbuf, 8); break;
-- case rRSP: VG_(memcpy)(&state->guest_RSP, rbuf, 8); break;
-- case rRBP: VG_(memcpy)(&state->guest_RBP, rbuf, 8); break;
-- case rRSI: VG_(memcpy)(&state->guest_RSI, rbuf, 8); break;
-- case rRDI: VG_(memcpy)(&state->guest_RDI, rbuf, 8); break;
--
-- case rR8: VG_(memcpy)(&state->guest_R8, rbuf, 8); break;
-- case rR9: VG_(memcpy)(&state->guest_R9, rbuf, 8); break;
-- case rR10: VG_(memcpy)(&state->guest_R10, rbuf, 8); break;
-- case rR11: VG_(memcpy)(&state->guest_R11, rbuf, 8); break;
-- case rR12: VG_(memcpy)(&state->guest_R12, rbuf, 8); break;
-- case rR13: VG_(memcpy)(&state->guest_R13, rbuf, 8); break;
-- case rR14: VG_(memcpy)(&state->guest_R14, rbuf, 8); break;
-- case rR15: VG_(memcpy)(&state->guest_R15, rbuf, 8); break;
--
-- case rRIP: VG_(memcpy)(&state->guest_RIP, rbuf, 8); break;
-- case rRFLAGS: break;// fixme LibVEX_GuestX86_put_eflags(state, value);
-- case rCS: /* fixme state->guest_CS = value; */ break;
-- case rSS: /* fixme state->guest_SS = value; */ break;
-- case rDS: /* fixme state->guest_DS = value; */ break;
-- case rES: /* fixme state->guest_ES = value; */ break;
-- case rFS: /* fixme state->guest_FS = value; */ break;
-- case rGS: /* fixme state->guest_GS = value; */ break;
--
-- // vex does not simulate 80-bit precision
-- // fixme shift by FTOP?
-- case rST0:
-- case rST1:
-- case rST2:
-- case rST3:
-- case rST4:
-- case rST5:
-- case rST6:
-- case rST7:
-- convert_f80le_to_f64le(rbuf, &state->guest_FPREG[regnum-rST0]);
-- break;
--
-- case rXMM0: VG_(memcpy)(&state->guest_XMM0, rbuf, 16); break;
-- case rXMM1: VG_(memcpy)(&state->guest_XMM1, rbuf, 16); break;
-- case rXMM2: VG_(memcpy)(&state->guest_XMM2, rbuf, 16); break;
-- case rXMM3: VG_(memcpy)(&state->guest_XMM3, rbuf, 16); break;
-- case rXMM4: VG_(memcpy)(&state->guest_XMM4, rbuf, 16); break;
-- case rXMM5: VG_(memcpy)(&state->guest_XMM5, rbuf, 16); break;
-- case rXMM6: VG_(memcpy)(&state->guest_XMM6, rbuf, 16); break;
-- case rXMM7: VG_(memcpy)(&state->guest_XMM7, rbuf, 16); break;
-- case rXMM8: VG_(memcpy)(&state->guest_XMM8, rbuf, 16); break;
-- case rXMM9: VG_(memcpy)(&state->guest_XMM9, rbuf, 16); break;
-- case rXMM10: VG_(memcpy)(&state->guest_XMM10, rbuf, 16); break;
-- case rXMM11: VG_(memcpy)(&state->guest_XMM11, rbuf, 16); break;
-- case rXMM12: VG_(memcpy)(&state->guest_XMM12, rbuf, 16); break;
-- case rXMM13: VG_(memcpy)(&state->guest_XMM13, rbuf, 16); break;
-- case rXMM14: VG_(memcpy)(&state->guest_XMM14, rbuf, 16); break;
-- case rXMM15: VG_(memcpy)(&state->guest_XMM15, rbuf, 16); break;
--
-- default: vg_assert(0);
-- }
--
--#else
--#error unknown architecture
--#endif
--}
--
--
--Int VG_(reg_for_regnum)(Int regnum, void *rbuf, Int shadow)
--{
-- // fixme sanitize tid?
-- return reg_from_vex(query_tid, regnum, rbuf, shadow);
--}
--
--
--// DDD: this should be in m_libc somewhere
--static Bool VG_(isxdigit)(int c)
--{
-- if (c >= '0' && c <= '9') return True;
-- if (c >= 'a' && c <= 'f') return True;
-- if (c >= 'A' && c <= 'F') return True;
-- return False;
--}
--
--static Int fromhex(char c)
--{
-- if (c >= '0' && c <= '9') return c - '0';
-- if (c >= 'a' && c <= 'z') return c - 'a' + 10;
-- if (c >= 'A' && c <= 'F') return c - 'A' + 10;
-- return -1;
--}
--
--// len is in BINARY BYTES (sizeof bin, not dst)
--static void hexify(char *dst, const void *bin, Int len)
--{
-- const UChar *src = (const UChar *)bin;
-- const UChar *end = src + len;
--
-- for ( ; src < end; src++) {
-- *dst++ = xdigit[*src >> 4];
-- *dst++ = xdigit[*src & 0xf];
-- }
-- *dst++ = 0;
--}
--
--// len is in BINARY BYTES (sizeof bin, not src)
--static void binify(void *bin, const char *src, Int len)
--{
-- UChar *dst = (UChar *)bin;
-- UChar *end = dst + len;
--
-- for ( ; dst < end; dst++) {
-- *dst = fromhex(*src++) * 16;
-- *dst += fromhex(*src++);
-- }
--}
--
--// like binify, but can write to read-only memory
--static void binify_force(void *bin, unsigned char *src, Int len)
--{
-- mach_vm_address_t vmaddr = (mach_vm_address_t)(uintptr_t)bin;
-- mach_vm_size_t vmsize = len;
-- vm_region_flavor_t flavor = VM_REGION_BASIC_INFO_64;
-- mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
-- vm_region_basic_info_data_64_t data;
-- mach_port_t unused;
-- kern_return_t kr;
--
-- kr = mach_vm_region(mach_task_self(), &vmaddr, &vmsize,
-- flavor, (vm_region_info_t)&data, &count, &unused);
-- if (kr) debuglog("debugger: mach_vm_region failed (%d)", kr);
-- kr = mach_vm_protect(mach_task_self(), vmaddr, vmsize,
-- 0, VM_PROT_READ|VM_PROT_WRITE);
-- if (kr) debuglog("debugger: mach_vm_protect failed (%d)", kr);
--
-- binify(bin, src, len);
--
-- kr = mach_vm_protect(mach_task_self(), vmaddr, vmsize, 0, data.protection);
-- if (kr) debuglog("debugger: mach_vm_protect failed (%d)", kr);
--}
--
--static ThreadId current_tid(void)
--{
-- ThreadId tid = VG_(last_running_tid);
-- if (VG_(is_valid_tid)(tid)) {
-- return tid;
-- }
--
-- // find a new thread
-- for (tid = 1; tid < VG_N_THREADS; tid++) {
-- if (VG_(is_valid_tid)(tid)) {
-- return tid;
-- }
-- }
--
-- return 0;
--}
--
--
--static Int listen_to(Int port)
--{
-- Int opt;
-- Int serv;
-- Int err;
-- vki_socklen_t size;
-- struct vki_sockaddr_in addr = { sizeof(struct vki_sockaddr_in), VKI_AF_INET, VG_(htons)(port), {VG_(htonl)(VKI_INADDR_LOOPBACK)} };
--
-- serv = VG_(socket)(VKI_AF_INET, VKI_SOCK_STREAM, 0);
-- if (serv < 0) {
-- return -1;
-- }
-- serv = VG_(safe_fd)(serv);
-- if (serv < 0) {
-- return -1;
-- }
--
-- // set SO_REUSEADDR to help prevent "address already in use" errors
-- opt = 1;
-- VG_(setsockopt)(serv, VKI_SOL_SOCKET, VKI_SO_REUSEADDR, &opt, sizeof(opt));
--
-- size = sizeof(addr);
-- err = VG_(bind)(serv, (struct vki_sockaddr *)&addr, size);
-- if (err < 0) {
-- VG_(close)(serv);
-- return -1;
-- }
--
-- err = VG_(listen)(serv, 1);
-- if (err < 0) {
-- VG_(close)(serv);
-- return -1;
-- }
--
-- return serv;
--}
--
--
--static Int accept_from(Int serv)
--{
-- Int sock;
-- struct vki_sockaddr_in addr;
-- vki_socklen_t size;
--
-- size = sizeof(addr);
-- sock = VG_(accept)(serv, (struct vki_sockaddr *)&addr, &size);
-- if (sock < 0) {
-- return -1;
-- }
-- sock = VG_(safe_fd)(sock);
-- if (sock < 0) {
-- return -1;
-- }
--
-- return sock;
--}
--
--
--static char *read_command(Int sock)
--{
-- char checksum[2];
-- char *p = msgbuf;
-- Int count;
-- char c;
--
-- // read '$'
-- do {
-- count = VG_(read)(sock, &c, 1);
-- } while (count == 1 && c != '$');
-- if (count != 1) {
-- debuglog("debugger: failed while looking for '$'");
-- return NULL;
-- }
--
-- // read through '#'
-- do {
-- count = VG_(read)(sock, &c, 1);
-- *p++ = c;
-- if (p == msgbuf+msgbufsize) {
-- debuglog("debugger: command too large");
-- return NULL;
-- }
-- } while (count == 1 && c != '#');
-- if (count != 1) {
-- debuglog("debugger: failed while looking for '#'");
-- return NULL;
-- }
-- vg_assert(p > msgbuf && p < msgbuf+msgbufsize);
-- p[-1] = 0; // overwrite '#'
--
-- // read checksum
-- do {
-- count = VG_(read)(sock, &checksum[0], 1);
-- } while (count != 1);
-- if (count != 1) {
-- debuglog("debugger: failed while looking for checksum digit");
-- return NULL;
-- }
-- do {
-- count = VG_(read)(sock, &checksum[1], 1);
-- } while (count != 1);
-- if (count != 1) {
-- debuglog("debugger: failed while looking for checksum digit");
-- return NULL;
-- }
--
-- // check checksum
-- // fixme actually do the sum
-- if (!VG_(isxdigit)(checksum[0]) || !VG_(isxdigit)(checksum[1])) {
-- debuglog("bad checksum digits %c%c", checksum[0], checksum[1]);
-- }
--
-- // acknoledge
-- VG_(write)(sock, "+", 1);
--
-- debuglog("debugger: received command '%s'", msgbuf);
--
-- return VG_(arena_strdup)(VG_AR_CORE, "debugstub.msg", msgbuf);
--}
--
--
--static void write_command(Int sock, const char *cmd)
--{
-- const char *p;
-- unsigned int sum = 0;
-- char suffix[3];
-- // Int count;
-- // char c;
--
-- // compute checksum
-- for (p = cmd; *p; p++) {
-- sum += (unsigned char)*p;
-- }
-- sum &= 0xff;
--
-- suffix[0] = '#';
-- suffix[1] = xdigit[sum >> 4];
-- suffix[2] = xdigit[sum & 0x0f];
--
-- // write $cmd#ck
-- VG_(write)(sock, "$", 1);
-- VG_(write)(sock, cmd, VG_(strlen)(cmd));
-- VG_(write)(sock, suffix, sizeof(suffix));
-- debuglog("debugger: sent command '%s'", cmd);
--
-- // read '+'
-- /*
-- do {
-- count = read(sock, &c, 1);
-- } while (count == 1);
-- if (count != 1 || c != '+') return fail("packet not acknowledged");
-- */
--}
--
--static void list_threads(Int sock)
--{
-- ThreadId tid;
-- char *p;
-- char prefix;
--
-- prefix = 'm'; // first thread starts with 'm'
-- p = outbuf;
-- for (tid = 1; tid < VG_N_THREADS; tid++) {
-- if (VG_(is_valid_tid)(tid)) {
-- p += VG_(sprintf)(p, "%c%08x", prefix, tid);
-- prefix = ','; // comma-separated after first
-- }
-- }
-- write_command(sock, outbuf);
--}
--
--static void handle_m(Int sock, char *cmd)
--{
-- Long addr, len;
--
-- addr = VG_(strtoll16)(cmd, NULL);
-- cmd = VG_(strchr)(cmd, ',');
-- if (!cmd) {
-- write_command(sock, "E01"); // fixme errno
-- return;
-- }
-- len = VG_(strtoll16)(cmd+1, NULL);
-- if (len > (sizeof(outbuf)-1) / 2) len = (sizeof(outbuf)-1) / 2;
--
-- if (! VG_(am_is_valid_for_client)((Addr)addr, (SizeT)len, VKI_PROT_READ)) {
-- write_command(sock, "E14"); // fixme EFAULT
-- return;
-- }
--
-- hexify(outbuf, (char *)(Addr)addr, len);
-- write_command(sock, outbuf);
--}
--
--static void handle_M(Int sock, char *cmd)
--{
-- Long addr, len;
-- unsigned char *inbuf;
--
-- addr = VG_(strtoll16)(cmd, NULL);
--
-- cmd = VG_(strchr)(cmd, ',');
-- if (!cmd) {
-- write_command(sock, "E01"); // fixme errno
-- return;
-- }
-- len = VG_(strtoll16)(cmd+1, NULL);
--
-- if (! VG_(am_is_valid_for_client)((Addr)addr, (SizeT)len, VKI_PROT_READ)) {
-- write_command(sock, "E14"); // fixme EFAULT
-- return;
-- }
--
-- inbuf = VG_(strchr)(cmd, ':');
-- if (!inbuf) {
-- write_command(sock, "E01");
-- return;
-- }
-- inbuf++;
--
-- binify_force((char *)(Addr)addr, inbuf, len);
-- VG_TRACK( post_mem_write, Vg_CoreClientReq/*fixme?*/, 1/*fixme*/, addr, len);
-- VG_(discard_translations)(addr, len, "debugger(M)");
--
-- write_command(sock, "OK");
--}
--
--
--
--static Bool handle_q_valgrind(Int sock, char *cmd)
--{
-- Bool handled = True; // False means unknown valgrind query command
-- Char *toolname = VG_(details).name;
-- Int toollen = VG_(strlen)(VG_(details).name);
--
-- debuglog("qvalgrind command %s", cmd);
--
-- if (VG_(needs).debugger_commands &&
-- VG_(tdict).tool_handle_debugger_query &&
-- 0 == VG_(strncmp)(cmd, toolname, toollen) &&
-- cmd[toollen] == '.')
-- {
-- debuglog("forwarding %s to tool", cmd);
-- handled = VG_(tdict).tool_handle_debugger_query(sock, cmd+toollen+1);
-- }
-- /*
-- else if (0 == VG_(strncmp)(cmd, "core.", 5)) {
-- // any core-provided commands go here
-- }
-- */
-- else {
-- handled = False;
-- }
--
-- return handled;
--}
--
--static Bool handle_q(Int sock, char *cmd)
--{
-- Bool handled = True; // False means unknown query command
--
-- debuglog("q command %s", cmd);
--
-- if (0 == VG_(strcmp)(cmd, "C")) {
-- // current thread
-- VG_(sprintf)(outbuf, "QC%04x", current_tid());
-- write_command(sock, outbuf);
-- }
-- else if (0 == VG_(strcmp)(cmd, "fThreadInfo")) {
-- // thread list
-- list_threads(sock);
-- }
-- else if (0 == VG_(strcmp)(cmd, "sThreadInfo")) {
-- // fThreadInfo continuation - we did it all the first time
-- write_command(sock, "l");
-- }
-- else if (0 == VG_(strcmp)(cmd, "Offsets")) {
-- // text and data offsets
-- // fixme hack
-- write_command(sock, "Text=0;Data=0;Bss=0");
-- }
-- else if (0 == VG_(strcmp)(cmd, "valgrind")) {
-- // valgrind existence query - reply with tool name
-- write_command(sock, VG_(details).name);
-- }
-- else if (0 == VG_(strncmp)(cmd, "valgrind.", 9)) {
-- // valgrind subcommand
-- handled = handle_q_valgrind(sock, cmd+9);
-- }
-- else {
-- // unknown query
-- handled = False;
-- }
--
-- return handled;
--}
--
--
--static Bool handle_Q_valgrind(Int sock, char *cmd)
--{
-- Bool handled = True; // False means unknown valgrind action command
-- Char *toolname = VG_(details).name;
-- Int toollen = VG_(strlen)(VG_(details).name);
--
-- if (VG_(needs).debugger_commands &&
-- VG_(tdict).tool_handle_debugger_action &&
-- 0 == VG_(strncmp)(cmd, toolname, toollen) &&
-- cmd[toollen] == '.')
-- {
-- debuglog("forwarding %s to tool", cmd);
-- handled = VG_(tdict).tool_handle_debugger_action(sock, cmd+toollen+1);
-- }
-- /*
-- else if (0 == VG_(strncmp)(cmd, "core.", 5)) {
-- // any core-provided commands go here
-- }
-- */
-- else {
-- handled = False;
-- }
--
-- return handled;
--}
--
--static Bool handle_Q(Int sock, char *cmd)
--{
-- Bool handled = True; // False means unknown action command
--
-- if (0 == VG_(strncmp)(cmd, "valgrind.", 10)) {
-- // valgrind subcommand
-- handled = handle_Q_valgrind(sock, cmd+10);
-- }
-- else {
-- // unknown query
-- handled = False;
-- }
--
-- return handled;
--}
--
--
--__attribute__((unused))
--static Bool handle_v(Int sock, char *cmd)
--{
-- if (0 == VG_(strncmp)(cmd, "Cont", 4)) {
-- // vCont
-- if (0 == VG_(strcmp)(cmd, "Cont?")) {
-- // capability query
-- // fixme can't really handle C/s/S, but gdb won't use c otherwise
-- write_command(sock, "vCont;c;C;s;S");
-- return True;
-- }
-- else if (0 == VG_(strncmp)(cmd, "Cont;", 5)) {
-- // continue command
-- ThreadId tid = -1;
-- Bool continueOthers = True;
--
-- cmd += 5;
-- // fixme this only handles a subset of possible vCont commands,
-- // but gdb only generates a subset anyway
-- // fixme incorrect C/S/s handling
-- switch (cmd[0]) {
-- case 'c':
-- case 's':
-- cmd++;
-- break;
-- case 'C':
-- case 'S':
-- cmd += 3; // skip signal number
-- break;
-- default:
-- return False;
-- }
-- if (cmd[0] == ':') {
-- // target thread ID
-- tid = VG_(strtoll16)(cmd+1, NULL);
-- continueOthers = False;
-- }
--
-- // command for other threads - assume 'c' or empty
-- cmd = VG_(strchr)(cmd, ';');
-- if (cmd) {
-- if (cmd[0] == 'c') continueOthers = True;
-- }
--
-- if (tid != -1 && !continueOthers) {
-- // Run tid only
-- } else if (tid) {
-- // Run all threads, tid first
-- } else {
-- // Run all threads
-- }
--
-- return True;
-- }
-- }
--
-- return False;
--}
--
--
--static void handle_p(Int sock, char *cmd)
--{
-- char rbuf[16];
-- int rsize;
-- Long reg = VG_(strtoll16)(cmd, NULL);
-- if (!VG_(is_valid_tid)(query_tid)) {
-- write_command(sock, "E01"); // fixme errno
-- } else if (reg < 0 || reg >= rcount) {
-- write_command(sock, "E01");
-- } else {
-- rsize = reg_from_vex(query_tid, reg, rbuf, 0);
-- hexify(outbuf, rbuf, rsize);
-- write_command(sock, outbuf);
-- }
--}
--
--static void handle_P(Int sock, char *cmd)
--{
-- uint8_t rbuf[16] = {0};
-- int rsize;
--
-- Long reg = VG_(strtoll16)(cmd, NULL);
-- cmd = VG_(strchr)(cmd, '=');
-- if (!cmd) {
-- write_command(sock, "E01");
-- return;
-- }
-- cmd++;
--
-- rsize = VG_(strlen)(cmd) / 2;
-- vg_assert(rsize <= 16);
-- binify(rbuf, cmd, rsize);
-- /*
-- char oldbuf[16];
-- int oldsize = reg_from_vex(query_tid, reg, oldbuf, 0);
-- if (rsize == oldsize && 0 == VG_(memcmp)(rbuf, oldbuf, rsize)) {
-- // no change - ok for any register
-- write_command(sock, "OK");
-- return;
-- }
-- */
-- // fixme can't change all registers all the time
-- // - can't change PC during error report
-- // - other registers during error report?
-- if (reg == rPC && stop_sig != 5) {
-- write_command(sock, "E01");
-- return;
-- }
-- reg_to_vex(query_tid, reg, rbuf);
-- debuglog("pc %p", VG_(threads)[query_tid].arch.vex.guest_PC);
-- write_command(sock, "OK");
--}
--
--static void handle_T(Int sock, char *cmd)
--{
-- Long tid = VG_(strtoll16)(cmd, NULL);
-- if (VG_(is_valid_tid)(tid)) {
-- write_command(sock, "OK");
-- } else {
-- write_command(sock, "E01");
-- }
--}
--
--static void handle_g(Int sock)
--{
-- Addr regs[grcount];
-- Int r;
--
-- if (!VG_(is_valid_tid)(query_tid)) {
-- write_command(sock, "E01"); // fixme errno
-- return;
-- }
--
-- for (r = 0; r < grcount; r++) {
-- reg_from_vex(query_tid, r, ®s[r], 0);
-- }
--
-- hexify(outbuf, (char *)regs, sizeof(regs));
-- write_command(sock, outbuf);
--}
--
--
--static void handle_G(Int sock, char *cmd)
--{
-- Addr regs[grcount];
-- Int r;
--
-- if (!VG_(is_valid_tid)(query_tid)) {
-- write_command(sock, "E01"); // fixme errno
-- return;
-- }
--
-- if (VG_(strlen)(cmd) != 2 * sizeof(regs)) {
-- write_command(sock, "E01"); // fixme errno
-- return;
-- }
--
-- binify((char *)regs, cmd, sizeof(regs));
--
-- for (r = 0; r < grcount; r++) {
-- reg_to_vex(query_tid, r, ®s[r]);
-- }
--
-- write_command(sock, "OK");
--}
--
--
--static Bool handle_why(Int sock)
--{
-- if (stop_tid) {
-- VG_(sprintf)(outbuf, "T%02xthread:%x;", stop_sig, stop_tid);
-- } else {
-- VG_(sprintf)(outbuf, "T%02xthread:%x;", 0, query_tid);
-- }
-- write_command(sock, outbuf);
-- return True;
--}
--
--// run until remote debugger or local tools asks us to stop
--// return False if debugger disconnects
--static Bool do_continue(Int sock)
--{
-- Bool halt = False;
--
-- VG_(message)(Vg_UserMsg, "Continuing.");
--
-- debugger_unlock();
--
-- while (1) {
-- int selected;
-- int nfds = 1 + (sock > debugger_notify[0] ? sock : debugger_notify[0]);
-- fd_set fds;
-- FD_ZERO(&fds);
-- FD_SET(sock, &fds);
-- FD_SET(debugger_notify[0], &fds);
-- selected = VG_(select)(nfds, &fds, NULL, NULL, NULL);
--
-- if (FD_ISSET(sock, &fds)) {
-- char c;
-- Int count = VG_(read)(sock, &c, 1);
-- if (count != 1) {
-- halt = True;
-- break;
-- } else if (c == 0x03) {
-- break;
-- }
-- }
-- if (FD_ISSET(debugger_notify[0], &fds)) {
-- Int count = VG_(read)(debugger_notify[0], &stop_tid, sizeof(stop_tid));
-- count += VG_(read)(debugger_notify[0], &stop_sig, sizeof(stop_sig));
-- if (count == sizeof(stop_tid)+sizeof(stop_sig)) {
-- break;
-- } else {
-- stop_tid = 0;
-- stop_sig = 0;
-- }
-- }
-- }
--
-- debugger_lock(sock);
--
-- if (halt) {
-- ...
[truncated message content] |