]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Prepare for AVX support : restructure gdbsrv/target/valgrind-low/arch low
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Wed, 23 May 2012 21:50:36 +0000 (21:50 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Wed, 23 May 2012 21:50:36 +0000 (21:50 +0000)
AVX support implies to have target xml files which are selected
according to the machine hwcaps.
This change improves the structure of the gdbserver software layering
to prepare for this.

Basically, the protocol files (e.g. server.c) are now calling directly
the valgrind target operations which are now defined in target.h/target.c
(before, there was a level of indirection inheritated from the GDB
structure which was useless for valgrind gdbserver).
+ clarified some comments

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12579

12 files changed:
coregrind/Makefile.am
coregrind/m_gdbserver/m_gdbserver.c
coregrind/m_gdbserver/regcache.c
coregrind/m_gdbserver/remote-utils.c
coregrind/m_gdbserver/server.c
coregrind/m_gdbserver/server.h
coregrind/m_gdbserver/target.c
coregrind/m_gdbserver/target.h
coregrind/m_gdbserver/valgrind-low-amd64.c
coregrind/m_gdbserver/valgrind-low-x86.c
coregrind/m_gdbserver/valgrind-low.c [deleted file]
coregrind/m_gdbserver/valgrind_low.h

index 329a01bdac4a13d53df3e7fc0da0af3725f6da26..2cc83b982f5b4f923295578c0246db83c751ccb0 100644 (file)
@@ -312,7 +312,6 @@ COREGRIND_SOURCES_COMMON = \
        m_gdbserver/signals.c \
        m_gdbserver/target.c \
        m_gdbserver/utils.c \
-       m_gdbserver/valgrind-low.c \
        m_gdbserver/valgrind-low-x86.c \
        m_gdbserver/valgrind-low-amd64.c \
        m_gdbserver/valgrind-low-arm.c \
index f3d3d507f0758243d68116d64c24a7327f5003cc..42bb198dd0b0fa7d7ea75f1073ac9b104de7a025 100644 (file)
@@ -130,13 +130,6 @@ static Addr ignore_this_break_once = 0;
 
 static void call_gdbserver ( ThreadId tid , CallReason reason);
 
-/* convert from CORE_ADDR to void* */
-static
-void* C2v(CORE_ADDR addr)
-{
-   return (void*) addr;
-}
-
 /* Describes the address addr (for debugging/printing purposes).
    Last two results are kept. A third call will replace the
    oldest result. */
index a9202316f2f72768f6fd466496a8ead1eeda0489..477c208d52a9596ab9de6dff31839276027127a0 100644 (file)
@@ -54,7 +54,7 @@ struct inferior_regcache_data * get_regcache (struct thread_info *inf,
 
    /* FIXME - fetch registers for INF */
    if (fetch && regcache->registers_valid == 0) {
-      fetch_inferior_registers (0);
+      valgrind_fetch_registers (0);
       regcache->registers_valid = 1;
    }
 
@@ -72,7 +72,7 @@ void regcache_invalidate_one (struct inferior_list_entry *entry)
       struct thread_info *saved_inferior = current_inferior;
 
       current_inferior = thread;
-      store_inferior_registers (-1);
+      valgrind_store_registers (-1);
       current_inferior = saved_inferior;
    }
 
index 88b903f01e955e092f2beb713bf9d0fd2774f242..009f3275bd10b03e414d98673a1d2fe72bcac8cf 100644 (file)
@@ -542,6 +542,29 @@ int hexify (char *hex, const char *bin, int count)
   return i;
 }
 
+/* builds an image of bin according to byte order of the architecture 
+   Useful for register and int image */
+char* heximage (char *buf, char *bin, int count)
+{
+#if defined(VGA_x86) || defined(VGA_amd64)
+   char rev[count]; 
+   /* note: no need for trailing \0, length is known with count */
+  int i;
+  for (i = 0; i < count; i++)
+    rev[i] = bin[count - i - 1];
+  hexify (buf, rev, count);
+#else
+  hexify (buf, bin, count);
+#endif
+  return buf;
+}
+
+void* C2v(CORE_ADDR addr)
+{
+   return (void*) addr;
+}
+
+
 /* Convert BUFFER, binary data at least LEN bytes long, into escaped
    binary data in OUT_BUF.  Set *OUT_LEN to the length of the data
    encoded in OUT_BUF, and return the number of bytes in OUT_BUF
@@ -729,7 +752,7 @@ int putpkt_binary (char *buf, int cnt)
 
       /* Check for an input interrupt while we're here.  */
       if (cc == '\003')
-         (*the_target->send_signal) (VKI_SIGINT);
+         dlog(1, "Received 0x03 character (SIGINT)\n");
    }
    while (cc != '+');
 
