[PATCH] target attributes [3/5] GDB access support

Hui Zhu hui_zhu@mentor.com
Wed Aug 29 08:12:00 GMT 2012


This patch add the target attributes support to let GDB access them as internal variables.


Thanks,
Hui

2012-08-29  Hui Zhu  <hui_zhu@mentor.com>

	* remote.c (remote_get_target_attribute_value,
	remote_set_target_attribute_value): New functions.
	(init_remote_ops): Set remote_ops.to_get_target_attribute_value
	and remote_ops.to_set_target_attribute_value.
	* target.c (update_current_target): Set
	to_get_target_attribute_value and to_set_target_attribute_value.
	* target.h (target_ops): Add to_get_target_attribute_value and
	to_set_target_attribute_value.
	(target_get_target_attribute_value,
	target_set_target_attribute_value): New macros.
	* value.c (target-attributes.h): New include.
	(value_of_internalvar): Add handler for target attributes.
	(set_internalvar): Ditto.
-------------- next part --------------
--- a/remote.c
+++ b/remote.c
@@ -10995,6 +10995,47 @@ remote_set_trace_notes (char *user, char
 }
 
 static int
+remote_get_target_attribute_value (int id, ULONGEST *uval)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *reply;
+
+  set_remote_traceframe ();
+
+  xsnprintf (rs->buf, get_remote_packet_size (), "qTA:%x", id);
+  putpkt (rs->buf);
+  reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
+  if (reply && *reply)
+    {
+      if (*reply == 'V')
+	{
+	  unpack_varlen_hex (reply + 1, uval);
+	  return 1;
+	}
+    }
+  return 0;
+}
+
+static int
+remote_set_target_attribute_value (int id, ULONGEST uval)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *reply;
+
+  set_remote_traceframe ();
+
+  xsnprintf (rs->buf, get_remote_packet_size (), "QTA:%x:%s", id,
+	     phex (uval, 8));
+  putpkt (rs->buf);
+  remote_get_noisy_reply (&target_buf, &target_buf_size);
+  if (*target_buf == '\0')
+    error (_("Target does not support this command."));
+  if (strcmp (target_buf, "OK") != 0)
+    return 0;
+  return 1;
+}
+
+static int
 remote_use_agent (int use)
 {
   if (remote_protocol_packets[PACKET_QAgent].support != PACKET_DISABLE)
@@ -11127,6 +11168,8 @@ Specify the serial device it is connecte
   remote_ops.to_set_disconnected_tracing = remote_set_disconnected_tracing;
   remote_ops.to_set_circular_trace_buffer = remote_set_circular_trace_buffer;
   remote_ops.to_set_trace_notes = remote_set_trace_notes;
+  remote_ops.to_get_target_attribute_value = remote_get_target_attribute_value;
+  remote_ops.to_set_target_attribute_value = remote_set_target_attribute_value;
   remote_ops.to_core_of_thread = remote_core_of_thread;
   remote_ops.to_verify_memory = remote_verify_memory;
   remote_ops.to_get_tib_address = remote_get_tib_address;
--- a/target.c
+++ b/target.c
@@ -694,6 +694,8 @@ update_current_target (void)
       INHERIT (to_set_disconnected_tracing, t);
       INHERIT (to_set_circular_trace_buffer, t);
       INHERIT (to_set_trace_notes, t);
+      INHERIT (to_get_target_attribute_value, t);
+      INHERIT (to_set_target_attribute_value, t);
       INHERIT (to_get_tib_address, t);
       INHERIT (to_set_permissions, t);
       INHERIT (to_static_tracepoint_marker_at, t);
@@ -915,6 +917,12 @@ update_current_target (void)
   de_fault (to_set_trace_notes,
 	    (int (*) (char *, char *, char *))
 	    return_zero);
+  de_fault (to_get_target_attribute_value,
+	    (int (*) (int, ULONGEST *))
+	    return_zero);
+  de_fault (to_set_target_attribute_value,
+	    (int (*) (int, ULONGEST))
+	    return_zero);
   de_fault (to_get_tib_address,
 	    (int (*) (ptid_t, CORE_ADDR *))
 	    tcomplain);
--- a/target.h
+++ b/target.h
@@ -813,6 +813,15 @@ struct target_ops
        successful, 0 otherwise.  */
     int (*to_set_trace_notes) (char *user, char *notes, char* stopnotes);
 
+    /* Get the value of the target attribute id TA, returning
+       1 if the value is known and writing the value itself into the
+       location pointed to by UVAL, else returning 0.  */
+    int (*to_get_target_attribute_value) (int ta, ULONGEST *uval);
+
+    /* Set the value UVAL to the target attribute id TA, returning
+       1 if success, else returning 0.  */
+    int (*to_set_target_attribute_value) (int ta, ULONGEST uval);
+
     /* Return the processor core that thread PTID was last seen on.
        This information is updated only when:
        - update_thread_list is called
@@ -1733,6 +1742,14 @@ extern char *target_fileio_read_stralloc
 #define target_can_use_agent() \
   (*current_target.to_can_use_agent) ()
 
+/* Target-attributes-related operations.  */
+
+#define target_get_target_attribute_value(ta, uval) \
+  (*current_target.to_get_target_attribute_value) ((ta), (uval))
+
+#define target_set_target_attribute_value(ta, uval) \
+  (*current_target.to_set_target_attribute_value) ((ta), (uval))
+
 /* Command logging facility.  */
 
 #define target_log_command(p)						\
--- a/value.c
+++ b/value.c
@@ -42,6 +42,7 @@
 #include <ctype.h>
 #include "tracepoint.h"
 #include "cp-abi.h"
+#include "target-attributes.h"
 
 /* Prototypes for exported functions.  */
 
@@ -1816,6 +1817,26 @@ value_of_internalvar (struct gdbarch *gd
 {
   struct value *val;
   struct trace_state_variable *tsv;
+  struct target_attribute *ta;
+
+  ta = find_target_attribute_name (var->name);
+  if (ta)
+    {
+      ULONGEST uval;
+
+      if ((ta->gdb_access & TARGET_ATTRIBUTE_ACCESS_READ) == 0)
+	error (_("Target attribute $%s cannot be read by GDB."), ta->name);
+
+      if (target_get_target_attribute_value (ta->id, &uval))
+	val = value_from_ulongest (target_attribute_type (gdbarch, ta), uval);
+      else
+        val = allocate_value (builtin_type (gdbarch)->builtin_void);
+
+      VALUE_LVAL (val) = lval_internalvar;
+      VALUE_INTERNALVAR (val) = var;
+
+      return val;
+    }
 
   /* If there is a trace state variable of the same name, assume that
      is what we really want to see.  */
@@ -1965,6 +1986,20 @@ set_internalvar (struct internalvar *var
 {
   enum internalvar_kind new_kind;
   union internalvar_data new_data = { 0 };
+  struct target_attribute *ta;
+
+  ta = find_target_attribute_name (var->name);
+  if (ta)
+    {
+      ULONGEST uval;
+
+      if ((ta->gdb_access & TARGET_ATTRIBUTE_ACCESS_WRITE) == 0)
+	error (_("Target attribute $%s cannot be written by GDB."), ta->name);
+
+      if (!target_set_target_attribute_value (ta->id,
+					      (ULONGEST)value_as_long(val)))
+        error (_("Write target attribute $%s failed."), ta->name);
+    }
 
   if (var->kind == INTERNALVAR_FUNCTION && var->u.fn.canonical)
     error (_("Cannot overwrite convenience function %s"), var->name);


More information about the Gdb-patches mailing list