[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