@@ -962,15 +985,14 @@ void prepare_resume_reply (char *buf, char status, unsigned char sig)
    if (status == 'T') {
       const char **regp = gdbserver_expedite_regs;
       
-      if (the_target->stopped_by_watchpoint != NULL
-         && (*the_target->stopped_by_watchpoint) ()) {
+      if (valgrind_stopped_by_watchpoint()) {
          CORE_ADDR addr;
          int i;
 
          strncpy (buf, "watch:", 6);
          buf += 6;
 
-         addr = (*the_target->stopped_data_address) ();
+         addr = valgrind_stopped_data_address ();
 
          /* Convert each byte of the address into two hexadecimal chars.
             Note that we take sizeof (void *) instead of sizeof (addr);
index 4eb325c54b7c1c49d15ce2e7617dc138088c0643..58fb2295ac484c21e1c093641cb8d96628d13d94 100644 (file)
@@ -38,11 +38,13 @@ int pass_signals[TARGET_SIGNAL_LAST]; /* indexed by gdb signal nr */
 
 /* for a gdbserver integrated in valgrind, resuming the process consists
    in returning the control to valgrind.
+   The guess process resumes its execution.
    Then at the next error or break or ..., valgrind calls gdbserver again.
-   A resume packet must then be built.
-   resume_packet_needed records the fact that the next call to gdbserver
+   A resume reply packet must then be built to inform GDB that the
+   resume request is finished.
+   resume_reply_packet_needed records the fact that the next call to gdbserver
    must send a resume packet to gdb. */
-static Bool resume_packet_needed = False;
+static Bool resume_reply_packet_needed = False;
 
 VG_MINIMAL_JMP_BUF(toplevel);
 
@@ -530,8 +532,8 @@ void handle_query (char *arg_own_buf, int *new_packet_len_p)
       }
    }
 
-   if ( ((*the_target->target_xml)() != NULL 
-         || (*the_target->shadow_target_xml)() != NULL)
+   if ( (valgrind_target_xml() != NULL 
+         || valgrind_shadow_target_xml() != NULL)
         && strncmp ("qXfer:features:read:", arg_own_buf, 20) == 0) {
       CORE_ADDR ofs;
       unsigned int len, doc_len;
@@ -553,13 +555,13 @@ void handle_query (char *arg_own_buf, int *new_packet_len_p)
             shadow_target_xml. Fallback to target_xml
             if not defined. */
          if (VG_(clo_vgdb_shadow_registers)) {
-            annex = (*the_target->shadow_target_xml)();
+            annex = valgrind_shadow_target_xml();
             if (annex != NULL)
                /* Ensure the shadow registers are initialized. */
                initialize_shadow_low(True);
          }
          if (annex == NULL)
-            annex = (*the_target->target_xml)();
+            annex = valgrind_target_xml();
          if (annex == NULL) {
             strcpy (arg_own_buf, "E00");
             return;
@@ -667,8 +669,8 @@ void handle_query (char *arg_own_buf, int *new_packet_len_p)
       if (VG_(client_auxv))
          strcat (arg_own_buf, ";qXfer:auxv:read+");
 
-      if ((*the_target->target_xml)() != NULL
-          || (*the_target->shadow_target_xml)() != NULL) {
+      if (valgrind_target_xml() != NULL
+          || valgrind_shadow_target_xml() != NULL) {
          strcat (arg_own_buf, ";qXfer:features:read+");
          /* if a new gdb connects to us, we have to reset the register
             set to the normal register sets to allow this new gdb to
@@ -707,21 +709,16 @@ void myresume (int step, int sig)
    struct thread_resume resume_info[2];
    int n = 0;
 
-   if (step || sig || (cont_thread != 0 && cont_thread != -1)) {
-      resume_info[0].thread
-         = ((struct inferior_list_entry *) current_inferior)->id;
+   if (step || sig) {
       resume_info[0].step = step;
       resume_info[0].sig = sig;
-      resume_info[0].leave_stopped = 0;
       n++;
    }
-   resume_info[n].thread = -1;
    resume_info[n].step = 0;
    resume_info[n].sig = 0;
-   resume_info[n].leave_stopped = (cont_thread != 0 && cont_thread != -1);
 
-   resume_packet_needed = True;
-   (*the_target->resume) (resume_info);
+   resume_reply_packet_needed = True;
+   valgrind_resume (resume_info);
 }
 
 /* server_main global variables */
@@ -732,7 +729,7 @@ void gdbserver_init (void)
 {
    dlog(1, "gdbserver_init gdbserver embedded in valgrind: %s\n", version);
    noack_mode = False;
-   initialize_low ();
+   valgrind_initialize_target ();
    // After a fork, gdbserver_init can be called again.
    // We do not have to re-malloc the buffers in such a case.
    if (own_buf == NULL)
@@ -761,7 +758,7 @@ void server_main (void)
    unsigned int len;
    CORE_ADDR mem_addr;
 
-   zignal = mywait (&status);
+   zignal = valgrind_wait (&status);
    if (VG_MINIMAL_SETJMP(toplevel)) {
       dlog(0, "error caused VG_MINIMAL_LONGJMP to server_main\n");
    }
@@ -770,8 +767,10 @@ void server_main (void)
       int packet_len;
       int new_packet_len = -1;
       
-      if (resume_packet_needed) {
-         resume_packet_needed = False;
+      if (resume_reply_packet_needed) {
+         /* Send the resume reply to reply to last GDB resume
+            request. */
+         resume_reply_packet_needed = False;
          prepare_resume_reply (own_buf, status, zignal);
          putpkt (own_buf);
       }
@@ -804,7 +803,7 @@ void server_main (void)
          remote_finish (reset_after_error);
          remote_open (VG_(clo_vgdb_prefix));
          myresume (0, 0);
-         resume_packet_needed = False;
+         resume_reply_packet_needed = False;
          return;
       case '!':
          /* We can not use the extended protocol with valgrind,
@@ -890,14 +889,14 @@ void server_main (void)
       }
       case 'm':
          decode_m_packet (&own_buf[1], &mem_addr, &len);
-         if (read_inferior_memory (mem_addr, mem_buf, len) == 0)
+         if (valgrind_read_memory (mem_addr, mem_buf, len) == 0)
             convert_int_to_ascii (mem_buf, own_buf, len);
          else
             write_enn (own_buf);
          break;
       case 'M':
          decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
-         if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
+         if (valgrind_write_memory (mem_addr, mem_buf, len) == 0)
             write_ok (own_buf);
          else
             write_enn (own_buf);
@@ -905,7 +904,7 @@ void server_main (void)
       case 'X':
          if (decode_X_packet (&own_buf[1], packet_len - 1,
                               &mem_addr, &len, mem_buf) < 0
-             || write_inferior_memory (mem_addr, mem_buf, len) != 0)
+             || valgrind_write_memory (mem_addr, mem_buf, len) != 0)
             write_enn (own_buf);
          else
             write_ok (own_buf);
@@ -943,15 +942,13 @@ void server_main (void)
          int zlen = strtol (lenptr + 1, &dataptr, 16);
          char type = own_buf[1];
          
-         if (the_target->insert_watchpoint == NULL
-             || (type < '0' || type > '4')) {
-            /* No watchpoint support or not a watchpoint command;
-               unrecognized either way.  */
+         if (type < '0' || type > '4') {
+            /* Watchpoint command type unrecognized. */
             own_buf[0] = '\0';
          } else {
             int res;
             
-            res = (*the_target->insert_watchpoint) (type, addr, zlen);
+            res = valgrind_insert_watchpoint (type, addr, zlen);
             if (res == 0)
                write_ok (own_buf);
             else if (res == 1)
@@ -969,15 +966,13 @@ void server_main (void)
          int zlen = strtol (lenptr + 1, &dataptr, 16);
          char type = own_buf[1];
          
-         if (the_target->remove_watchpoint == NULL
-             || (type < '0' || type > '4')) {
-            /* No watchpoint support or not a watchpoint command;
-               unrecognized either way.  */
+         if (type < '0' || type > '4') {
+            /* Watchpoint command type unrecognized. */
             own_buf[0] = '\0';
          } else {
             int res;
             
-            res = (*the_target->remove_watchpoint) (type, addr, zlen);
+            res = valgrind_remove_watchpoint (type, addr, zlen);
             if (res == 0)
                write_ok (own_buf);
             else if (res == 1)
@@ -1001,7 +996,7 @@ void server_main (void)
             break;
          }
 
-         if (mythread_alive (thread_id))
+         if (valgrind_thread_alive (thread_id))
             write_ok (own_buf);
          else
             write_enn (own_buf);
@@ -1055,6 +1050,6 @@ void server_main (void)
    remote_finish (reset_after_error);
    remote_open (VG_(clo_vgdb_prefix)); 
    myresume (0, 0);
-   resume_packet_needed = False;
+   resume_reply_packet_needed = False;
    return;
 }
index a88bc03050e2caa5f357da3b16fb37a6a8749eb0..077a65876029bcb10a4a96c37ab0b30053634a0c 100644 (file)
@@ -107,34 +107,6 @@ extern void reset_valgrind_sink(char* info);
    If debug info not found for this pc, assumes arm */
 extern Addr thumb_pc (Addr pc);
 
-/* True if gdbserver is single stepping the valgrind process */
-extern Bool valgrind_single_stepping(void);
-
-/* Set Valgrind in single stepping mode or not according to Bool. */
-extern void valgrind_set_single_stepping(Bool);
-
-/* gets the addr at which a (possible) break must be ignored once.
-   If there is no such break to be ignored once, 0 is returned.
-   This is needed for the following case:
-   The user sets a break at address AAA.
-   The break is encountered. Then the user does stepi 
-   (i.e. step one instruction).
-   In such a case, the already encountered break must be ignored
-   to ensure the stepi will advance by one instruction: a "break"
-   is implemented in valgrind by some helper code just after the
-   instruction mark at which the break is set. This helper code
-   verifies if either there is a break at the current PC
-   or if we are in stepping mode. If we are in stepping mode,
-   the already encountered break must be ignored once to advance
-   to the next instruction.
-   ??? need to check if this is *really* needed. */
-extern Addr valgrind_get_ignore_break_once(void);
-
-/* When addr > 0, ensures the next stop reply packet informs
-   gdb about the encountered watchpoint.
-   Use addr 0x0 to reset. */
-extern void VG_(set_watchpoint_stop_address) (Addr addr);
-
 /* when invoked by vgdb using ptrace, contains the tid chosen
    by vgdb (if vgdb gives a tid different of 0: a 0 tid by
    vgdb means use the running_tid if there is one running
@@ -249,13 +221,6 @@ extern int pass_signals[]; /* indexed by gdb signal nr */
 
 /* Target-specific functions */
 
-void initialize_low (void);
-
-/* initialize or re-initialize the register set of the low target.
-   if shadow_mode, then (re-)define the normal and valgrind shadow registers
-   else (re-)define only the normal registers. */
-void initialize_shadow_low (Bool shadow_mode);
-
 /* From inferiors.c.  */
 
 extern struct inferior_list all_threads;
@@ -323,6 +288,14 @@ int decode_X_packet (char *from, int packet_len, CORE_ADDR * mem_addr_ptr,
 
 int unhexify (char *bin, const char *hex, int count);
 int hexify (char *hex, const char *bin, int count);
+/* heximage builds an image of bin according to byte order of the architecture 
+   Useful for register and int image */
+char* heximage (char *buf, char *bin, int count);
+
+/* convert from CORE_ADDR to void* */
+void* C2v(CORE_ADDR addr);
+
+
 int remote_escape_output (const gdb_byte *buffer, int len,
                          gdb_byte *out_buf, int *out_len,
                          int out_maxlen);
index c72c761bf37dfebf861e0bb56500b8eabf7d0d96..0a4094e1d91c0c16ebcb309188b4457259572ac9 100644 (file)
    Boston, MA 02110-1301, USA.  */
 
 #include "server.h"
+#include "target.h"
+#include "regdef.h"
+#include "regcache.h"
+#include "valgrind_low.h"
+#include "gdb/signals.h"
+#include "pub_core_aspacemgr.h"
+#include "pub_tool_machine.h"
+#include "pub_core_threadstate.h"
+#include "pub_core_transtab.h"
+#include "pub_core_gdbserver.h" 
+#include "pub_tool_debuginfo.h"
 
-struct target_ops *the_target;
+
+/* the_low_target defines the architecture specific aspects depending
+   on the cpu */
+static struct valgrind_target_ops the_low_target;
+
+static
+char *image_ptid(unsigned long ptid)
+{
+  static char result[100];
+  VG_(sprintf) (result, "id %ld", ptid);
+  return result;
+}
+#define get_thread(inf) ((struct thread_info *)(inf))
+static
+void remove_thread_if_not_in_vg_threads (struct inferior_list_entry *inf)
+{
+  struct thread_info *thread = get_thread (inf);
+  if (!VG_(lwpid_to_vgtid)(thread_to_gdb_id(thread))) {
+     dlog(1, "removing gdb ptid %s\n", 
+          image_ptid(thread_to_gdb_id(thread)));
+     remove_thread (thread);
+  }
+}
+
+/* synchronize threads known by valgrind and threads known by gdbserver */
+static
+void valgrind_update_threads (int pid)
+{
+  ThreadId tid;
+  ThreadState *ts;
+  unsigned long ptid;
+  struct thread_info *ti;
+
+  /* call remove_thread for all gdb threads not in valgrind threads */
+  for_each_inferior (&all_threads, remove_thread_if_not_in_vg_threads);
+  
+  /* call add_thread for all valgrind threads not known in gdb all_threads */
+  for (tid = 1; tid < VG_N_THREADS; tid++) {
+
+#define LOCAL_THREAD_TRACE " ti* %p vgtid %d status %s as gdb ptid %s lwpid %d\n", \
+        ti, tid, VG_(name_of_ThreadStatus) (ts->status), \
+        image_ptid (ptid), ts->os_state.lwpid
+
+     if (VG_(is_valid_tid) (tid)) {
+        ts = VG_(get_ThreadState) (tid);
+        ptid = ts->os_state.lwpid;
+        ti = gdb_id_to_thread (ptid);
+        if (!ti) {
+           /* we do not report the threads which are not yet fully
+              initialized otherwise this creates duplicated threads
+              in gdb: once with pid xxx lwpid 0, then after that
+              with pid xxx lwpid yyy. */
+           if (ts->status != VgTs_Init) {
+              dlog(1, "adding_thread" LOCAL_THREAD_TRACE);
+              add_thread (ptid, ts, ptid);
+           }
+        } else {
+           dlog(2, "(known thread)" LOCAL_THREAD_TRACE);
+        }
+     }
+#undef LOCAL_THREAD_TRACE
+  }
+}
+
+static
+struct reg* build_shadow_arch (struct reg *reg_defs, int n) {
+   int i, r;
+   static char *postfix[3] = { "", "s1", "s2" };
+   struct reg *new_regs = malloc(3 * n * sizeof(reg_defs[0]));
+   int reg_set_len = reg_defs[n-1].offset + reg_defs[n-1].size;
+
+   for (i = 0; i < 3; i++) {
+      for (r = 0; r < n; r++) {
+         new_regs[i*n + r].name = malloc(strlen(reg_defs[r].name) 
+                                         + strlen (postfix[i]) + 1);
+         strcpy (new_regs[i*n + r].name, reg_defs[r].name);
+         strcat (new_regs[i*n + r].name, postfix[i]);
+         new_regs[i*n + r].offset = i*reg_set_len + reg_defs[r].offset;
+         new_regs[i*n + r].size = reg_defs[r].size;
+         dlog(1,
+              "%10s Nr %d offset(bit) %d offset(byte) %d  size(bit) %d\n",
+              new_regs[i*n + r].name, i*n + r, new_regs[i*n + r].offset,
+              (new_regs[i*n + r].offset) / 8, new_regs[i*n + r].size);
+      }  
+   }
+
+   return new_regs;
+}
+
+
+static CORE_ADDR stopped_data_address = 0;
+void VG_(set_watchpoint_stop_address) (Addr addr)
+{
+   stopped_data_address = addr;
+}
+
+int valgrind_stopped_by_watchpoint (void)
+{
+   return stopped_data_address != 0;
+}
+
+CORE_ADDR valgrind_stopped_data_address (void)
+{
+   return stopped_data_address;
+}
+
+/* pc at which we last stopped */
+static CORE_ADDR stop_pc;
+
+/* pc at which we resume. 
+   If stop_pc != resume_pc, it means
+      gdb/gdbserver has changed the pc so as to have either
+      a    "continue by jumping at that address"
+      or a "continue at that address to call some code from gdb".
+*/
+static CORE_ADDR resume_pc;
+
+static int vki_signal_to_report;
+
+void gdbserver_signal_encountered (Int vki_sigNo)
+{
+   vki_signal_to_report = vki_sigNo;
+}
+
+static int vki_signal_to_deliver;
+Bool gdbserver_deliver_signal (Int vki_sigNo)
+{
+   return vki_sigNo == vki_signal_to_deliver;
+}
+
+static
+char* sym (Addr addr)
+{
+   static char buf[200];
+   VG_(describe_IP) (addr, buf, 200);
+   return buf;
+}
+
+ThreadId vgdb_interrupted_tid = 0;
+
+/* 0 => not single stepping.
+   1 => single stepping asked by gdb
+   2 => single stepping asked by valgrind (watchpoint) */
+static int stepping = 0;
+
+Addr valgrind_get_ignore_break_once(void)
+{
+   if (valgrind_single_stepping())
+      return resume_pc;
+   else
+      return 0;
+}
+
+void valgrind_set_single_stepping(Bool set)
+{
+   if (set)
+      stepping = 2;
+   else
+      stepping = 0;
+}
+
+Bool valgrind_single_stepping(void)
+{
+   if (stepping)
+      return True;
+   else
+      return False;
+}
+
+int valgrind_thread_alive (unsigned long tid)
+{
+  struct thread_info *ti =  gdb_id_to_thread(tid);
+  ThreadState *tst;
+
+  if (ti != NULL) {
+     tst = (ThreadState *) inferior_target_data (ti);
+     return tst->status != VgTs_Zombie;
+  }
+  else {
+    return 0;
+  }
+}
+
+void valgrind_resume (struct thread_resume *resume_info)
+{
+   dlog(1,
+        "resume_info step %d sig %d stepping %d\n", 
+        resume_info->step,
+        resume_info->sig,
+        stepping);
+   if (valgrind_stopped_by_watchpoint()) {
+      dlog(1, "clearing watchpoint stopped_data_address %p\n",
+           C2v(stopped_data_address));
+      VG_(set_watchpoint_stop_address) ((Addr) 0);
+   }
+   vki_signal_to_deliver = resume_info->sig;
+   
+   stepping = resume_info->step;
+   resume_pc = (*the_low_target.get_pc) ();
+   if (resume_pc != stop_pc) {
+      dlog(1,
+           "stop_pc %p changed to be resume_pc %s\n",
+           C2v(stop_pc), sym(resume_pc));
+   }
+   regcache_invalidate();
+}
+
+unsigned char valgrind_wait (char *ourstatus)
+{
+   int pid;
+   unsigned long wptid;
+   ThreadState *tst;
+   enum target_signal sig;
+
+   pid = VG_(getpid) ();
+   dlog(1, "enter valgrind_wait pid %d\n", pid);
+
+   regcache_invalidate();
+   valgrind_update_threads(pid);
+
+   /* in valgrind, we consider that a wait always succeeds with STOPPED 'T' 
+      and with a signal TRAP (i.e. a breakpoint), unless there is
+      a signal to report. */
+   *ourstatus = 'T';
+   if (vki_signal_to_report == 0)
+      sig = TARGET_SIGNAL_TRAP;
+   else {
+      sig = target_signal_from_host(vki_signal_to_report);
+      vki_signal_to_report = 0;
+   }
+   
+   if (vgdb_interrupted_tid != 0)
+      tst = VG_(get_ThreadState) (vgdb_interrupted_tid);
+   else
+      tst = VG_(get_ThreadState) (VG_(running_tid));
+   wptid = tst->os_state.lwpid;
+   /* we can only change the current_inferior when the wptid references
+      an existing thread. Otherwise, we are still in the init phase.
+      (hack similar to main thread hack in valgrind_update_threads) */
+   if (tst->os_state.lwpid)
+      current_inferior = gdb_id_to_thread (wptid);
+   stop_pc = (*the_low_target.get_pc) ();
+   
+   dlog(1,
+        "exit valgrind_wait returns ptid %s stop_pc %s signal %d\n", 
+        image_ptid (wptid), sym (stop_pc), sig);
+   return sig;
+}
+
+/* Fetch one register from valgrind VEX guest state.  */
+static
+void fetch_register (int regno)
+{
+   int size;
+   ThreadState *tst = (ThreadState *) inferior_target_data (current_inferior);
+   ThreadId tid = tst->tid;
+
+   if (regno >= the_low_target.num_regs) {
+      dlog(0, "error fetch_register regno %d max %d\n",
+           regno, the_low_target.num_regs);
+      return;
+   }
+   size = register_size (regno);
+   if (size > 0) {
+      Bool mod;
+      char buf [size];
+      VG_(memset) (buf, 0, size); // registers not fetched will be seen as 0.
+      (*the_low_target.transfer_register) (tid, regno, buf,
+                                           valgrind_to_gdbserver, size, &mod);
+      // Note: the *mod received from transfer_register is not interesting.
+      // We are interested to see if the register data in the register cache is modified.
+      supply_register (regno, buf, &mod);
+      if (mod && VG_(debugLog_getLevel)() > 1) {
+         char bufimage [2*size + 1];
+         heximage (bufimage, buf, size);
+         dlog(2, "fetched register %d size %d name %s value %s tid %d status %s\n", 
+              regno, size, the_low_target.reg_defs[regno].name, bufimage, 
+              tid, VG_(name_of_ThreadStatus) (tst->status));
+      }
+   }
+}
+
+/* Fetch all registers, or just one, from the child process.  */
+static
+void usr_fetch_inferior_registers (int regno)
+{
+   if (regno == -1 || regno == 0)
+      for (regno = 0; regno < the_low_target.num_regs; regno++)
+         fetch_register (regno);
+   else
+      fetch_register (regno);
+}
+
+/* Store our register values back into the inferior.
+   If REGNO is -1, do this for all registers.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+static
+void usr_store_inferior_registers (int regno)
+{
+   int size;
+   ThreadState *tst = (ThreadState *) inferior_target_data (current_inferior);
+   ThreadId tid = tst->tid;
+   
+   if (regno >= 0) {
+
+      if (regno >= the_low_target.num_regs) {
+         dlog(0, "error store_register regno %d max %d\n",
+              regno, the_low_target.num_regs);
+         return;
+      }
+      
+      size = register_size (regno);
+      if (size > 0) {
+         Bool mod;
+         Addr old_SP, new_SP;
+         char buf[size];
+
+         if (regno == the_low_target.stack_pointer_regno) {
+            /* When the stack pointer register is changed such that
+               the stack is extended, we better inform the tool of the
+               stack increase.  This is needed in particular to avoid
+               spurious Memcheck errors during Inferior calls. So, we
+               save in old_SP the SP before the change. A change of
+               stack pointer is also assumed to have initialised this
+               new stack space. For the typical example of an inferior
+               call, gdb writes arguments on the stack, and then
+               changes the stack pointer. As the stack increase tool
+               function might mark it as undefined, we have to call it
+               at the good moment. */
+            VG_(memset) ((void *) &old_SP, 0, size);
+            (*the_low_target.transfer_register) (tid, regno, (void *) &old_SP, 
+                                                 valgrind_to_gdbserver, size, &mod);
+         }
+
+         VG_(memset) (buf, 0, size);
+         collect_register (regno, buf);
+         (*the_low_target.transfer_register) (tid, regno, buf, 
+                                              gdbserver_to_valgrind, size, &mod);
+         if (mod && VG_(debugLog_getLevel)() > 1) {
+            char bufimage [2*size + 1];
+            heximage (bufimage, buf, size);
+            dlog(2, 
+                 "stored register %d size %d name %s value %s "
+                 "tid %d status %s\n", 
+                 regno, size, the_low_target.reg_defs[regno].name, bufimage, 
+                 tid, VG_(name_of_ThreadStatus) (tst->status));
+         }
+         if (regno == the_low_target.stack_pointer_regno) {
+            VG_(memcpy) (&new_SP, buf, size);
+            if (old_SP > new_SP) {
+               Word delta  = (Word)new_SP - (Word)old_SP;
+               dlog(1, 
+                    "   stack increase by stack pointer changed from %p to %p "
+                    "delta %ld\n",
+                    (void*) old_SP, (void *) new_SP,
+                    delta);
+               VG_TRACK( new_mem_stack_w_ECU, new_SP, -delta, 0 );
+               VG_TRACK( new_mem_stack,       new_SP, -delta );
+               if (VG_(tdict).track_post_mem_write) {
+                  VG_(tdict).track_post_mem_write( Vg_CoreClientReq, tid, 
+                                                   new_SP, -delta);
+               }
+            }
+         }
+      }
+   }
+   else {
+      for (regno = 0; regno < the_low_target.num_regs; regno++)
+         usr_store_inferior_registers (regno);
+   }
+}
+
+void valgrind_fetch_registers (int regno)
+{
+   usr_fetch_inferior_registers (regno);
+}
+
+void valgrind_store_registers (int regno)
+{
+   usr_store_inferior_registers (regno);
+}
+
+int valgrind_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+{
+   const void *sourceaddr = C2v (memaddr);
+   dlog(2, "reading memory %p size %d\n", sourceaddr, len);
+   if (!VG_(am_is_valid_for_client_or_free_or_resvn) ((Addr) sourceaddr, 
+                                                      len, VKI_PROT_READ)) {
+      dlog(1, "error reading memory %p size %d\n", sourceaddr, len);
+      return -1;
+   }
+   VG_(memcpy) (myaddr, sourceaddr, len);
+   return 0;
+}
+
+int valgrind_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
+{
+   void *targetaddr = C2v (memaddr);
+   dlog(2, "writing memory %p size %d\n", targetaddr, len);
+   if (!VG_(am_is_valid_for_client_or_free_or_resvn) ((Addr)targetaddr, 
+                                                      len, VKI_PROT_WRITE)) {
+      dlog(1, "error writing memory %p size %d\n", targetaddr, len);
+      return -1;
+   }
+   if (len > 0) {
+      VG_(memcpy) (targetaddr, myaddr, len);
+      if (VG_(tdict).track_post_mem_write) {
+         /* Inform the tool of the post memwrite.  Note that we do the
+            minimum necessary to avoid complains from e.g.
+            memcheck. The idea is that the debugger is as least
+            intrusive as possible.  So, we do not inform of the pre
+            mem write (and in any case, this would cause problems with
+            memcheck that does not like our CorePart in
+            pre_mem_write. */
+         ThreadState *tst = 
+            (ThreadState *) inferior_target_data (current_inferior);
+         ThreadId tid = tst->tid;
+         VG_(tdict).track_post_mem_write( Vg_CoreClientReq, tid,
+                                          (Addr) targetaddr, len );
+      }
+   }
+   return 0;
+}
+
+/* insert or remove a breakpoint */
+static
+int valgrind_point (Bool insert, char type, CORE_ADDR addr, int len)
+{
+   PointKind kind;
+   switch (type) {
+   case '0': /* implemented by inserting checks at each instruction in sb */
+      kind = software_breakpoint;
+      break;
+   case '1': /* hw breakpoint, same implementation as sw breakpoint */
+      kind = hardware_breakpoint;
+      break;
+   case '2':
+      kind = write_watchpoint;
+      break;
+   case '3':
+      kind = read_watchpoint;
+      break;
+   case '4':
+      kind = access_watchpoint;
+      break;
+   default:
+      vg_assert (0);
+   }
+
+   /* Attention: gdbserver convention differs: 0 means ok; 1 means not ok */
+   if (VG_(gdbserver_point) (kind, insert, addr, len))
+      return 0;
+   else
+      return 1; /* error or unsupported */
+}
+
+char* valgrind_target_xml (void)
+{
+   return (char *) the_low_target.target_xml;
+}
+
+char* valgrind_shadow_target_xml (void)
+{
+   return (char *) the_low_target.shadow_target_xml;
+}
+
+int valgrind_insert_watchpoint (char type, CORE_ADDR addr, int len)
+{
+   return valgrind_point (/* insert */ True, type, addr, len);
+}
+
+int valgrind_remove_watchpoint (char type, CORE_ADDR addr, int len)
+{
+   return valgrind_point (/* insert*/ False, type, addr, len);
+}
+
+/* returns a pointer to the architecture state corresponding to
+   the provided register set: 0 => normal guest registers,
+                              1 => shadow1
+                              2 => shadow2
+*/
+VexGuestArchState* get_arch (int set, ThreadState* tst) 
+{
+  switch (set) {
+  case 0: return &tst->arch.vex;
+  case 1: return &tst->arch.vex_shadow1;
+  case 2: return &tst->arch.vex_shadow2;
+  default: vg_assert(0);
+  }
+}
+
+static int non_shadow_num_regs = 0;
+static struct reg *non_shadow_reg_defs = NULL;
+void initialize_shadow_low(Bool shadow_mode)
+{
+  if (non_shadow_reg_defs == NULL) {
+    non_shadow_reg_defs = the_low_target.reg_defs;
+    non_shadow_num_regs = the_low_target.num_regs;
+  }
+
+  regcache_invalidate();
+  if (the_low_target.reg_defs != non_shadow_reg_defs) {
+     free (the_low_target.reg_defs);
+  }
+  if (shadow_mode) {
+    the_low_target.num_regs = 3 * non_shadow_num_regs;
+    the_low_target.reg_defs = build_shadow_arch (non_shadow_reg_defs, non_shadow_num_regs);
+  } else {
+    the_low_target.num_regs = non_shadow_num_regs;
+    the_low_target.reg_defs = non_shadow_reg_defs;
+  }
+  set_register_cache (the_low_target.reg_defs, the_low_target.num_regs);
+}
 
 void set_desired_inferior (int use_general)
 {
@@ -61,42 +584,6 @@ void set_desired_inferior (int use_general)
   }
 }
 
-int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
-{
-   int res;
-   res = (*the_target->read_memory) (memaddr, myaddr, len);
-   return res;
-}
-
-int write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
-                           int len)
-{
-   /* Lacking cleanups, there is some potential for a memory leak if the
-      write fails and we go through error().  Make sure that no more than
-      one buffer is ever pending by making BUFFER static.  */
-   static unsigned char *buffer = 0;
-   int res;
-
-   if (buffer != NULL)
-      free (buffer);
-
-   buffer = malloc (len);
-   VG_(memcpy) (buffer, myaddr, len);
-   res = (*the_target->write_memory) (memaddr, buffer, len);
-   free (buffer);
-   buffer = NULL;
-
-   return res;
-}
-
-void set_target_ops (struct target_ops *target)
-{
-   // Can be called again after a fork => do not re-malloc the_target.
-   if (the_target == NULL)
-      the_target = (struct target_ops *) malloc (sizeof (*the_target));
-   VG_(memcpy) (the_target, target, sizeof (*the_target));
-}
-
 void* VG_(dmemcpy) ( void *d, const void *s, SizeT sz, Bool *mod )
 {
    if (VG_(memcmp) (d, s, sz)) {
@@ -121,3 +608,22 @@ void VG_(transfer) (void *valgrind,
    else
       vg_assert (0);
 }
+
+void valgrind_initialize_target(void)
+{
+#if defined(VGA_x86)
+   x86_init_architecture(&the_low_target);
+#elif defined(VGA_amd64)
+   amd64_init_architecture(&the_low_target);
+#elif defined(VGA_arm)
+   arm_init_architecture(&the_low_target);
+#elif defined(VGA_ppc32)
+   ppc32_init_architecture(&the_low_target);
+#elif defined(VGA_ppc64)
+   ppc64_init_architecture(&the_low_target);
+#elif defined(VGA_s390x)
+   s390x_init_architecture(&the_low_target);
+#else
+   architecture missing in target.c valgrind_initialize_target
+#endif
+}
index d657438adde7b9df0579902fe8f465a55900d81d..b5adda14b7f5757f661db927c5be041ca769528a 100644 (file)
@@ -1,6 +1,7 @@
-/* Target operations for the remote server for GDB.
-   Copyright (C) 2002, 2003, 2004, 2005
+/* Target operations for the Valgrind remote server for GDB.
+   Copyright (C) 2002, 2003, 2004, 2005, 2012
    Free Software Foundation, Inc.
+   Philippe Waroquiers.
 
    Contributed by MontaVista Software.
 
 #ifndef TARGET_H
 #define TARGET_H
 
-/* This structure describes how to resume a particular thread (or
-   all threads) based on the client's request.  If thread is -1, then
-   this entry applies to all threads.  These are generally passed around
-   as an array, and terminated by a thread == -1 entry.  */
+/* This file defines the architecture independent Valgrind gdbserver
+   high level operations such as read memory, get/set registers, ...
 
-struct thread_resume
-{
-  unsigned long thread;
-
-  /* If non-zero, leave this thread stopped.  */
-  int leave_stopped;
-
-  /* If non-zero, we want to single-step.  */
-  int step;
-
-  /* If non-zero, send this signal when we resume.  */
-  int sig;
-};
-
-struct target_ops
-{
-  /* Return 1 iff the thread with process ID PID is alive.  */
-
-  int (*thread_alive) (unsigned long pid);
-
-  /* Resume the inferior process.  */
-
-  void (*resume) (struct thread_resume *resume_info);
-
-  /* Wait for the inferior process to change state.
-
-     STATUS will be filled in with a response code to send to GDB.
-
-     Returns the signal which caused the process to stop, in the
-     remote protocol numbering (e.g. TARGET_SIGNAL_STOP), or the
-     exit code as an integer if *STATUS is 'W'.  */
-
-  unsigned char (*wait) (char *status);
-
-  /* Fetch registers from the inferior process.
-
-     If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO.  */
-
-  void (*fetch_registers) (int regno);
-
-  /* Store registers to the inferior process.
-
-     If REGNO is -1, store all registers; otherwise, store at least REGNO.  */
-
-  void (*store_registers) (int regno);
+   These high level operations are called by the gdbserver
+   protocol implementation (e.g. typically server.c).
+   
+   For some of these high level operations, target.c will call
+   low level operations dependent on the architecture.
+   
+   For example, getting or setting the registers will work on a
+   register cache. The exact details of the registers (how much,
+   their size, etc) is not defined by target.c or the register cache.
 
-  /* Read memory from the inferior process.  This should generally be
-     called through read_inferior_memory, which handles breakpoint shadowing.
+   Such architecture dependent information is defined by
+   valgrind_low.h/valgrind-low-xxxxx.c providing 'low level operations'
+   specific to the xxxxx architecture (for example,
+   valgrind-low-x86.c, valgrind-low-armc.c). */
+        
+/* -------------------------------------------------------------------------- */
+/* ------------------------ Initialisation ---------------------------------- */
+/* -------------------------------------------------------------------------- */
 
-     Read LEN bytes at MEMADDR into a buffer at MYADDR.
-  
-     Returns 0 on success and errno on failure.  */
+/* Initialize the Valgrind high target. This will in turn
+   initialise the low (architecture specific) target. */
+extern void valgrind_initialize_target(void);
 
-  int (*read_memory) (CORE_ADDR memaddr, unsigned char *myaddr, int len);
+/* initialize or re-initialize the register set of the low target.
+   if shadow_mode, then (re-)define the normal and valgrind shadow registers
+   else (re-)define only the normal registers. */
+extern void initialize_shadow_low (Bool shadow_mode);
 
-  /* Write memory to the inferior process.  This should generally be
-     called through write_inferior_memory, which handles breakpoint shadowing.
+/* Returns the name of the xml target description file. 
+   returns NULL if no xml target description available. */
+extern char* valgrind_target_xml (void);
 
-     Write LEN bytes from the buffer at MYADDR to MEMADDR.
+/* Same but describes also the shadow registers. */
+extern char* valgrind_shadow_target_xml (void);
 
-     Returns 0 on success and errno on failure.  */
 
-  int (*write_memory) (CORE_ADDR memaddr, const unsigned char *myaddr,
-                      int len);
 
-  /* Send a signal to the inferior process, however is appropriate.  */
-  void (*send_signal) (int);
+/* -------------------------------------------------------------------------- */
+/* --------------------------- Execution control ---------------------------- */
+/* -------------------------------------------------------------------------- */
 
-  /* Returns the name of the xml target description file. 
-     returns NULL if no xml target description available. */
-  char* (*target_xml)(void);
-
-  /* Same but describes also the shadow registers. */
-  char* (*shadow_target_xml)(void);
-
-  /* Insert and remove a hardware watchpoint.
-     Returns 0 on success, -1 on failure and 1 on unsupported.  
-     The type is coded as follows:
-       2 = write watchpoint
-       3 = read watchpoint
-       4 = access watchpoint
-  */
-
-  int (*insert_watchpoint) (char type, CORE_ADDR addr, int len);
-  int (*remove_watchpoint) (char type, CORE_ADDR addr, int len);
-
-  /* Returns 1 if target was stopped due to a watchpoint hit, 0 otherwise.  */
-
-  int (*stopped_by_watchpoint) (void);
-
-  /* Returns the address associated with the watchpoint that hit, if any;  
-     returns 0 otherwise.  */
-
-  CORE_ADDR (*stopped_data_address) (void);
+/* This structure describes how to resume the execution.
+   Currently, there is no way to resume only a specific thread.  */
+struct thread_resume
+{
+  /* If non-zero, we want to single-step.  */
+  int step;
 
+  /* If non-zero, send this signal when we resume.  */
+  int sig;
 };
 
-extern struct target_ops *the_target;
-
-void set_target_ops (struct target_ops *);
-
-#define detach_inferior() \
-  (*the_target->detach) ()
-
-#define mythread_alive(pid) \
-  (*the_target->thread_alive) (pid)
-
-#define fetch_inferior_registers(regno) \
-  (*the_target->fetch_registers) (regno)
-
-#define store_inferior_registers(regno) \
-  (*the_target->store_registers) (regno)
-
-#define mywait(statusp) \
-  (*the_target->wait) (statusp)
-
-int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len);
-
-int write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
-                          int len);
-
-void set_desired_inferior (int id);
+/* Prepare to Resume (i.e. restart) the guest.
+   The resume info indicates how the resume will be done. 
+   In case GDB has changed the program counter, valgrind_resume
+   will also ensure that the execution will be resumed at this
+   new program counter.
+   The Resume is really only executed once the gdbserver
+   returns (giving back the control to Valgrind). */
+extern void valgrind_resume (struct thread_resume *resume_info);
+
+/* When Valgrind gets the control, it will execute the guest
+   process till there is a reason to call the gdbserver
+   again (e.g. because a breakpoint is encountered or the
+   tool reports an error).
+   In such case, the executionof guest code  stops, and the
+   control is given to gdbserver. Gdbserver will send a resume
+   reply packet to GDB.
+
+   valgrind_wait gets from Valgrind data structures the
+   information needed produce the resume reply for GDB:
+   a.o. OURSTATUS will be filled in with a response code to send to GDB.
+
+   Returns the signal which caused the process to stop, in the
+   remote protocol numbering (e.g. TARGET_SIGNAL_STOP), or the
+   exit code as an integer if *OURSTATUS is 'W'.  */
+extern unsigned char valgrind_wait (char *outstatus);
+
+/* When execution is stopped and gdbserver has control, more
+   info about the stop reason can be retrieved using the following
+   functions. */
+
+/* gets the addr at which a (possible) break must be ignored once.
+   If there is no such break to be ignored once, 0 is returned.
+   This is needed for the following case:
+   The user sets a break at address AAA.
+   The break is encountered. Then the user does stepi 
+   (i.e. step one instruction).
+   In such a case, the already encountered break must be ignored
+   to ensure the stepi will advance by one instruction: a "break"
+   is implemented in valgrind by some helper code just after the
+   instruction mark at which the break is set. This helper code
+   verifies if either there is a break at the current PC
+   or if we are in stepping mode. If we are in stepping mode,
+   the already encountered break must be ignored once to advance
+   to the next instruction.
+   ??? need to check if this is *really* needed. */
+extern Addr valgrind_get_ignore_break_once(void);
+
+/* When addr > 0, ensures the next resume reply packet informs
+   gdb about the encountered watchpoint.
+   valgrind_stopped_by_watchpoint() will return 1 till reset.
+   Use addr 0x0 to reset. */
+extern void VG_(set_watchpoint_stop_address) (Addr addr);
+
+/* Returns 1 if target was stopped due to a watchpoint hit, 0 otherwise.  */
+extern int valgrind_stopped_by_watchpoint (void);
+
+/* Returns the address associated with the watchpoint that hit, if any;  
+   returns 0 otherwise.  */
+extern CORE_ADDR valgrind_stopped_data_address (void);
+
+/* True if gdbserver is single stepping the valgrind process */
+extern Bool valgrind_single_stepping(void);
+
+/* Set Valgrind in single stepping mode or not according to Bool. */
+extern void valgrind_set_single_stepping(Bool);
+
+/* -------------------------------------------------------------------------- */
+/* ----------------- Examining/modifying data while stopped ----------------- */
+/* -------------------------------------------------------------------------- */
+
+/* Return 1 iff the thread with ID tid is alive.  */
+extern int valgrind_thread_alive (unsigned long tid);
+
+/* Allows to controls the thread (current_inferior) used for following
+   valgrind_(fetch|store)_registers calls.
+   If USE_GENERAL,
+     current_inferior is set to general_thread
+   else
+     current_inferior is set to step_thread or else cont_thread.
+   If the above gives no valid thread, then current_inferior is
+   set to the first valid thread. */
+extern void set_desired_inferior (int use_general);
+
+/* Fetch registers from the current_inferior thread.
+   If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO.  */
+extern void valgrind_fetch_registers (int regno);
+
+/* Store registers to the current_inferior thread.
+   If REGNO is -1, store all registers; otherwise, store at least REGNO.  */
+extern void valgrind_store_registers (int regno);
+
+
+
+/* Read memory from the inferior process.
+   Read LEN bytes at MEMADDR into a buffer at MYADDR.
+   Returns 0 on success and errno on failure.  */
+extern int valgrind_read_memory (CORE_ADDR memaddr,
+                                 unsigned char *myaddr, int len);
+
+/* Write memory to the inferior process.
+   Write LEN bytes from the buffer at MYADDR to MEMADDR.
+   Returns 0 on success and errno on failure.  */
+extern int valgrind_write_memory (CORE_ADDR memaddr,
+                                  const unsigned char *myaddr, int len);
+
+
+/* Insert and remove a hardware watchpoint.
+   Returns 0 on success, -1 on failure and 1 on unsupported.  
+   The type is coded as follows:
+   2 = write watchpoint
+   3 = read watchpoint
+   4 = access watchpoint
+*/
+extern int valgrind_insert_watchpoint (char type, CORE_ADDR addr, int len);
+extern int valgrind_remove_watchpoint (char type, CORE_ADDR addr, int len);
+
+
+/* -------------------------------------------------------------------------- */
+/* ----------- Utils functions for low level arch specific files ------------ */
+/* -------------------------------------------------------------------------- */
+
+/* returns a pointer to the architecture state corresponding to
+   the provided register set: 0 => normal guest registers,
+                              1 => shadow1
+                              2 => shadow2
+*/
+extern VexGuestArchState* get_arch (int set, ThreadState* tst);
 
 /* like memcpy but first check if content of destination and source
    differs. If no difference, no copy is done, *mod set to False.
@@ -173,4 +229,6 @@ extern void  VG_(transfer) (void *valgrind,
                             SizeT sz,
                             Bool *mod);
 
+
+
 #endif /* TARGET_H */
index 5880eeaaf3c0caf10a0a5970430e89aa72c8ca57..d46afec0f235ee5f1041ceb7a15ab4e13851ddcd 100644 (file)
@@ -160,16 +160,7 @@ void transfer_register (ThreadId tid, int abs_regno, void * buf,
    case 13: VG_(transfer) (&amd64->guest_R13, buf, dir, size, mod); break;
    case 14: VG_(transfer) (&amd64->guest_R14, buf, dir, size, mod); break;
    case 15: VG_(transfer) (&amd64->guest_R15, buf, dir, size, mod); break;
-   case 16: 
-      VG_(transfer) (&amd64->guest_RIP, buf, dir, size, mod);
-      if (*mod && VG_(debugLog_getLevel)() > 2) {
-         char bufimage [2*sizeof(amd64->guest_IP_AT_SYSCALL) + 1];
-         heximage (bufimage, 
-                   (char *) &amd64->guest_IP_AT_SYSCALL, 
-                   sizeof(amd64->guest_IP_AT_SYSCALL));
-         dlog(3, "guest_IP_AT_SYSCALL %s\n", bufimage);
-      }
-      break;
+   case 16: VG_(transfer) (&amd64->guest_RIP, buf, dir, size, mod); break;
    case 17: 
       if (dir == valgrind_to_gdbserver) {
          ULong rflags;
index 89ef32977b19ca01780dbe44baefd56e964adede..991b8bd70e2b7282385c9e48abf8727fdad2b7c4 100644 (file)
@@ -137,16 +137,7 @@ void transfer_register (ThreadId tid, int abs_regno, void * buf,
    case 5:  VG_(transfer) (&x86->guest_EBP, buf, dir, size, mod); break;
    case 6:  VG_(transfer) (&x86->guest_ESI, buf, dir, size, mod); break;
    case 7:  VG_(transfer) (&x86->guest_EDI, buf, dir, size, mod); break;
-   case 8:  
-      VG_(transfer) (&x86->guest_EIP, buf, dir, size, mod); 
-      if (*mod && VG_(debugLog_getLevel)() > 2) {
-         char bufimage [2*sizeof(x86->guest_IP_AT_SYSCALL) + 1];
-         heximage (bufimage, 
-                   (char *) &x86->guest_IP_AT_SYSCALL, 
-                   sizeof(x86->guest_IP_AT_SYSCALL));
-         dlog(3, "guest_IP_AT_SYSCALL %s\n", bufimage);
-      }
-      break;
+   case 8:  VG_(transfer) (&x86->guest_EIP, buf, dir, size, mod); break;
    case 9:  
       if (dir == valgrind_to_gdbserver) {
          UInt eflags;
diff --git a/coregrind/m_gdbserver/valgrind-low.c b/coregrind/m_gdbserver/valgrind-low.c
deleted file mode 100644 (file)
index 59f5284..0000000
+++ /dev/null
@@ -1,641 +0,0 @@
-/* Low level interface to valgrind, for the remote server for GDB integrated
-   in valgrind.
-   Copyright (C) 2011
-   Free Software Foundation, Inc.
-
-   This file is part of VALGRIND.
-   It has been inspired from a file from gdbserver in gdb 6.6.
-
-   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., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
-
-#include "server.h"
-#include "target.h"
-#include "regdef.h"
-#include "regcache.h"
-#include "valgrind_low.h"
-#include "gdb/signals.h"
-#include "pub_core_aspacemgr.h"
-#include "pub_tool_machine.h"
-#include "pub_core_threadstate.h"
-#include "pub_core_transtab.h"
-#include "pub_core_gdbserver.h" 
-#include "pub_tool_debuginfo.h"
-
-/* the_low_target defines the architecture specific aspects depending
-   on the cpu */
-static struct valgrind_target_ops the_low_target;
-
-/* builds an image of bin according to byte order of the architecture 
-   Useful for register and int image */
-char* heximage (char *buf, char *bin, int count)
-{
-#if defined(VGA_x86) || defined(VGA_amd64)
-   char rev[count]; 
-   /* note: no need for trailing \0, length is known with count */
-  int i;
-  for (i = 0; i < count; i++)
-    rev[i] = bin[count - i - 1];
-  hexify (buf, rev, count);
-#else
-  hexify (buf, bin, count);
-#endif
-  return buf;
-}
-
-void* C2v(CORE_ADDR addr)
-{
-   return (void*) addr;
-}
-
-static
-char *image_ptid(unsigned long ptid)
-{
-  static char result[100];
-  VG_(sprintf) (result, "id %ld", ptid);
-  return result;
-}
-#define get_thread(inf) ((struct thread_info *)(inf))
-static
-void remove_thread_if_not_in_vg_threads (struct inferior_list_entry *inf)
-{
-  struct thread_info *thread = get_thread (inf);
-  if (!VG_(lwpid_to_vgtid)(thread_to_gdb_id(thread))) {
-     dlog(1, "removing gdb ptid %s\n", 
-          image_ptid(thread_to_gdb_id(thread)));
-     remove_thread (thread);
-  }
-}
-
-/* synchronize threads known by valgrind and threads known by gdbserver */
-static
-void valgrind_update_threads (int pid)
-{
-  ThreadId tid;
-  ThreadState *ts;
-  unsigned long ptid;
-  struct thread_info *ti;
-
-  /* call remove_thread for all gdb threads not in valgrind threads */
-  for_each_inferior (&all_threads, remove_thread_if_not_in_vg_threads);
-  
-  /* call add_thread for all valgrind threads not known in gdb all_threads */
-  for (tid = 1; tid < VG_N_THREADS; tid++) {
-
-#define LOCAL_THREAD_TRACE " ti* %p vgtid %d status %s as gdb ptid %s lwpid %d\n", \
-        ti, tid, VG_(name_of_ThreadStatus) (ts->status), \
-        image_ptid (ptid), ts->os_state.lwpid
-
-     if (VG_(is_valid_tid) (tid)) {
-        ts = VG_(get_ThreadState) (tid);
-        ptid = ts->os_state.lwpid;
-        ti = gdb_id_to_thread (ptid);
-        if (!ti) {
-           /* we do not report the threads which are not yet fully
-              initialized otherwise this creates duplicated threads
-              in gdb: once with pid xxx lwpid 0, then after that
-              with pid xxx lwpid yyy. */
-           if (ts->status != VgTs_Init) {
-              dlog(1, "adding_thread" LOCAL_THREAD_TRACE);
-              add_thread (ptid, ts, ptid);
-           }
-        } else {
-           dlog(2, "(known thread)" LOCAL_THREAD_TRACE);
-        }
-     }
-#undef LOCAL_THREAD_TRACE
-  }
-}
-
-/* Return nonzero if the given thread is still alive.  */
-static
-int valgrind_thread_alive (unsigned long tid)
-{
-  struct thread_info *ti =  gdb_id_to_thread(tid);
-  ThreadState *tst;
-
-  if (ti != NULL) {
-     tst = (ThreadState *) inferior_target_data (ti);
-     return tst->status != VgTs_Zombie;
-  }
-  else {
-    return 0;
-  }
-}
-
-/* allocate and build a register structure containing the shadow registers.
-   reg_defs is the normal registers, n is their numbers */
-static
-struct reg* build_shadow_arch (struct reg *reg_defs, int n) {
-   int i, r;
-   static char *postfix[3] = { "", "s1", "s2" };
-   struct reg *new_regs = malloc(3 * n * sizeof(reg_defs[0]));
-   int reg_set_len = reg_defs[n-1].offset + reg_defs[n-1].size;
-
-   for (i = 0; i < 3; i++) {
-      for (r = 0; r < n; r++) {
-         new_regs[i*n + r].name = malloc(strlen(reg_defs[r].name) 
-                                         + strlen (postfix[i]) + 1);
-         strcpy (new_regs[i*n + r].name, reg_defs[r].name);
-         strcat (new_regs[i*n + r].name, postfix[i]);
-         new_regs[i*n + r].offset = i*reg_set_len + reg_defs[r].offset;
-         new_regs[i*n + r].size = reg_defs[r].size;
-         dlog(1,
-              "%10s Nr %d offset(bit) %d offset(byte) %d  size(bit) %d\n",
-              new_regs[i*n + r].name, i*n + r, new_regs[i*n + r].offset,
-              (new_regs[i*n + r].offset) / 8, new_regs[i*n + r].size);
-      }  
-   }
-
-   return new_regs;
-}
-
-/* Fetch one register from valgrind VEX guest state.  */
-static
-void fetch_register (int regno)
-{
-   int size;
-   ThreadState *tst = (ThreadState *) inferior_target_data (current_inferior);
-   ThreadId tid = tst->tid;
-
-   if (regno >= the_low_target.num_regs) {
-      dlog(0, "error fetch_register regno %d max %d\n",
-           regno, the_low_target.num_regs);
-      return;
-   }
-   size = register_size (regno);
-   if (size > 0) {
-      Bool mod;
-      char buf [size];
-      VG_(memset) (buf, 0, size); // registers not fetched will be seen as 0.
-      (*the_low_target.transfer_register) (tid, regno, buf,
-                                           valgrind_to_gdbserver, size, &mod);
-      // Note: the *mod received from transfer_register is not interesting.
-      // We are interested to see if the register data in the register cache is modified.
-      supply_register (regno, buf, &mod);
-      if (mod && VG_(debugLog_getLevel)() > 1) {
-         char bufimage [2*size + 1];
-         heximage (bufimage, buf, size);
-         dlog(2, "fetched register %d size %d name %s value %s tid %d status %s\n", 
-              regno, size, the_low_target.reg_defs[regno].name, bufimage, 
-              tid, VG_(name_of_ThreadStatus) (tst->status));
-      }
-   }
-}
-
-/* Fetch all registers, or just one, from the child process.  */
-static
-void usr_fetch_inferior_registers (int regno)
-{
-   if (regno == -1 || regno == 0)
-      for (regno = 0; regno < the_low_target.num_regs; regno++)
-         fetch_register (regno);
-   else
-      fetch_register (regno);
-}
-
-/* Store our register values back into the inferior.
-   If REGNO is -1, do this for all registers.
-   Otherwise, REGNO specifies which register (so we can save time).  */
-static
-void usr_store_inferior_registers (int regno)
-{
-   int size;
-   ThreadState *tst = (ThreadState *) inferior_target_data (current_inferior);
-   ThreadId tid = tst->tid;
-   
-   if (regno >= 0) {
-
-      if (regno >= the_low_target.num_regs) {
-         dlog(0, "error store_register regno %d max %d\n",
-              regno, the_low_target.num_regs);
-         return;
-      }
-      
-      size = register_size (regno);
-      if (size > 0) {
-         Bool mod;
-         Addr old_SP, new_SP;
-         char buf[size];
-
-         if (regno == the_low_target.stack_pointer_regno) {
-            /* When the stack pointer register is changed such that
-               the stack is extended, we better inform the tool of the
-               stack increase.  This is needed in particular to avoid
-               spurious Memcheck errors during Inferior calls. So, we
-               save in old_SP the SP before the change. A change of
-               stack pointer is also assumed to have initialised this
-               new stack space. For the typical example of an inferior
-               call, gdb writes arguments on the stack, and then
-               changes the stack pointer. As the stack increase tool
-               function might mark it as undefined, we have to call it
-               at the good moment. */
-            VG_(memset) ((void *) &old_SP, 0, size);
-            (*the_low_target.transfer_register) (tid, regno, (void *) &old_SP, 
-                                                 valgrind_to_gdbserver, size, &mod);
-         }
-
-         VG_(memset) (buf, 0, size);
-         collect_register (regno, buf);
-         (*the_low_target.transfer_register) (tid, regno, buf, 
-                                              gdbserver_to_valgrind, size, &mod);
-         if (mod && VG_(debugLog_getLevel)() > 1) {
-            char bufimage [2*size + 1];
-            heximage (bufimage, buf, size);
-            dlog(2, 
-                 "stored register %d size %d name %s value %s "
-                 "tid %d status %s\n", 
-                 regno, size, the_low_target.reg_defs[regno].name, bufimage, 
-                 tid, VG_(name_of_ThreadStatus) (tst->status));
-         }
-         if (regno == the_low_target.stack_pointer_regno) {
-            VG_(memcpy) (&new_SP, buf, size);
-            if (old_SP > new_SP) {
-               Word delta  = (Word)new_SP - (Word)old_SP;
-               dlog(1, 
-                    "   stack increase by stack pointer changed from %p to %p "
-                    "delta %ld\n",
-                    (void*) old_SP, (void *) new_SP,
-                    delta);
-               VG_TRACK( new_mem_stack_w_ECU, new_SP, -delta, 0 );
-               VG_TRACK( new_mem_stack,       new_SP, -delta );
-               if (VG_(tdict).track_post_mem_write) {
-                  VG_(tdict).track_post_mem_write( Vg_CoreClientReq, tid, 
-                                                   new_SP, -delta);
-               }
-            }
-         }
-      }
-   }
-   else {
-      for (regno = 0; regno < the_low_target.num_regs; regno++)
-         usr_store_inferior_registers (regno);
-   }
-}
-
-static
-void valgrind_fetch_registers (int regno)
-{
-   usr_fetch_inferior_registers (regno);
-}
-
-static
-void valgrind_store_registers (int regno)
-{
-   usr_store_inferior_registers (regno);
-}
-
-/* Copy LEN bytes from inferior's memory starting at MEMADDR
-   to debugger memory starting at MYADDR.  */
-
-static
-int valgrind_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
-{
-   const void *sourceaddr = C2v (memaddr);
-   dlog(2, "reading memory %p size %d\n", sourceaddr, len);
-   if (!VG_(am_is_valid_for_client_or_free_or_resvn) ((Addr) sourceaddr, 
-                                                      len, VKI_PROT_READ)) {
-      dlog(1, "error reading memory %p size %d\n", sourceaddr, len);
-      return -1;
-   }
-   VG_(memcpy) (myaddr, sourceaddr, len);
-   return 0;
-}
-
-/* Copy LEN bytes of data from debugger memory at MYADDR
-   to inferior's memory at MEMADDR.
-   On failure (cannot write the inferior)
-   returns the value of errno.  */
-
-static
-int valgrind_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
-{
-   void *targetaddr = C2v (memaddr);
-   dlog(2, "writing memory %p size %d\n", targetaddr, len);
-   if (!VG_(am_is_valid_for_client_or_free_or_resvn) ((Addr)targetaddr, 
-                                                      len, VKI_PROT_WRITE)) {
-      dlog(1, "error writing memory %p size %d\n", targetaddr, len);
-      return -1;
-   }
-   if (len > 0) {
-      VG_(memcpy) (targetaddr, myaddr, len);
-      if (VG_(tdict).track_post_mem_write) {
-         /* Inform the tool of the post memwrite.  Note that we do the
-            minimum necessary to avoid complains from e.g.
-            memcheck. The idea is that the debugger is as least
-            intrusive as possible.  So, we do not inform of the pre
-            mem write (and in any case, this would cause problems with
-            memcheck that does not like our CorePart in
-            pre_mem_write. */
-         ThreadState *tst = (ThreadState *) inferior_target_data (current_inferior);
-         ThreadId tid = tst->tid;
-         VG_(tdict).track_post_mem_write( Vg_CoreClientReq, tid, (Addr) targetaddr, len );
-      }
-   }
-   return 0;
-}
-
-/* insert or remove a breakpoint */
-static
-int valgrind_point (Bool insert, char type, CORE_ADDR addr, int len)
-{
-   PointKind kind;
-   switch (type) {
-   case '0': /* implemented by inserting checks at each instruction in sb */
-      kind = software_breakpoint;
-      break;
-   case '1': /* hw breakpoint, same implementation as sw breakpoint */
-      kind = hardware_breakpoint;
-      break;
-   case '2':
-      kind = write_watchpoint;
-      break;
-   case '3':
-      kind = read_watchpoint;
-      break;
-   case '4':
-      kind = access_watchpoint;
-      break;
-   default:
-      vg_assert (0);
-   }
-
-   /* Attention: gdbserver convention differs: 0 means ok; 1 means not ok */
-   if (VG_(gdbserver_point) (kind, insert, addr, len))
-      return 0;
-   else
-      return 1; /* error or unsupported */
-}
-
-static
-void valgrind_send_signal (int sig)
-{
-   dlog(1, "valgrind_send_signal %d called ????\n", sig); 
-}
-
-static
-char* valgrind_target_xml (void)
-{
-   return (char *) the_low_target.target_xml;
-}
-
-static
-char* valgrind_shadow_target_xml (void)
-{
-   return (char *) the_low_target.shadow_target_xml;
-}
-
-static
-int valgrind_insert_point (char type, CORE_ADDR addr, int len)
-{
-   return valgrind_point (/* insert */ True, type, addr, len);
-}
-
-static
-int valgrind_remove_point (char type, CORE_ADDR addr, int len)
-{
-   return valgrind_point (/* insert*/ False, type, addr, len);
-}
-
-static CORE_ADDR stopped_data_address = 0;
-void VG_(set_watchpoint_stop_address) (Addr addr)
-{
-   stopped_data_address = addr;
-}
-
-static
-int valgrind_stopped_by_watchpoint (void)
-{
-   return stopped_data_address != 0;
-}
-
-static
-CORE_ADDR valgrind_stopped_data_address (void)
-{
-   return stopped_data_address;
-}
-
-/* pc at which we last stopped */
-static CORE_ADDR stop_pc;
-
-/* pc at which we resume. 
-   If stop_pc != resume_pc, it means
-      gdb/gdbserver has changed the pc so as to have either
-      a    "continue by jumping at that address"
-      or a "continue at that address to call some code from gdb".
-*/
-static CORE_ADDR resume_pc;
-
-static int vki_signal_to_report;
-
-void gdbserver_signal_encountered (Int vki_sigNo)
-{
-   vki_signal_to_report = vki_sigNo;
-}
-
-static int vki_signal_to_deliver;
-Bool gdbserver_deliver_signal (Int vki_sigNo)
-{
-   return vki_sigNo == vki_signal_to_deliver;
-}
-
-static
-char* sym (Addr addr)
-{
-   static char buf[200];
-   VG_(describe_IP) (addr, buf, 200);
-   return buf;
-}
-
-ThreadId vgdb_interrupted_tid = 0;
-/* called to wait for the process to stop */
-static
-unsigned char valgrind_wait (char *ourstatus)
-{
-   int pid;
-   unsigned long wptid;
-   ThreadState *tst;
-   enum target_signal sig;
-
-   pid = VG_(getpid) ();
-   dlog(1, "enter valgrind_wait pid %d\n", pid);
-
-   regcache_invalidate();
-   valgrind_update_threads(pid);
-
-   /* in valgrind, we consider that a wait always succeeds with STOPPED 'T' 
-      and with a signal TRAP (i.e. a breakpoint), unless there is
-      a signal to report. */
-   *ourstatus = 'T';
-   if (vki_signal_to_report == 0)
-      sig = TARGET_SIGNAL_TRAP;
-   else {
-      sig = target_signal_from_host(vki_signal_to_report);
-      vki_signal_to_report = 0;
-   }
-   
-   if (vgdb_interrupted_tid != 0)
-      tst = VG_(get_ThreadState) (vgdb_interrupted_tid);
-   else
-      tst = VG_(get_ThreadState) (VG_(running_tid));
-   wptid = tst->os_state.lwpid;
-   /* we can only change the current_inferior when the wptid references
-      an existing thread. Otherwise, we are still in the init phase.
-      (hack similar to main thread hack in valgrind_update_threads) */
-   if (tst->os_state.lwpid)
-      current_inferior = gdb_id_to_thread (wptid);
-   stop_pc = (*the_low_target.get_pc) ();
-   
-   dlog(1,
-        "exit valgrind_wait returns ptid %s stop_pc %s signal %d\n", 
-        image_ptid (wptid), sym (stop_pc), sig);
-   return sig;
-}
-
-/* 0 => not single stepping.
-   1 => single stepping asked by gdb
-   2 => single stepping asked by valgrind (watchpoint) */
-static int stepping = 0;
-
-/* called when the process is to be resumed */
-static
-void valgrind_resume (struct thread_resume *resume_info)
-{
-   dlog(1,
-        "resume_info thread %ld leave_stopped %d step %d sig %d stepping %d\n", 
-        resume_info->thread,
-        resume_info->leave_stopped,
-        resume_info->step,
-        resume_info->sig,
-        stepping);
-   if (valgrind_stopped_by_watchpoint()) {
-      dlog(1, "clearing watchpoint stopped_data_address %p\n",
-           C2v(stopped_data_address));
-      VG_(set_watchpoint_stop_address) ((Addr) 0);
-   }
-   vki_signal_to_deliver = resume_info->sig;
-   
-   stepping = resume_info->step;
-   resume_pc = (*the_low_target.get_pc) ();
-   if (resume_pc != stop_pc) {
-      dlog(1,
-           "stop_pc %p changed to be resume_pc %s\n",
-           C2v(stop_pc), sym(resume_pc));
-   }
-   regcache_invalidate();
-}
-
-Addr valgrind_get_ignore_break_once(void)
-{
-   if (valgrind_single_stepping())
-      return resume_pc;
-   else
-      return 0;
-}
-
-
-void valgrind_set_single_stepping(Bool set)
-{
-   if (set)
-      stepping = 2;
-   else
-      stepping = 0;
-}
-
-Bool valgrind_single_stepping(void)
-{
-   if (stepping)
-      return True;
-   else
-      return False;
-}
-
-static struct target_ops valgrind_target_ops = {
-   valgrind_thread_alive,
-   valgrind_resume,
-   valgrind_wait,
-   valgrind_fetch_registers,
-   valgrind_store_registers,
-   valgrind_read_memory,
-   valgrind_write_memory,
-   valgrind_send_signal,
-   valgrind_target_xml,
-   valgrind_shadow_target_xml,
-   valgrind_insert_point,
-   valgrind_remove_point,
-   valgrind_stopped_by_watchpoint,
-   valgrind_stopped_data_address,
-};
-
-
-/* returns a pointer to the architecture state corresponding to
-   the provided register set: 0 => normal guest registers,
-                              1 => shadow1
-                              2 => shadow2
-*/
-VexGuestArchState* get_arch (int set, ThreadState* tst) 
-{
-  switch (set) {
-  case 0: return &tst->arch.vex;
-  case 1: return &tst->arch.vex_shadow1;
-  case 2: return &tst->arch.vex_shadow2;
-  default: vg_assert(0);
-  }
-}
-
-static int non_shadow_num_regs = 0;
-static struct reg *non_shadow_reg_defs = NULL;
-void initialize_shadow_low(Bool shadow_mode)
-{
-  if (non_shadow_reg_defs == NULL) {
-    non_shadow_reg_defs = the_low_target.reg_defs;
-    non_shadow_num_regs = the_low_target.num_regs;
-  }
-
-  regcache_invalidate();
-  if (the_low_target.reg_defs != non_shadow_reg_defs) {
-     free (the_low_target.reg_defs);
-  }
-  if (shadow_mode) {
-    the_low_target.num_regs = 3 * non_shadow_num_regs;
-    the_low_target.reg_defs = build_shadow_arch (non_shadow_reg_defs, non_shadow_num_regs);
-  } else {
-    the_low_target.num_regs = non_shadow_num_regs;
-    the_low_target.reg_defs = non_shadow_reg_defs;
-  }
-  set_register_cache (the_low_target.reg_defs, the_low_target.num_regs);
-}
-
-void initialize_low(void)
-{
-   set_target_ops (&valgrind_target_ops);
-
-#if defined(VGA_x86)
-   x86_init_architecture(&the_low_target);
-#elif defined(VGA_amd64)
-   amd64_init_architecture(&the_low_target);
-#elif defined(VGA_arm)
-   arm_init_architecture(&the_low_target);
-#elif defined(VGA_ppc32)
-   ppc32_init_architecture(&the_low_target);
-#elif defined(VGA_ppc64)
-   ppc64_init_architecture(&the_low_target);
-#elif defined(VGA_s390x)
-   s390x_init_architecture(&the_low_target);
-#else
-   architecture missing in valgrind-low.c
-#endif
-
-}
index 6817110eb751b894a5049a4ab62ce07ed5343f76..e89c2dcfde4b576035fc3268c143359481f42db8 100644 (file)
@@ -67,20 +67,6 @@ struct valgrind_target_ops
    const char *shadow_target_xml;
 };
 
-
-/* convert from CORE_ADDR to void* */
-extern void* C2v(CORE_ADDR addr);
-
-/* builds an image of bin according to byte order of the architecture 
-   Useful for register and int image */
-extern char* heximage (char *buf, char *bin, int count);
-
-/* returns a pointer to the architecture state corresponding to
-   the provided register set: 0 => normal guest registers,
-                              1 => shadow1
-                              2 => shadow2 */
-VexGuestArchState* get_arch (int set, ThreadState* tst);
-
 extern void x86_init_architecture (struct valgrind_target_ops *target);
 extern void amd64_init_architecture (struct valgrind_target_ops *target);
 extern void arm_init_architecture (struct valgrind_target_ops *target);