* [PATCH] target attributes [1/5] core and load from target function
@ 2012-08-29 8:12 Hui Zhu
2012-08-29 14:43 ` Yao Qi
0 siblings, 1 reply; 9+ messages in thread
From: Hui Zhu @ 2012-08-29 8:12 UTC (permalink / raw)
To: gdb-patches; +Cc: Stan Shebs
[-- Attachment #1: Type: text/plain, Size: 1177 bytes --]
This patch add the core files target-attributes.c and target-attributes.h. And add the code that load tha target attributes form remote target.
Thanks,
Hui
2012-08-29 Hui Zhu <hui_zhu@mentor.com>
* Makefile.in (SFILES): Add target-attributes.c.
(HFILES_NO_SRCDIR): Add target-attributes.h.
(COMMON_OBS): Add target-attributes.o.
* breakpoint.h (breakpoint): Add target_only_cond_check.
* remote.c (target-attributes.h): New include.
(PACKET_qXfer_target_attributes_read): New enum.
(remote_start_remote): Add handler for target attributes.
(remote_protocol_features): Add "qXfer:target-attributes:read".
(remote_xfer_partial): Add handler for TARGET_OBJECT_ATTRIBUTES.
(_initialize_remote): Add command
"set remote target-attributes-packet".
(target-attributes.c, target-attributes.h): New files.
* tracepoint.c (target-attributes.h): New include.
(find_trace_state_variable_number,
trace_variable_number_check_1,
trace_variable_number_check): New functions.
(trace_variable_command): Call trace_variable_number_check_1.
(merge_uploaded_trace_state_variables): Call
trace_variable_number_check.
tracepoint.h (trace_variable_number_check): New extern.
[-- Attachment #2: target_attribute_load.txt --]
[-- Type: text/plain, Size: 31780 bytes --]
--- a/Makefile.in
+++ b/Makefile.in
@@ -729,7 +729,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
solib.c solib-target.c source.c \
stabsread.c stack.c probe.c stap-probe.c std-regs.c \
symfile.c symfile-mem.c symmisc.c symtab.c \
- target.c target-descriptions.c target-memory.c \
+ target.c target-attributes.c target-descriptions.c target-memory.c \
thread.c top.c tracepoint.c \
trad-frame.c \
tramp-frame.c \
@@ -829,7 +829,8 @@ gnulib/import/extra/snippet/warn-on-use.
gnulib/import/stddef.in.h gnulib/import/inttypes.in.h inline-frame.h skip.h \
common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
common/format.h common/host-defs.h utils.h \
-common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h gdb_bfd.h
+common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h gdb_bfd.h \
+target-attributes.h
# Header files that already have srcdir in them, or which are in objdir.
@@ -915,7 +916,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
solib.o solib-target.o \
prologue-value.o memory-map.o memrange.o \
xml-support.o xml-syscall.o xml-utils.o \
- target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
+ target-attributes.o target-descriptions.o target-memory.o \
+ xml-tdesc.o xml-builtin.o \
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
gdb_vecs.o jit.o progspace.o skip.o probe.o \
common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o \
--- a/breakpoint.h
+++ b/breakpoint.h
@@ -700,6 +700,11 @@ struct breakpoint
there is no condition. */
char *cond_string;
+ /* If True, the GDB side cannot do the condition check for
+ the condition of this breakpoint and this condition only can
+ be checked in agent side. */
+ int target_only_cond_check;
+
/* String form of extra parameters, or NULL if there are none. */
char *extra_string;
--- a/remote.c
+++ b/remote.c
@@ -43,6 +43,7 @@
#include "cli/cli-setshow.h"
#include "target-descriptions.h"
#include "gdb_bfd.h"
+#include "target-attributes.h"
#include <ctype.h>
#include <sys/time.h>
@@ -1292,6 +1293,7 @@ enum {
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
PACKET_QAgent,
+ PACKET_qXfer_target_attributes_read,
PACKET_MAX
};
@@ -3509,6 +3511,22 @@ remote_start_remote (int from_tty, struc
remote_check_symbols (symfile_objfile);
}
+ if (remote_protocol_packets[PACKET_qXfer_target_attributes_read].support
+ != PACKET_DISABLE)
+ {
+ char *text;
+
+ text = target_read_stralloc (¤t_target, TARGET_OBJECT_ATTRIBUTES,
+ NULL);
+ if (text != NULL)
+ {
+ struct cleanup *back_to = make_cleanup (xfree, text);
+
+ add_xml_target_attributes (text);
+ do_cleanups (back_to);
+ }
+ }
+
/* Possibly the target has been engaged in a trace run started
previously; find out where things are at. */
if (remote_get_trace_status (current_trace_status ()) != -1)
@@ -3945,6 +3963,8 @@ static struct protocol_feature remote_pr
{ "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent},
{ "tracenz", PACKET_DISABLE,
remote_string_tracing_feature, -1 },
+ { "qXfer:target-attributes:read", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_target_attributes_read },
};
static char *remote_support_xml;
@@ -8671,6 +8691,12 @@ remote_xfer_partial (struct target_ops *
return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len,
&remote_protocol_packets[PACKET_qXfer_uib]);
+ case TARGET_OBJECT_ATTRIBUTES:
+ gdb_assert (annex == NULL);
+ return remote_read_qxfer
+ (ops, "target-attributes", annex, readbuf, offset, len,
+ &remote_protocol_packets[PACKET_qXfer_target_attributes_read]);
+
default:
return -1;
}
@@ -11636,6 +11662,10 @@ Show the maximum size of the address (in
add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
"QAgent", "agent", 0);
+ add_packet_config_cmd
+ (&remote_protocol_packets[PACKET_qXfer_target_attributes_read],
+ "qXfer:target-attributes:read", "target-attributes", 0);
+
/* Keep the old ``set remote Z-packet ...'' working. Each individual
Z sub-packet has its own set and show commands, but users may
have sets to this variable in their .gdbinit files (or in their
--- /dev/null
+++ b/target-attributes.c
@@ -0,0 +1,669 @@
+/* Target attributes for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "ui-out.h"
+#include "tracepoint.h"
+#include "gdbcmd.h"
+#include "target-attributes.h"
+
+static struct target_attribute *target_attributes_list;
+
+struct target_attribute *
+find_target_attribute_name (const char *name)
+{
+ struct target_attribute *ta;
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ if (strcmp (ta->name, name) == 0)
+ return ta;
+ }
+
+ return NULL;
+}
+
+struct target_attribute *
+find_target_attribute_id (int id)
+{
+ struct target_attribute *ta;
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ if (id == ta->id)
+ return ta;
+ }
+
+ return NULL;
+}
+
+static struct bp_location *check_agent_target_attribute_bl = NULL;
+char *check_agent_target_attribute_error = NULL;
+
+static void
+clear_check_agent_target_attribute (void *unused)
+{
+ check_agent_target_attribute_bl = NULL;
+}
+
+struct cleanup *
+set_check_agent_target_attribute (struct bp_location *bl)
+{
+ check_agent_target_attribute_bl = bl;
+ check_agent_target_attribute_error = NULL;
+
+ return make_cleanup (clear_check_agent_target_attribute, NULL);
+}
+
+void
+check_agent_target_attribute (struct target_attribute *ta, int write)
+{
+ static char error_str[256];
+ check_agent_target_attribute_error = error_str;
+
+ if (write)
+ {
+ if ((ta->agent_access & TARGET_ATTRIBUTE_ACCESS_WRITE) == 0)
+ {
+ snprintf (error_str, 256, _("$%s cannot be written in agent code."),
+ ta->name);
+ error (_("$%s cannot be written in agent code."), ta->name);
+ }
+ }
+ else
+ {
+ if ((ta->agent_access & TARGET_ATTRIBUTE_ACCESS_READ) == 0)
+ {
+ snprintf (error_str, 256, _("$%s cannot be read in agent code."),
+ ta->name);
+ error (_("$%s cannot be read in agent code."), ta->name);
+ }
+ }
+
+ if (check_agent_target_attribute_bl)
+ {
+ struct target_attribute_address *ta_addr;
+
+ if (ta->target_only_cond_check)
+ check_agent_target_attribute_bl->owner->target_only_cond_check = 1;
+
+ switch (check_agent_target_attribute_bl->loc_type)
+ {
+ case bp_loc_software_breakpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in software breakpoint."),
+ ta->name);
+ error (_("$%s cannot be used in software breakpoint."), ta->name);
+ }
+ break;
+ case bp_loc_hardware_breakpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in hardware breakpoint."),
+ ta->name);
+ error (_("$%s cannot be used in hardware breakpoint."),
+ ta->name);
+ }
+ break;
+ case bp_loc_hardware_watchpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in hardware watchpoint."),
+ ta->name);
+ error (_("$%s cannot be used in hardware watchpoint."),
+ ta->name);
+ }
+ break;
+ default:
+ if (check_agent_target_attribute_bl->owner->type == bp_tracepoint
+ || check_agent_target_attribute_bl->owner->type
+ == bp_fast_tracepoint
+ || check_agent_target_attribute_bl->owner->type
+ == bp_static_tracepoint)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in tracepoint."), ta->name);
+ if ((ta->support & TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT) == 0)
+ error (_("$%s cannot be used in tracepoint."), ta->name);
+ }
+ else
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in breakpoint %d."),
+ ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ error (_("$%s cannot be used in breakpoint %d."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ }
+ break;
+ }
+
+ if (ta->addresses)
+ {
+ for (ta_addr = ta->addresses; ta_addr; ta_addr = ta_addr->prev)
+ {
+ if (check_agent_target_attribute_bl->address >= ta_addr->start
+ && check_agent_target_attribute_bl->address <= ta_addr->end)
+ break;
+ }
+ if (!ta_addr)
+ {
+ snprintf (error_str, 256,
+ _("\
+$%s cannot be used in breakpoint %d because the address limit."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ error (_("\
+$%s cannot be used in breakpoint %d because the address limit."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ }
+ }
+ }
+
+ check_agent_target_attribute_error = NULL;
+}
+
+void
+clear_target_attributes (void *unused)
+{
+ struct target_attribute *ta, *tmp;
+
+ for (ta = target_attributes_list; ta;)
+ {
+ struct target_attribute_address *ta_addr, *tmp_addr;
+
+ tmp = ta;
+ ta = ta->next;
+
+ for (ta_addr = tmp->addresses; ta_addr;)
+ {
+ tmp_addr = ta_addr;
+ ta_addr = ta_addr->prev;
+ xfree (tmp_addr);
+ }
+
+ xfree (tmp);
+ }
+
+ target_attributes_list = NULL;
+}
+
+static void
+info_target_attributes (char *args, int from_tty)
+{
+ struct target_attribute *ta;
+ struct cleanup *back_to;
+ struct ui_out *uiout = current_uiout;
+ int count = 0;
+
+ if (target_attributes_list == NULL)
+ {
+ ui_out_message (uiout, 0, _("No target attributes.\n"));
+ return;
+ }
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ count++;
+
+ back_to = make_cleanup_ui_out_table_begin_end (uiout, 6,
+ count, "target-attributes");
+ ui_out_table_header (uiout, 15, ui_left, "name", "Name");
+ ui_out_table_header (uiout, 15, ui_left, "type", "Type");
+ ui_out_table_header (uiout, 15, ui_left, "target-only-cond-check",
+ "Target-only-cond-check");
+ ui_out_table_header (uiout, 15, ui_left, "agent access", "Agent access");
+ ui_out_table_header (uiout, 15, ui_left, "gdb access", "GDB access");
+ ui_out_table_header (uiout, 15, ui_left, "breakpoint type",
+ "Breakpoint type");
+
+ ui_out_table_body (uiout);
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ struct target_attribute_address *ta_addr;
+ char buf[512];
+ struct cleanup *back_to2
+ = make_cleanup_ui_out_tuple_begin_end (uiout, "attributes");
+
+ snprintf (buf, 512, "$%s", ta->name);
+ ui_out_field_string (uiout, "name", buf);
+
+ switch (ta->type)
+ {
+ case TARGET_ATTRIBUTE_TYPE_INT8:
+ ui_out_field_string (uiout, "type", "int8");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT8:
+ ui_out_field_string (uiout, "type", "uint8");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT16:
+ ui_out_field_string (uiout, "type", "int16");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT16:
+ ui_out_field_string (uiout, "type", "uint16");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT32:
+ ui_out_field_string (uiout, "type", "int32");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT32:
+ ui_out_field_string (uiout, "type", "uint32");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT64:
+ ui_out_field_string (uiout, "type", "int64");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT64:
+ ui_out_field_string (uiout, "type", "uint64");
+ break;
+ }
+
+ ui_out_field_string (uiout, "target-only-cond-check",
+ ta->target_only_cond_check ? "yes" : "no");
+
+ snprintf (buf, 512, "%s%s",
+ (ta->agent_access
+ & TARGET_ATTRIBUTE_ACCESS_READ) ? "read " : "",
+ (ta->agent_access
+ & TARGET_ATTRIBUTE_ACCESS_WRITE) ? "write" : "");
+ ui_out_field_string (uiout, "agent access", buf);
+
+ snprintf (buf, 512, "%s%s",
+ (ta->gdb_access & TARGET_ATTRIBUTE_ACCESS_READ) ? "read " : "",
+ (ta->gdb_access
+ & TARGET_ATTRIBUTE_ACCESS_WRITE) ? "write" : "");
+ ui_out_field_string (uiout, "gdb access", buf);
+
+ snprintf (buf, 512, "%s%s%s%s",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT)
+ ? "software-breakpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT)
+ ? "hardware-breakpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT)
+ ? "hardware-watchpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT)
+ ? "tracepoint " : "");
+ ui_out_field_string (uiout, "breakpoint type", buf);
+
+ ui_out_text (uiout, "\n");
+
+ for (ta_addr = ta->addresses; ta_addr; ta_addr = ta_addr->prev)
+ {
+ ui_out_spaces (uiout, 2);
+ ui_out_message (uiout, 0, "start:%s end:%s\n",
+ paddress (target_gdbarch, ta_addr->start),
+ paddress (target_gdbarch, ta_addr->end));
+ }
+ do_cleanups (back_to2);
+ }
+
+ do_cleanups (back_to);
+}
+
+#if !defined(HAVE_LIBEXPAT)
+
+void
+add_xml_target_attributes (const char *text)
+{
+ if (strlen (text) > 0)
+ warning (_("Can not parse XML target attributes; XML support "
+ "was disabled at compile time"));
+}
+
+#else
+
+#include "xml-support.h"
+
+static void
+target_attribute_attr_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ char *name = NULL;
+ int i, len, id = -1, type, target_only_cond_check = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+ struct target_attribute *ta, **tap = user_data;
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "name") == 0)
+ name = attrs[i].value;
+ else if (strcmp (attrs[i].name, "id") == 0)
+ id = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "type") == 0)
+ type = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "target-only-cond-check") == 0)
+ target_only_cond_check = * (ULONGEST *) attrs[i].value;
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ if (!name || id < 0)
+ gdb_xml_error (parser, _("\"name\" or \"id\" is missed."));
+
+ if (find_target_attribute_name (name))
+ gdb_xml_error (parser,_("\
+name \"%s\" is same with a target attribute."), name);
+ if (find_target_attribute_id (id))
+ gdb_xml_error (parser,_("id \"%d\" is same with a target attribute."), id);
+
+ ta = xzalloc (sizeof (struct target_attribute));
+ ta->name = xstrdup (name);
+ ta->id = id;
+ ta->type = type;
+ ta->target_only_cond_check = target_only_cond_check;
+
+ if (*tap)
+ (*tap)->next = ta;
+ else
+ target_attributes_list = ta;
+ *tap = ta;
+
+ user_data = &ta;
+}
+
+static void
+target_attribute_access_children_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ int i, len, ta_access = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "read") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta_access |= TARGET_ATTRIBUTE_ACCESS_READ;
+ }
+ else if (strcmp (attrs[i].name, "write") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta_access |= TARGET_ATTRIBUTE_ACCESS_WRITE;
+ }
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ if (strcmp (element->name, "agent") == 0)
+ ta->agent_access = ta_access;
+ else
+ ta->gdb_access = ta_access;
+}
+
+static void
+target_attribute_support_attr_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ int i, len = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "software-breakpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT;
+ }
+ else if (strcmp (attrs[i].name, "hardware-breakpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT;
+ }
+ else if (strcmp (attrs[i].name, "hardware-watchpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT;
+ }
+ else if (strcmp (attrs[i].name, "tracepoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT;
+ }
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+}
+
+static void
+target_attribute_address_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ int i, len;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ CORE_ADDR start, end;
+ struct target_attribute_address *ta_addr;
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "start") == 0)
+ start = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "end") == 0)
+ end = * (ULONGEST *) attrs[i].value;
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ ta_addr = xmalloc (sizeof (struct target_attribute_address));
+ ta_addr->start = start;
+ ta_addr->end = end;
+
+ ta_addr->prev = ta->addresses;
+ ta->addresses = ta_addr;
+}
+
+const struct gdb_xml_enum target_attribute_type_enums[] = {
+ { "int8", TARGET_ATTRIBUTE_TYPE_INT8 },
+ { "uint8", TARGET_ATTRIBUTE_TYPE_UINT8 },
+ { "int16", TARGET_ATTRIBUTE_TYPE_INT16 },
+ { "uint16", TARGET_ATTRIBUTE_TYPE_UINT16 },
+ { "int32", TARGET_ATTRIBUTE_TYPE_INT32 },
+ { "uint32", TARGET_ATTRIBUTE_TYPE_UINT32 },
+ { "int64", TARGET_ATTRIBUTE_TYPE_INT64 },
+ { "uint64", TARGET_ATTRIBUTE_TYPE_UINT64 },
+ { NULL, 0 }
+};
+
+static const struct gdb_xml_attribute target_attribute_attr[] = {
+ { "name", GDB_XML_AF_NONE, NULL, NULL },
+ { "id", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "type", GDB_XML_AF_NONE, gdb_xml_parse_attr_enum,
+ target_attribute_type_enums },
+ { "target-only-cond-check", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute
+ target_attribute_access_children_attr[] = {
+ { "read", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "write", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_access_children[] = {
+ { "agent", target_attribute_access_children_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_access_children_handler, NULL },
+ { "gdb", target_attribute_access_children_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_access_children_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute target_attribute_support_attr[] = {
+ { "software-breakpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "hardware-breakpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "hardware-watchpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "tracepoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute target_attribute_address_attr[] = {
+ { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_addresses_children[] = {
+ { "address", target_attribute_address_attr, NULL,
+ GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+ target_attribute_address_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_elements[] = {
+ { "access", NULL, target_attribute_access_children,
+ GDB_XML_EF_NONE, NULL, NULL },
+ { "support", target_attribute_support_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_support_attr_handler, NULL },
+ { "addresses", NULL, target_attribute_addresses_children,
+ GDB_XML_EF_OPTIONAL, NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attributes_children[] = {
+ { "target-attribute", target_attribute_attr, target_attribute_elements,
+ GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+ target_attribute_attr_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attributes_elements[] = {
+ { "target-attributes", NULL, target_attributes_children,
+ GDB_XML_EF_NONE, NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+void
+add_xml_target_attributes (const char *text)
+{
+ struct target_attribute *ta = NULL;
+ struct cleanup *back_to = make_cleanup (clear_target_attributes, NULL);
+
+ clear_target_attributes(NULL);
+ if (gdb_xml_parse_quick (_("target attributes"), NULL,
+ target_attributes_elements, text, &ta) == 0)
+ {
+ discard_cleanups (back_to);
+ trace_variable_number_check ();
+ }
+ else
+ do_cleanups (back_to);
+}
+
+#endif
+
+struct type *
+target_attribute_type (struct gdbarch *gdbarch, struct target_attribute *ta)
+{
+ struct type *ret;
+
+ switch (ta->type)
+ {
+ case TARGET_ATTRIBUTE_TYPE_INT8:
+ ret = builtin_type (gdbarch)->builtin_int8;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT8:
+ ret = builtin_type (gdbarch)->builtin_uint8;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT16:
+ ret = builtin_type (gdbarch)->builtin_int16;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT16:
+ ret = builtin_type (gdbarch)->builtin_uint16;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT32:
+ ret = builtin_type (gdbarch)->builtin_int32;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT32:
+ ret = builtin_type (gdbarch)->builtin_uint32;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT64:
+ ret = builtin_type (gdbarch)->builtin_int64;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT64:
+ ret = builtin_type (gdbarch)->builtin_uint64;
+ break;
+ }
+
+ return ret;
+}
+
+static void
+load_target_attributes_command (char *exp, int from_tty)
+{
+ char *text = xml_fetch_content_from_file (exp, NULL);
+
+ if (text == NULL)
+ error (_("Could not open \"%s\""), exp);
+ add_xml_target_attributes (text);
+}
+
+static void
+clear_target_attributes_command (char *exp, int from_tty)
+{
+ clear_target_attributes (NULL);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_targets_attributes;
+
+void
+_initialize_targets_attributes (void)
+{
+ add_cmd ("load-target-attributes", class_maintenance,
+ load_target_attributes_command,
+ _("Load target attributes from a XML file."),
+ &maintenancelist);
+
+ add_cmd ("clear-target-attributes", class_maintenance,
+ clear_target_attributes_command,
+ _("Remove all target attributes."),
+ &maintenancelist);
+
+ add_info ("target-attributes", info_target_attributes, _("\
+Status of target attributes."));
+}
--- /dev/null
+++ b/target-attributes.h
@@ -0,0 +1,104 @@
+/* Target attributes for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef TARGET_ATTRIBUTES_H
+#define TARGET_ATTRIBUTES_H 1
+
+enum
+{
+ TARGET_ATTRIBUTE_TYPE_INT8,
+ TARGET_ATTRIBUTE_TYPE_UINT8,
+ TARGET_ATTRIBUTE_TYPE_INT16,
+ TARGET_ATTRIBUTE_TYPE_UINT16,
+ TARGET_ATTRIBUTE_TYPE_INT32,
+ TARGET_ATTRIBUTE_TYPE_UINT32,
+ TARGET_ATTRIBUTE_TYPE_INT64,
+ TARGET_ATTRIBUTE_TYPE_UINT64,
+};
+
+#define TARGET_ATTRIBUTE_ACCESS_READ 0x1
+#define TARGET_ATTRIBUTE_ACCESS_WRITE 0x2
+
+#define TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT 0x1
+#define TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT 0x2
+#define TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT 0x4
+#define TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT 0x8
+
+struct target_attribute_address
+ {
+ struct target_attribute_address *prev;
+ CORE_ADDR start;
+ CORE_ADDR end;
+ };
+
+/* This is the core struct of a target attribute.
+ When GDB get a target attribute from XML,
+ it will alloc a struct for it. */
+
+struct target_attribute
+ {
+ struct target_attribute *next;
+ char *name;
+ int id;
+ int type;
+ int target_only_cond_check;
+ unsigned int agent_access;
+ unsigned int gdb_access;
+ unsigned int support;
+ struct target_attribute_address *addresses;
+ };
+
+/* This is the error report string for function
+ check_agent_target_attribute.
+ Because some function call check_agent_target_attribute
+ with TRY_CATCH. Use this string report error. */
+
+extern char *check_agent_target_attribute_error;
+
+extern struct target_attribute *find_target_attribute_name (const char *name);
+extern struct target_attribute *find_target_attribute_id (int id);
+
+/* Set BL for function check_agent_target_attribute
+ before translate a string to agent expression bytecode. */
+
+extern struct cleanup *set_check_agent_target_attribute
+ (struct bp_location *bl);
+
+/* The function that translate a string to agent expression bytecode call
+ check_agent_target_attribute to check if TA is OK to use with
+ BL that set by set_check_agent_target_attribute. */
+
+extern void check_agent_target_attribute (struct target_attribute *ta,
+ int write);
+
+/* Remove all the target attributes inside the GDB. */
+
+extern void clear_target_attributes (void *unused);
+
+/* Parse target attributes out from XML formart string TEXT
+ and add them to GDB. */
+
+extern void add_xml_target_attributes (const char *text);
+
+/* Return the type of TA. */
+
+extern struct type *target_attribute_type (struct gdbarch *gdbarch,
+ struct target_attribute *ta);
+
+#endif /* TARGET_ATTRIBUTES_H */
--- a/target.h
+++ b/target.h
@@ -286,7 +286,9 @@ enum target_object
/* Darwin dynamic linker info data. */
TARGET_OBJECT_DARWIN_DYLD_INFO,
/* OpenVMS Unwind Information Block. */
- TARGET_OBJECT_OPENVMS_UIB
+ TARGET_OBJECT_OPENVMS_UIB,
+ /* Target attributes. */
+ TARGET_OBJECT_ATTRIBUTES,
/* Possible future objects: TARGET_OBJECT_FILE, ... */
};
--- a/tracepoint.c
+++ b/tracepoint.c
@@ -53,6 +53,7 @@
#include "exceptions.h"
#include "cli/cli-utils.h"
#include "probe.h"
+#include "target-attributes.h"
/* readline include files */
#include "readline/readline.h"
@@ -348,6 +349,21 @@ find_trace_state_variable (const char *n
return NULL;
}
+/* Look for a trace state variable of the given number. */
+
+static struct trace_state_variable *
+find_trace_state_variable_number (int number)
+{
+ struct trace_state_variable *tsv;
+ int ix;
+
+ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ if (number == tsv->number)
+ return tsv;
+
+ return NULL;
+}
+
static void
delete_trace_state_variable (const char *name)
{
@@ -365,6 +381,41 @@ delete_trace_state_variable (const char
warning (_("No trace variable named \"$%s\", not deleting"), name);
}
+static int
+trace_variable_number_check_1 (struct trace_state_variable *tsv)
+{
+ if (find_target_attribute_id (tsv->number))
+ {
+ int new_number = tsv->number + 1;
+ tsv->number = 0;
+ while (find_target_attribute_id (new_number)
+ || find_trace_state_variable_number (new_number))
+ new_number++;
+ tsv->number = new_number;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+trace_variable_number_check (void)
+{
+ struct trace_state_variable *tsv;
+ int ix;
+
+ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ {
+ if (trace_variable_number_check_1 (tsv))
+ {
+ warning (_("\
+number of trace variable $%s is same with a tsv compatible \n\
+target attribute. So it is changed to %d."), tsv->name, tsv->number);
+ }
+ }
+}
+
/* The 'tvariable' command collects a name and optional expression to
evaluate into an initial value. */
@@ -423,6 +474,8 @@ trace_variable_command (char *args, int
tsv = create_trace_state_variable (internalvar_name (intvar));
tsv->initial_value = initval;
+ trace_variable_number_check_1 (tsv);
+
printf_filtered (_("Trace state variable $%s "
"created, with initial value %s.\n"),
tsv->name, plongest (tsv->initial_value));
@@ -3608,6 +3661,8 @@ merge_uploaded_trace_state_variables (st
if (tsv->number == 0)
tsv->number = highest++;
+ trace_variable_number_check();
+
free_uploaded_tsvs (uploaded_tsvs);
}
--- a/tracepoint.h
+++ b/tracepoint.h
@@ -250,6 +250,8 @@ extern void while_stepping_pseudocommand
extern struct trace_state_variable *find_trace_state_variable (const char *name);
extern struct trace_state_variable *create_trace_state_variable (const char *name);
+extern void trace_variable_number_check(void);
+
extern int encode_source_string (int num, ULONGEST addr,
char *srctype, char *src,
char *buf, int buf_size);
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] target attributes [1/5] core and load from target function
2012-08-29 8:12 [PATCH] target attributes [1/5] core and load from target function Hui Zhu
@ 2012-08-29 14:43 ` Yao Qi
2012-09-02 10:39 ` Hui Zhu
0 siblings, 1 reply; 9+ messages in thread
From: Yao Qi @ 2012-08-29 14:43 UTC (permalink / raw)
To: Hui Zhu; +Cc: gdb-patches
On 08/29/2012 04:11 PM, Hui Zhu wrote:
> +static void
> +target_attribute_address_handler (struct gdb_xml_parser *parser,
> + const struct gdb_xml_element *element,
> + void *user_data,
> + VEC(gdb_xml_value_s) *attributes)
> +{
> + int i, len;
> + struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
> + struct target_attribute *ta = *(struct target_attribute **)user_data;
> + CORE_ADDR start, end;
> + struct target_attribute_address *ta_addr;
I happen to see some compilation warnings on my new Fedora 16 box, while
these warnings don't appear on my Ubuntu box.
... -Werror -c -o target-memory.o -MT target-memory.o -MMD -MP -MF .deps/target-memory.Tpo ../../../git/gdb/target-memory.c
../../../git/gdb/target-attributes.c: In function ‘target_attribute_address_handler’:
../../../git/gdb/target-attributes.c:487:16: error: ‘end’ may be used uninitialized in this function [-Werror=uninitialized]
../../../git/gdb/target-attributes.c:486:18: error: ‘start’ may be used uninitialized in this function [-Werror=uninitialized]
../../../git/gdb/target-attributes.c: In function ‘target_attribute_attr_handler’:
../../../git/gdb/target-attributes.c:376:12: error: ‘type’ may be used uninitialized in this function [-Werror=uninitialized]
../../../git/gdb/target-attributes.c: In function ‘target_attribute_type’:
../../../git/gdb/target-attributes.c:632:3: error: ‘ret’ may be used uninitialized in this function [-Werror=uninitialized]
cc1: all warnings being treated as errors
make: *** [target-attributes.o] Error 1
The gcc I am using is 4.6.3
$ gcc --version
gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
We have to get these warnings fixed.
> +
> + len = VEC_length (gdb_xml_value_s, attributes);
> + for (i = 0; i < len; i++)
> + {
> + if (strcmp (attrs[i].name, "start") == 0)
> + start = * (ULONGEST *) attrs[i].value;
> + else if (strcmp (attrs[i].name, "end") == 0)
> + end = * (ULONGEST *) attrs[i].value;
> + else
> + gdb_xml_error (parser, _("Unknown attribute name '%s'."),
> + attrs[i].name);
> + }
> +
> + ta_addr = xmalloc (sizeof (struct target_attribute_address));
> + ta_addr->start = start;
> + ta_addr->end = end;
> +
> + ta_addr->prev = ta->addresses;
> + ta->addresses = ta_addr;
> +}
--
Yao
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] target attributes [1/5] core and load from target function
2012-08-29 14:43 ` Yao Qi
@ 2012-09-02 10:39 ` Hui Zhu
2012-11-21 8:56 ` Hui Zhu
0 siblings, 1 reply; 9+ messages in thread
From: Hui Zhu @ 2012-09-02 10:39 UTC (permalink / raw)
To: Yao Qi; +Cc: Hui Zhu, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2653 bytes --]
On Wed, Aug 29, 2012 at 10:43 PM, Yao Qi <yao@codesourcery.com> wrote:
> On 08/29/2012 04:11 PM, Hui Zhu wrote:
>> +static void
>> +target_attribute_address_handler (struct gdb_xml_parser *parser,
>> + const struct gdb_xml_element *element,
>> + void *user_data,
>> + VEC(gdb_xml_value_s) *attributes)
>> +{
>> + int i, len;
>> + struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
>> + struct target_attribute *ta = *(struct target_attribute **)user_data;
>> + CORE_ADDR start, end;
>> + struct target_attribute_address *ta_addr;
>
> I happen to see some compilation warnings on my new Fedora 16 box, while
> these warnings don't appear on my Ubuntu box.
>
> ... -Werror -c -o target-memory.o -MT target-memory.o -MMD -MP -MF .deps/target-memory.Tpo ../../../git/gdb/target-memory.c
> ../../../git/gdb/target-attributes.c: In function ‘target_attribute_address_handler’:
> ../../../git/gdb/target-attributes.c:487:16: error: ‘end’ may be used uninitialized in this function [-Werror=uninitialized]
> ../../../git/gdb/target-attributes.c:486:18: error: ‘start’ may be used uninitialized in this function [-Werror=uninitialized]
> ../../../git/gdb/target-attributes.c: In function ‘target_attribute_attr_handler’:
> ../../../git/gdb/target-attributes.c:376:12: error: ‘type’ may be used uninitialized in this function [-Werror=uninitialized]
> ../../../git/gdb/target-attributes.c: In function ‘target_attribute_type’:
> ../../../git/gdb/target-attributes.c:632:3: error: ‘ret’ may be used uninitialized in this function [-Werror=uninitialized]
> cc1: all warnings being treated as errors
> make: *** [target-attributes.o] Error 1
>
> The gcc I am using is 4.6.3
> $ gcc --version
> gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
>
> We have to get these warnings fixed.
>
>> +
>> + len = VEC_length (gdb_xml_value_s, attributes);
>> + for (i = 0; i < len; i++)
>> + {
>> + if (strcmp (attrs[i].name, "start") == 0)
>> + start = * (ULONGEST *) attrs[i].value;
>> + else if (strcmp (attrs[i].name, "end") == 0)
>> + end = * (ULONGEST *) attrs[i].value;
>> + else
>> + gdb_xml_error (parser, _("Unknown attribute name '%s'."),
>> + attrs[i].name);
>> + }
>> +
>> + ta_addr = xmalloc (sizeof (struct target_attribute_address));
>> + ta_addr->start = start;
>> + ta_addr->end = end;
>> +
>> + ta_addr->prev = ta->addresses;
>> + ta->addresses = ta_addr;
>> +}
>
> --
> Yao
Thanks. I post a new version.
Best,
Hui
[-- Attachment #2: target_attribute_load.txt --]
[-- Type: text/plain, Size: 31833 bytes --]
--- a/Makefile.in
+++ b/Makefile.in
@@ -731,7 +731,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
solib.c solib-target.c source.c \
stabsread.c stack.c probe.c stap-probe.c std-regs.c \
symfile.c symfile-mem.c symmisc.c symtab.c \
- target.c target-descriptions.c target-memory.c \
+ target.c target-attributes.c target-descriptions.c target-memory.c \
thread.c top.c tracepoint.c \
trad-frame.c \
tramp-frame.c \
@@ -831,7 +831,8 @@ gnulib/import/extra/snippet/warn-on-use.
gnulib/import/stddef.in.h gnulib/import/inttypes.in.h inline-frame.h skip.h \
common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
common/format.h common/host-defs.h utils.h \
-common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h gdb_bfd.h
+common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h gdb_bfd.h \
+target-attributes.h
# Header files that already have srcdir in them, or which are in objdir.
@@ -917,7 +918,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
solib.o solib-target.o \
prologue-value.o memory-map.o memrange.o \
xml-support.o xml-syscall.o xml-utils.o \
- target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
+ target-attributes.o target-descriptions.o target-memory.o \
+ xml-tdesc.o xml-builtin.o \
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
gdb_vecs.o jit.o progspace.o skip.o probe.o \
common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o \
--- a/breakpoint.h
+++ b/breakpoint.h
@@ -700,6 +700,11 @@ struct breakpoint
there is no condition. */
char *cond_string;
+ /* If True, the GDB side cannot do the condition check for
+ the condition of this breakpoint and this condition only can
+ be checked in agent side. */
+ int target_only_cond_check;
+
/* String form of extra parameters, or NULL if there are none. */
char *extra_string;
--- a/remote.c
+++ b/remote.c
@@ -43,6 +43,7 @@
#include "cli/cli-setshow.h"
#include "target-descriptions.h"
#include "gdb_bfd.h"
+#include "target-attributes.h"
#include <ctype.h>
#include <sys/time.h>
@@ -1292,6 +1293,7 @@ enum {
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
PACKET_QAgent,
+ PACKET_qXfer_target_attributes_read,
PACKET_MAX
};
@@ -3510,6 +3512,22 @@ remote_start_remote (int from_tty, struc
remote_check_symbols (symfile_objfile);
}
+ if (remote_protocol_packets[PACKET_qXfer_target_attributes_read].support
+ != PACKET_DISABLE)
+ {
+ char *text;
+
+ text = target_read_stralloc (¤t_target, TARGET_OBJECT_ATTRIBUTES,
+ NULL);
+ if (text != NULL)
+ {
+ struct cleanup *back_to = make_cleanup (xfree, text);
+
+ add_xml_target_attributes (text);
+ do_cleanups (back_to);
+ }
+ }
+
/* Possibly the target has been engaged in a trace run started
previously; find out where things are at. */
if (remote_get_trace_status (current_trace_status ()) != -1)
@@ -3946,6 +3964,8 @@ static struct protocol_feature remote_pr
{ "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent},
{ "tracenz", PACKET_DISABLE,
remote_string_tracing_feature, -1 },
+ { "qXfer:target-attributes:read", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_target_attributes_read },
};
static char *remote_support_xml;
@@ -8672,6 +8692,12 @@ remote_xfer_partial (struct target_ops *
return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len,
&remote_protocol_packets[PACKET_qXfer_uib]);
+ case TARGET_OBJECT_ATTRIBUTES:
+ gdb_assert (annex == NULL);
+ return remote_read_qxfer
+ (ops, "target-attributes", annex, readbuf, offset, len,
+ &remote_protocol_packets[PACKET_qXfer_target_attributes_read]);
+
default:
return -1;
}
@@ -11637,6 +11663,10 @@ Show the maximum size of the address (in
add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
"QAgent", "agent", 0);
+ add_packet_config_cmd
+ (&remote_protocol_packets[PACKET_qXfer_target_attributes_read],
+ "qXfer:target-attributes:read", "target-attributes", 0);
+
/* Keep the old ``set remote Z-packet ...'' working. Each individual
Z sub-packet has its own set and show commands, but users may
have sets to this variable in their .gdbinit files (or in their
--- /dev/null
+++ b/target-attributes.c
@@ -0,0 +1,669 @@
+/* Target attributes for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "ui-out.h"
+#include "tracepoint.h"
+#include "gdbcmd.h"
+#include "target-attributes.h"
+
+static struct target_attribute *target_attributes_list;
+
+struct target_attribute *
+find_target_attribute_name (const char *name)
+{
+ struct target_attribute *ta;
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ if (strcmp (ta->name, name) == 0)
+ return ta;
+ }
+
+ return NULL;
+}
+
+struct target_attribute *
+find_target_attribute_id (int id)
+{
+ struct target_attribute *ta;
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ if (id == ta->id)
+ return ta;
+ }
+
+ return NULL;
+}
+
+static struct bp_location *check_agent_target_attribute_bl = NULL;
+char *check_agent_target_attribute_error = NULL;
+
+static void
+clear_check_agent_target_attribute (void *unused)
+{
+ check_agent_target_attribute_bl = NULL;
+}
+
+struct cleanup *
+set_check_agent_target_attribute (struct bp_location *bl)
+{
+ check_agent_target_attribute_bl = bl;
+ check_agent_target_attribute_error = NULL;
+
+ return make_cleanup (clear_check_agent_target_attribute, NULL);
+}
+
+void
+check_agent_target_attribute (struct target_attribute *ta, int write)
+{
+ static char error_str[256];
+ check_agent_target_attribute_error = error_str;
+
+ if (write)
+ {
+ if ((ta->agent_access & TARGET_ATTRIBUTE_ACCESS_WRITE) == 0)
+ {
+ snprintf (error_str, 256, _("$%s cannot be written in agent code."),
+ ta->name);
+ error (_("$%s cannot be written in agent code."), ta->name);
+ }
+ }
+ else
+ {
+ if ((ta->agent_access & TARGET_ATTRIBUTE_ACCESS_READ) == 0)
+ {
+ snprintf (error_str, 256, _("$%s cannot be read in agent code."),
+ ta->name);
+ error (_("$%s cannot be read in agent code."), ta->name);
+ }
+ }
+
+ if (check_agent_target_attribute_bl)
+ {
+ struct target_attribute_address *ta_addr;
+
+ if (ta->target_only_cond_check)
+ check_agent_target_attribute_bl->owner->target_only_cond_check = 1;
+
+ switch (check_agent_target_attribute_bl->loc_type)
+ {
+ case bp_loc_software_breakpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in software breakpoint."),
+ ta->name);
+ error (_("$%s cannot be used in software breakpoint."), ta->name);
+ }
+ break;
+ case bp_loc_hardware_breakpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in hardware breakpoint."),
+ ta->name);
+ error (_("$%s cannot be used in hardware breakpoint."),
+ ta->name);
+ }
+ break;
+ case bp_loc_hardware_watchpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in hardware watchpoint."),
+ ta->name);
+ error (_("$%s cannot be used in hardware watchpoint."),
+ ta->name);
+ }
+ break;
+ default:
+ if (check_agent_target_attribute_bl->owner->type == bp_tracepoint
+ || check_agent_target_attribute_bl->owner->type
+ == bp_fast_tracepoint
+ || check_agent_target_attribute_bl->owner->type
+ == bp_static_tracepoint)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in tracepoint."), ta->name);
+ if ((ta->support & TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT) == 0)
+ error (_("$%s cannot be used in tracepoint."), ta->name);
+ }
+ else
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in breakpoint %d."),
+ ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ error (_("$%s cannot be used in breakpoint %d."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ }
+ break;
+ }
+
+ if (ta->addresses)
+ {
+ for (ta_addr = ta->addresses; ta_addr; ta_addr = ta_addr->prev)
+ {
+ if (check_agent_target_attribute_bl->address >= ta_addr->start
+ && check_agent_target_attribute_bl->address <= ta_addr->end)
+ break;
+ }
+ if (!ta_addr)
+ {
+ snprintf (error_str, 256,
+ _("\
+$%s cannot be used in breakpoint %d because the address limit."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ error (_("\
+$%s cannot be used in breakpoint %d because the address limit."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ }
+ }
+ }
+
+ check_agent_target_attribute_error = NULL;
+}
+
+void
+clear_target_attributes (void *unused)
+{
+ struct target_attribute *ta, *tmp;
+
+ for (ta = target_attributes_list; ta;)
+ {
+ struct target_attribute_address *ta_addr, *tmp_addr;
+
+ tmp = ta;
+ ta = ta->next;
+
+ for (ta_addr = tmp->addresses; ta_addr;)
+ {
+ tmp_addr = ta_addr;
+ ta_addr = ta_addr->prev;
+ xfree (tmp_addr);
+ }
+
+ xfree (tmp);
+ }
+
+ target_attributes_list = NULL;
+}
+
+static void
+info_target_attributes (char *args, int from_tty)
+{
+ struct target_attribute *ta;
+ struct cleanup *back_to;
+ struct ui_out *uiout = current_uiout;
+ int count = 0;
+
+ if (target_attributes_list == NULL)
+ {
+ ui_out_message (uiout, 0, _("No target attributes.\n"));
+ return;
+ }
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ count++;
+
+ back_to = make_cleanup_ui_out_table_begin_end (uiout, 6,
+ count, "target-attributes");
+ ui_out_table_header (uiout, 15, ui_left, "name", "Name");
+ ui_out_table_header (uiout, 15, ui_left, "type", "Type");
+ ui_out_table_header (uiout, 15, ui_left, "target-only-cond-check",
+ "Target-only-cond-check");
+ ui_out_table_header (uiout, 15, ui_left, "agent access", "Agent access");
+ ui_out_table_header (uiout, 15, ui_left, "gdb access", "GDB access");
+ ui_out_table_header (uiout, 15, ui_left, "breakpoint type",
+ "Breakpoint type");
+
+ ui_out_table_body (uiout);
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ struct target_attribute_address *ta_addr;
+ char buf[512];
+ struct cleanup *back_to2
+ = make_cleanup_ui_out_tuple_begin_end (uiout, "attributes");
+
+ snprintf (buf, 512, "$%s", ta->name);
+ ui_out_field_string (uiout, "name", buf);
+
+ switch (ta->type)
+ {
+ case TARGET_ATTRIBUTE_TYPE_INT8:
+ ui_out_field_string (uiout, "type", "int8");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT8:
+ ui_out_field_string (uiout, "type", "uint8");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT16:
+ ui_out_field_string (uiout, "type", "int16");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT16:
+ ui_out_field_string (uiout, "type", "uint16");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT32:
+ ui_out_field_string (uiout, "type", "int32");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT32:
+ ui_out_field_string (uiout, "type", "uint32");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT64:
+ ui_out_field_string (uiout, "type", "int64");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT64:
+ ui_out_field_string (uiout, "type", "uint64");
+ break;
+ }
+
+ ui_out_field_string (uiout, "target-only-cond-check",
+ ta->target_only_cond_check ? "yes" : "no");
+
+ snprintf (buf, 512, "%s%s",
+ (ta->agent_access
+ & TARGET_ATTRIBUTE_ACCESS_READ) ? "read " : "",
+ (ta->agent_access
+ & TARGET_ATTRIBUTE_ACCESS_WRITE) ? "write" : "");
+ ui_out_field_string (uiout, "agent access", buf);
+
+ snprintf (buf, 512, "%s%s",
+ (ta->gdb_access & TARGET_ATTRIBUTE_ACCESS_READ) ? "read " : "",
+ (ta->gdb_access
+ & TARGET_ATTRIBUTE_ACCESS_WRITE) ? "write" : "");
+ ui_out_field_string (uiout, "gdb access", buf);
+
+ snprintf (buf, 512, "%s%s%s%s",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT)
+ ? "software-breakpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT)
+ ? "hardware-breakpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT)
+ ? "hardware-watchpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT)
+ ? "tracepoint " : "");
+ ui_out_field_string (uiout, "breakpoint type", buf);
+
+ ui_out_text (uiout, "\n");
+
+ for (ta_addr = ta->addresses; ta_addr; ta_addr = ta_addr->prev)
+ {
+ ui_out_spaces (uiout, 2);
+ ui_out_message (uiout, 0, "start:%s end:%s\n",
+ paddress (target_gdbarch, ta_addr->start),
+ paddress (target_gdbarch, ta_addr->end));
+ }
+ do_cleanups (back_to2);
+ }
+
+ do_cleanups (back_to);
+}
+
+#if !defined(HAVE_LIBEXPAT)
+
+void
+add_xml_target_attributes (const char *text)
+{
+ if (strlen (text) > 0)
+ warning (_("Can not parse XML target attributes; XML support "
+ "was disabled at compile time"));
+}
+
+#else
+
+#include "xml-support.h"
+
+static void
+target_attribute_attr_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ char *name = NULL;
+ int i, len, id = -1, type = 0, target_only_cond_check = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+ struct target_attribute *ta, **tap = user_data;
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "name") == 0)
+ name = attrs[i].value;
+ else if (strcmp (attrs[i].name, "id") == 0)
+ id = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "type") == 0)
+ type = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "target-only-cond-check") == 0)
+ target_only_cond_check = * (ULONGEST *) attrs[i].value;
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ if (!name || id < 0)
+ gdb_xml_error (parser, _("\"name\" or \"id\" is missed."));
+
+ if (find_target_attribute_name (name))
+ gdb_xml_error (parser,_("\
+name \"%s\" is same with a target attribute."), name);
+ if (find_target_attribute_id (id))
+ gdb_xml_error (parser,_("id \"%d\" is same with a target attribute."), id);
+
+ ta = xzalloc (sizeof (struct target_attribute));
+ ta->name = xstrdup (name);
+ ta->id = id;
+ ta->type = type;
+ ta->target_only_cond_check = target_only_cond_check;
+
+ if (*tap)
+ (*tap)->next = ta;
+ else
+ target_attributes_list = ta;
+ *tap = ta;
+
+ user_data = &ta;
+}
+
+static void
+target_attribute_access_children_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ int i, len, ta_access = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "read") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta_access |= TARGET_ATTRIBUTE_ACCESS_READ;
+ }
+ else if (strcmp (attrs[i].name, "write") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta_access |= TARGET_ATTRIBUTE_ACCESS_WRITE;
+ }
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ if (strcmp (element->name, "agent") == 0)
+ ta->agent_access = ta_access;
+ else
+ ta->gdb_access = ta_access;
+}
+
+static void
+target_attribute_support_attr_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ int i, len = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "software-breakpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT;
+ }
+ else if (strcmp (attrs[i].name, "hardware-breakpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT;
+ }
+ else if (strcmp (attrs[i].name, "hardware-watchpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT;
+ }
+ else if (strcmp (attrs[i].name, "tracepoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT;
+ }
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+}
+
+static void
+target_attribute_address_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ int i, len;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ CORE_ADDR start = 0, end = 0;
+ struct target_attribute_address *ta_addr;
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "start") == 0)
+ start = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "end") == 0)
+ end = * (ULONGEST *) attrs[i].value;
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ ta_addr = xmalloc (sizeof (struct target_attribute_address));
+ ta_addr->start = start;
+ ta_addr->end = end;
+
+ ta_addr->prev = ta->addresses;
+ ta->addresses = ta_addr;
+}
+
+const struct gdb_xml_enum target_attribute_type_enums[] = {
+ { "int8", TARGET_ATTRIBUTE_TYPE_INT8 },
+ { "uint8", TARGET_ATTRIBUTE_TYPE_UINT8 },
+ { "int16", TARGET_ATTRIBUTE_TYPE_INT16 },
+ { "uint16", TARGET_ATTRIBUTE_TYPE_UINT16 },
+ { "int32", TARGET_ATTRIBUTE_TYPE_INT32 },
+ { "uint32", TARGET_ATTRIBUTE_TYPE_UINT32 },
+ { "int64", TARGET_ATTRIBUTE_TYPE_INT64 },
+ { "uint64", TARGET_ATTRIBUTE_TYPE_UINT64 },
+ { NULL, 0 }
+};
+
+static const struct gdb_xml_attribute target_attribute_attr[] = {
+ { "name", GDB_XML_AF_NONE, NULL, NULL },
+ { "id", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "type", GDB_XML_AF_NONE, gdb_xml_parse_attr_enum,
+ target_attribute_type_enums },
+ { "target-only-cond-check", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute
+ target_attribute_access_children_attr[] = {
+ { "read", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "write", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_access_children[] = {
+ { "agent", target_attribute_access_children_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_access_children_handler, NULL },
+ { "gdb", target_attribute_access_children_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_access_children_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute target_attribute_support_attr[] = {
+ { "software-breakpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "hardware-breakpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "hardware-watchpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "tracepoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute target_attribute_address_attr[] = {
+ { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_addresses_children[] = {
+ { "address", target_attribute_address_attr, NULL,
+ GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+ target_attribute_address_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_elements[] = {
+ { "access", NULL, target_attribute_access_children,
+ GDB_XML_EF_NONE, NULL, NULL },
+ { "support", target_attribute_support_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_support_attr_handler, NULL },
+ { "addresses", NULL, target_attribute_addresses_children,
+ GDB_XML_EF_OPTIONAL, NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attributes_children[] = {
+ { "target-attribute", target_attribute_attr, target_attribute_elements,
+ GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+ target_attribute_attr_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attributes_elements[] = {
+ { "target-attributes", NULL, target_attributes_children,
+ GDB_XML_EF_NONE, NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+void
+add_xml_target_attributes (const char *text)
+{
+ struct target_attribute *ta = NULL;
+ struct cleanup *back_to = make_cleanup (clear_target_attributes, NULL);
+
+ clear_target_attributes(NULL);
+ if (gdb_xml_parse_quick (_("target attributes"), NULL,
+ target_attributes_elements, text, &ta) == 0)
+ {
+ discard_cleanups (back_to);
+ trace_variable_number_check ();
+ }
+ else
+ do_cleanups (back_to);
+}
+
+#endif
+
+struct type *
+target_attribute_type (struct gdbarch *gdbarch, struct target_attribute *ta)
+{
+ struct type *ret = builtin_type (gdbarch)->builtin_uint64;
+
+ switch (ta->type)
+ {
+ case TARGET_ATTRIBUTE_TYPE_INT8:
+ ret = builtin_type (gdbarch)->builtin_int8;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT8:
+ ret = builtin_type (gdbarch)->builtin_uint8;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT16:
+ ret = builtin_type (gdbarch)->builtin_int16;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT16:
+ ret = builtin_type (gdbarch)->builtin_uint16;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT32:
+ ret = builtin_type (gdbarch)->builtin_int32;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT32:
+ ret = builtin_type (gdbarch)->builtin_uint32;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT64:
+ ret = builtin_type (gdbarch)->builtin_int64;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT64:
+ ret = builtin_type (gdbarch)->builtin_uint64;
+ break;
+ }
+
+ return ret;
+}
+
+static void
+load_target_attributes_command (char *exp, int from_tty)
+{
+ char *text = xml_fetch_content_from_file (exp, NULL);
+
+ if (text == NULL)
+ error (_("Could not open \"%s\""), exp);
+ add_xml_target_attributes (text);
+}
+
+static void
+clear_target_attributes_command (char *exp, int from_tty)
+{
+ clear_target_attributes (NULL);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_targets_attributes;
+
+void
+_initialize_targets_attributes (void)
+{
+ add_cmd ("load-target-attributes", class_maintenance,
+ load_target_attributes_command,
+ _("Load target attributes from a XML file."),
+ &maintenancelist);
+
+ add_cmd ("clear-target-attributes", class_maintenance,
+ clear_target_attributes_command,
+ _("Remove all target attributes."),
+ &maintenancelist);
+
+ add_info ("target-attributes", info_target_attributes, _("\
+Status of target attributes."));
+}
--- /dev/null
+++ b/target-attributes.h
@@ -0,0 +1,104 @@
+/* Target attributes for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef TARGET_ATTRIBUTES_H
+#define TARGET_ATTRIBUTES_H 1
+
+enum
+{
+ TARGET_ATTRIBUTE_TYPE_INT8,
+ TARGET_ATTRIBUTE_TYPE_UINT8,
+ TARGET_ATTRIBUTE_TYPE_INT16,
+ TARGET_ATTRIBUTE_TYPE_UINT16,
+ TARGET_ATTRIBUTE_TYPE_INT32,
+ TARGET_ATTRIBUTE_TYPE_UINT32,
+ TARGET_ATTRIBUTE_TYPE_INT64,
+ TARGET_ATTRIBUTE_TYPE_UINT64,
+};
+
+#define TARGET_ATTRIBUTE_ACCESS_READ 0x1
+#define TARGET_ATTRIBUTE_ACCESS_WRITE 0x2
+
+#define TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT 0x1
+#define TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT 0x2
+#define TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT 0x4
+#define TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT 0x8
+
+struct target_attribute_address
+ {
+ struct target_attribute_address *prev;
+ CORE_ADDR start;
+ CORE_ADDR end;
+ };
+
+/* This is the core struct of a target attribute.
+ When GDB get a target attribute from XML,
+ it will alloc a struct for it. */
+
+struct target_attribute
+ {
+ struct target_attribute *next;
+ char *name;
+ int id;
+ int type;
+ int target_only_cond_check;
+ unsigned int agent_access;
+ unsigned int gdb_access;
+ unsigned int support;
+ struct target_attribute_address *addresses;
+ };
+
+/* This is the error report string for function
+ check_agent_target_attribute.
+ Because some function call check_agent_target_attribute
+ with TRY_CATCH. Use this string report error. */
+
+extern char *check_agent_target_attribute_error;
+
+extern struct target_attribute *find_target_attribute_name (const char *name);
+extern struct target_attribute *find_target_attribute_id (int id);
+
+/* Set BL for function check_agent_target_attribute
+ before translate a string to agent expression bytecode. */
+
+extern struct cleanup *set_check_agent_target_attribute
+ (struct bp_location *bl);
+
+/* The function that translate a string to agent expression bytecode call
+ check_agent_target_attribute to check if TA is OK to use with
+ BL that set by set_check_agent_target_attribute. */
+
+extern void check_agent_target_attribute (struct target_attribute *ta,
+ int write);
+
+/* Remove all the target attributes inside the GDB. */
+
+extern void clear_target_attributes (void *unused);
+
+/* Parse target attributes out from XML formart string TEXT
+ and add them to GDB. */
+
+extern void add_xml_target_attributes (const char *text);
+
+/* Return the type of TA. */
+
+extern struct type *target_attribute_type (struct gdbarch *gdbarch,
+ struct target_attribute *ta);
+
+#endif /* TARGET_ATTRIBUTES_H */
--- a/target.h
+++ b/target.h
@@ -286,7 +286,9 @@ enum target_object
/* Darwin dynamic linker info data. */
TARGET_OBJECT_DARWIN_DYLD_INFO,
/* OpenVMS Unwind Information Block. */
- TARGET_OBJECT_OPENVMS_UIB
+ TARGET_OBJECT_OPENVMS_UIB,
+ /* Target attributes. */
+ TARGET_OBJECT_ATTRIBUTES,
/* Possible future objects: TARGET_OBJECT_FILE, ... */
};
--- a/tracepoint.c
+++ b/tracepoint.c
@@ -53,6 +53,7 @@
#include "exceptions.h"
#include "cli/cli-utils.h"
#include "probe.h"
+#include "target-attributes.h"
/* readline include files */
#include "readline/readline.h"
@@ -348,6 +349,21 @@ find_trace_state_variable (const char *n
return NULL;
}
+/* Look for a trace state variable of the given number. */
+
+static struct trace_state_variable *
+find_trace_state_variable_number (int number)
+{
+ struct trace_state_variable *tsv;
+ int ix;
+
+ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ if (number == tsv->number)
+ return tsv;
+
+ return NULL;
+}
+
static void
delete_trace_state_variable (const char *name)
{
@@ -365,6 +381,41 @@ delete_trace_state_variable (const char
warning (_("No trace variable named \"$%s\", not deleting"), name);
}
+static int
+trace_variable_number_check_1 (struct trace_state_variable *tsv)
+{
+ if (find_target_attribute_id (tsv->number))
+ {
+ int new_number = tsv->number + 1;
+ tsv->number = 0;
+ while (find_target_attribute_id (new_number)
+ || find_trace_state_variable_number (new_number))
+ new_number++;
+ tsv->number = new_number;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+trace_variable_number_check (void)
+{
+ struct trace_state_variable *tsv;
+ int ix;
+
+ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ {
+ if (trace_variable_number_check_1 (tsv))
+ {
+ warning (_("\
+number of trace variable $%s is same with a tsv compatible \n\
+target attribute. So it is changed to %d."), tsv->name, tsv->number);
+ }
+ }
+}
+
/* The 'tvariable' command collects a name and optional expression to
evaluate into an initial value. */
@@ -423,6 +474,8 @@ trace_variable_command (char *args, int
tsv = create_trace_state_variable (internalvar_name (intvar));
tsv->initial_value = initval;
+ trace_variable_number_check_1 (tsv);
+
printf_filtered (_("Trace state variable $%s "
"created, with initial value %s.\n"),
tsv->name, plongest (tsv->initial_value));
@@ -3602,6 +3655,8 @@ merge_uploaded_trace_state_variables (st
if (tsv->number == 0)
tsv->number = highest++;
+ trace_variable_number_check();
+
free_uploaded_tsvs (uploaded_tsvs);
}
--- a/tracepoint.h
+++ b/tracepoint.h
@@ -250,6 +250,8 @@ extern void while_stepping_pseudocommand
extern struct trace_state_variable *find_trace_state_variable (const char *name);
extern struct trace_state_variable *create_trace_state_variable (const char *name);
+extern void trace_variable_number_check(void);
+
extern int encode_source_string (int num, ULONGEST addr,
char *srctype, char *src,
char *buf, int buf_size);
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] target attributes [1/5] core and load from target function
2012-09-02 10:39 ` Hui Zhu
@ 2012-11-21 8:56 ` Hui Zhu
2012-11-30 6:03 ` Abid, Hafiz
0 siblings, 1 reply; 9+ messages in thread
From: Hui Zhu @ 2012-11-21 8:56 UTC (permalink / raw)
To: Yao Qi; +Cc: Hui Zhu, gdb-patches ml
[-- Attachment #1: Type: text/plain, Size: 2881 bytes --]
On Sun, Sep 2, 2012 at 6:37 PM, Hui Zhu <teawater@gmail.com> wrote:
> On Wed, Aug 29, 2012 at 10:43 PM, Yao Qi <yao@codesourcery.com> wrote:
>> On 08/29/2012 04:11 PM, Hui Zhu wrote:
>>> +static void
>>> +target_attribute_address_handler (struct gdb_xml_parser *parser,
>>> + const struct gdb_xml_element *element,
>>> + void *user_data,
>>> + VEC(gdb_xml_value_s) *attributes)
>>> +{
>>> + int i, len;
>>> + struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
>>> + struct target_attribute *ta = *(struct target_attribute **)user_data;
>>> + CORE_ADDR start, end;
>>> + struct target_attribute_address *ta_addr;
>>
>> I happen to see some compilation warnings on my new Fedora 16 box, while
>> these warnings don't appear on my Ubuntu box.
>>
>> ... -Werror -c -o target-memory.o -MT target-memory.o -MMD -MP -MF .deps/target-memory.Tpo ../../../git/gdb/target-memory.c
>> ../../../git/gdb/target-attributes.c: In function ‘target_attribute_address_handler’:
>> ../../../git/gdb/target-attributes.c:487:16: error: ‘end’ may be used uninitialized in this function [-Werror=uninitialized]
>> ../../../git/gdb/target-attributes.c:486:18: error: ‘start’ may be used uninitialized in this function [-Werror=uninitialized]
>> ../../../git/gdb/target-attributes.c: In function ‘target_attribute_attr_handler’:
>> ../../../git/gdb/target-attributes.c:376:12: error: ‘type’ may be used uninitialized in this function [-Werror=uninitialized]
>> ../../../git/gdb/target-attributes.c: In function ‘target_attribute_type’:
>> ../../../git/gdb/target-attributes.c:632:3: error: ‘ret’ may be used uninitialized in this function [-Werror=uninitialized]
>> cc1: all warnings being treated as errors
>> make: *** [target-attributes.o] Error 1
>>
>> The gcc I am using is 4.6.3
>> $ gcc --version
>> gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
>>
>> We have to get these warnings fixed.
>>
>>> +
>>> + len = VEC_length (gdb_xml_value_s, attributes);
>>> + for (i = 0; i < len; i++)
>>> + {
>>> + if (strcmp (attrs[i].name, "start") == 0)
>>> + start = * (ULONGEST *) attrs[i].value;
>>> + else if (strcmp (attrs[i].name, "end") == 0)
>>> + end = * (ULONGEST *) attrs[i].value;
>>> + else
>>> + gdb_xml_error (parser, _("Unknown attribute name '%s'."),
>>> + attrs[i].name);
>>> + }
>>> +
>>> + ta_addr = xmalloc (sizeof (struct target_attribute_address));
>>> + ta_addr->start = start;
>>> + ta_addr->end = end;
>>> +
>>> + ta_addr->prev = ta->addresses;
>>> + ta->addresses = ta_addr;
>>> +}
>>
>> --
>> Yao
>
> Thanks. I post a new version.
>
> Best,
> Hui
Got some error when built with trunk. Post a new version for this error.
Thanks,
Hui
[-- Attachment #2: target_attribute_load.txt --]
[-- Type: text/plain, Size: 31795 bytes --]
--- a/Makefile.in
+++ b/Makefile.in
@@ -731,7 +731,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
solib.c solib-target.c source.c \
stabsread.c stack.c probe.c stap-probe.c std-regs.c \
symfile.c symfile-mem.c symmisc.c symtab.c \
- target.c target-descriptions.c target-memory.c \
+ target.c target-attributes.c target-descriptions.c target-memory.c \
thread.c top.c tracepoint.c \
trad-frame.c \
tramp-frame.c \
@@ -831,7 +831,8 @@ gnulib/import/extra/snippet/warn-on-use.
gnulib/import/stddef.in.h gnulib/import/inttypes.in.h inline-frame.h skip.h \
common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
common/format.h common/host-defs.h utils.h \
-common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h gdb_bfd.h
+common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h gdb_bfd.h \
+target-attributes.h
# Header files that already have srcdir in them, or which are in objdir.
@@ -917,7 +918,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
solib.o solib-target.o \
prologue-value.o memory-map.o memrange.o \
xml-support.o xml-syscall.o xml-utils.o \
- target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
+ target-attributes.o target-descriptions.o target-memory.o \
+ xml-tdesc.o xml-builtin.o \
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
gdb_vecs.o jit.o progspace.o skip.o probe.o \
common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o \
--- a/breakpoint.h
+++ b/breakpoint.h
@@ -700,6 +700,11 @@ struct breakpoint
there is no condition. */
char *cond_string;
+ /* If True, the GDB side cannot do the condition check for
+ the condition of this breakpoint and this condition only can
+ be checked in agent side. */
+ int target_only_cond_check;
+
/* String form of extra parameters, or NULL if there are none. */
char *extra_string;
--- a/remote.c
+++ b/remote.c
@@ -43,6 +43,7 @@
#include "cli/cli-setshow.h"
#include "target-descriptions.h"
#include "gdb_bfd.h"
+#include "target-attributes.h"
#include <ctype.h>
#include <sys/time.h>
@@ -1292,6 +1293,7 @@ enum {
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
PACKET_QAgent,
+ PACKET_qXfer_target_attributes_read,
PACKET_MAX
};
@@ -3510,6 +3512,22 @@ remote_start_remote (int from_tty, struc
remote_check_symbols (symfile_objfile);
}
+ if (remote_protocol_packets[PACKET_qXfer_target_attributes_read].support
+ != PACKET_DISABLE)
+ {
+ char *text;
+
+ text = target_read_stralloc (¤t_target, TARGET_OBJECT_ATTRIBUTES,
+ NULL);
+ if (text != NULL)
+ {
+ struct cleanup *back_to = make_cleanup (xfree, text);
+
+ add_xml_target_attributes (text);
+ do_cleanups (back_to);
+ }
+ }
+
/* Possibly the target has been engaged in a trace run started
previously; find out where things are at. */
if (remote_get_trace_status (current_trace_status ()) != -1)
@@ -3946,6 +3964,8 @@ static struct protocol_feature remote_pr
{ "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent},
{ "tracenz", PACKET_DISABLE,
remote_string_tracing_feature, -1 },
+ { "qXfer:target-attributes:read", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_target_attributes_read },
};
static char *remote_support_xml;
@@ -8682,6 +8702,12 @@ remote_xfer_partial (struct target_ops *
return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len,
&remote_protocol_packets[PACKET_qXfer_uib]);
+ case TARGET_OBJECT_ATTRIBUTES:
+ gdb_assert (annex == NULL);
+ return remote_read_qxfer
+ (ops, "target-attributes", annex, readbuf, offset, len,
+ &remote_protocol_packets[PACKET_qXfer_target_attributes_read]);
+
default:
return -1;
}
@@ -11643,6 +11669,10 @@ Show the maximum size of the address (in
add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
"QAgent", "agent", 0);
+ add_packet_config_cmd
+ (&remote_protocol_packets[PACKET_qXfer_target_attributes_read],
+ "qXfer:target-attributes:read", "target-attributes", 0);
+
/* Keep the old ``set remote Z-packet ...'' working. Each individual
Z sub-packet has its own set and show commands, but users may
have sets to this variable in their .gdbinit files (or in their
--- /dev/null
+++ b/target-attributes.c
@@ -0,0 +1,669 @@
+/* Target attributes for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "ui-out.h"
+#include "tracepoint.h"
+#include "gdbcmd.h"
+#include "target-attributes.h"
+
+static struct target_attribute *target_attributes_list;
+
+struct target_attribute *
+find_target_attribute_name (const char *name)
+{
+ struct target_attribute *ta;
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ if (strcmp (ta->name, name) == 0)
+ return ta;
+ }
+
+ return NULL;
+}
+
+struct target_attribute *
+find_target_attribute_id (int id)
+{
+ struct target_attribute *ta;
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ if (id == ta->id)
+ return ta;
+ }
+
+ return NULL;
+}
+
+static struct bp_location *check_agent_target_attribute_bl = NULL;
+char *check_agent_target_attribute_error = NULL;
+
+static void
+clear_check_agent_target_attribute (void *unused)
+{
+ check_agent_target_attribute_bl = NULL;
+}
+
+struct cleanup *
+set_check_agent_target_attribute (struct bp_location *bl)
+{
+ check_agent_target_attribute_bl = bl;
+ check_agent_target_attribute_error = NULL;
+
+ return make_cleanup (clear_check_agent_target_attribute, NULL);
+}
+
+void
+check_agent_target_attribute (struct target_attribute *ta, int write)
+{
+ static char error_str[256];
+ check_agent_target_attribute_error = error_str;
+
+ if (write)
+ {
+ if ((ta->agent_access & TARGET_ATTRIBUTE_ACCESS_WRITE) == 0)
+ {
+ snprintf (error_str, 256, _("$%s cannot be written in agent code."),
+ ta->name);
+ error (_("$%s cannot be written in agent code."), ta->name);
+ }
+ }
+ else
+ {
+ if ((ta->agent_access & TARGET_ATTRIBUTE_ACCESS_READ) == 0)
+ {
+ snprintf (error_str, 256, _("$%s cannot be read in agent code."),
+ ta->name);
+ error (_("$%s cannot be read in agent code."), ta->name);
+ }
+ }
+
+ if (check_agent_target_attribute_bl)
+ {
+ struct target_attribute_address *ta_addr;
+
+ if (ta->target_only_cond_check)
+ check_agent_target_attribute_bl->owner->target_only_cond_check = 1;
+
+ switch (check_agent_target_attribute_bl->loc_type)
+ {
+ case bp_loc_software_breakpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in software breakpoint."),
+ ta->name);
+ error (_("$%s cannot be used in software breakpoint."), ta->name);
+ }
+ break;
+ case bp_loc_hardware_breakpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in hardware breakpoint."),
+ ta->name);
+ error (_("$%s cannot be used in hardware breakpoint."),
+ ta->name);
+ }
+ break;
+ case bp_loc_hardware_watchpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in hardware watchpoint."),
+ ta->name);
+ error (_("$%s cannot be used in hardware watchpoint."),
+ ta->name);
+ }
+ break;
+ default:
+ if (check_agent_target_attribute_bl->owner->type == bp_tracepoint
+ || check_agent_target_attribute_bl->owner->type
+ == bp_fast_tracepoint
+ || check_agent_target_attribute_bl->owner->type
+ == bp_static_tracepoint)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in tracepoint."), ta->name);
+ if ((ta->support & TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT) == 0)
+ error (_("$%s cannot be used in tracepoint."), ta->name);
+ }
+ else
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in breakpoint %d."),
+ ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ error (_("$%s cannot be used in breakpoint %d."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ }
+ break;
+ }
+
+ if (ta->addresses)
+ {
+ for (ta_addr = ta->addresses; ta_addr; ta_addr = ta_addr->prev)
+ {
+ if (check_agent_target_attribute_bl->address >= ta_addr->start
+ && check_agent_target_attribute_bl->address <= ta_addr->end)
+ break;
+ }
+ if (!ta_addr)
+ {
+ snprintf (error_str, 256,
+ _("\
+$%s cannot be used in breakpoint %d because the address limit."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ error (_("\
+$%s cannot be used in breakpoint %d because the address limit."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ }
+ }
+ }
+
+ check_agent_target_attribute_error = NULL;
+}
+
+void
+clear_target_attributes (void *unused)
+{
+ struct target_attribute *ta, *tmp;
+
+ for (ta = target_attributes_list; ta;)
+ {
+ struct target_attribute_address *ta_addr, *tmp_addr;
+
+ tmp = ta;
+ ta = ta->next;
+
+ for (ta_addr = tmp->addresses; ta_addr;)
+ {
+ tmp_addr = ta_addr;
+ ta_addr = ta_addr->prev;
+ xfree (tmp_addr);
+ }
+
+ xfree (tmp);
+ }
+
+ target_attributes_list = NULL;
+}
+
+static void
+info_target_attributes (char *args, int from_tty)
+{
+ struct target_attribute *ta;
+ struct cleanup *back_to;
+ struct ui_out *uiout = current_uiout;
+ int count = 0;
+
+ if (target_attributes_list == NULL)
+ {
+ ui_out_message (uiout, 0, _("No target attributes.\n"));
+ return;
+ }
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ count++;
+
+ back_to = make_cleanup_ui_out_table_begin_end (uiout, 6,
+ count, "target-attributes");
+ ui_out_table_header (uiout, 15, ui_left, "name", "Name");
+ ui_out_table_header (uiout, 15, ui_left, "type", "Type");
+ ui_out_table_header (uiout, 15, ui_left, "target-only-cond-check",
+ "Target-only-cond-check");
+ ui_out_table_header (uiout, 15, ui_left, "agent access", "Agent access");
+ ui_out_table_header (uiout, 15, ui_left, "gdb access", "GDB access");
+ ui_out_table_header (uiout, 15, ui_left, "breakpoint type",
+ "Breakpoint type");
+
+ ui_out_table_body (uiout);
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ struct target_attribute_address *ta_addr;
+ char buf[512];
+ struct cleanup *back_to2
+ = make_cleanup_ui_out_tuple_begin_end (uiout, "attributes");
+
+ snprintf (buf, 512, "$%s", ta->name);
+ ui_out_field_string (uiout, "name", buf);
+
+ switch (ta->type)
+ {
+ case TARGET_ATTRIBUTE_TYPE_INT8:
+ ui_out_field_string (uiout, "type", "int8");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT8:
+ ui_out_field_string (uiout, "type", "uint8");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT16:
+ ui_out_field_string (uiout, "type", "int16");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT16:
+ ui_out_field_string (uiout, "type", "uint16");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT32:
+ ui_out_field_string (uiout, "type", "int32");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT32:
+ ui_out_field_string (uiout, "type", "uint32");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT64:
+ ui_out_field_string (uiout, "type", "int64");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT64:
+ ui_out_field_string (uiout, "type", "uint64");
+ break;
+ }
+
+ ui_out_field_string (uiout, "target-only-cond-check",
+ ta->target_only_cond_check ? "yes" : "no");
+
+ snprintf (buf, 512, "%s%s",
+ (ta->agent_access
+ & TARGET_ATTRIBUTE_ACCESS_READ) ? "read " : "",
+ (ta->agent_access
+ & TARGET_ATTRIBUTE_ACCESS_WRITE) ? "write" : "");
+ ui_out_field_string (uiout, "agent access", buf);
+
+ snprintf (buf, 512, "%s%s",
+ (ta->gdb_access & TARGET_ATTRIBUTE_ACCESS_READ) ? "read " : "",
+ (ta->gdb_access
+ & TARGET_ATTRIBUTE_ACCESS_WRITE) ? "write" : "");
+ ui_out_field_string (uiout, "gdb access", buf);
+
+ snprintf (buf, 512, "%s%s%s%s",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT)
+ ? "software-breakpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT)
+ ? "hardware-breakpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT)
+ ? "hardware-watchpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT)
+ ? "tracepoint " : "");
+ ui_out_field_string (uiout, "breakpoint type", buf);
+
+ ui_out_text (uiout, "\n");
+
+ for (ta_addr = ta->addresses; ta_addr; ta_addr = ta_addr->prev)
+ {
+ ui_out_spaces (uiout, 2);
+ ui_out_message (uiout, 0, "start:%s end:%s\n",
+ paddress (target_gdbarch (), ta_addr->start),
+ paddress (target_gdbarch (), ta_addr->end));
+ }
+ do_cleanups (back_to2);
+ }
+
+ do_cleanups (back_to);
+}
+
+#if !defined(HAVE_LIBEXPAT)
+
+void
+add_xml_target_attributes (const char *text)
+{
+ if (strlen (text) > 0)
+ warning (_("Can not parse XML target attributes; XML support "
+ "was disabled at compile time"));
+}
+
+#else
+
+#include "xml-support.h"
+
+static void
+target_attribute_attr_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ char *name = NULL;
+ int i, len, id = -1, type = 0, target_only_cond_check = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+ struct target_attribute *ta, **tap = user_data;
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "name") == 0)
+ name = attrs[i].value;
+ else if (strcmp (attrs[i].name, "id") == 0)
+ id = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "type") == 0)
+ type = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "target-only-cond-check") == 0)
+ target_only_cond_check = * (ULONGEST *) attrs[i].value;
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ if (!name || id < 0)
+ gdb_xml_error (parser, _("\"name\" or \"id\" is missed."));
+
+ if (find_target_attribute_name (name))
+ gdb_xml_error (parser,_("\
+name \"%s\" is same with a target attribute."), name);
+ if (find_target_attribute_id (id))
+ gdb_xml_error (parser,_("id \"%d\" is same with a target attribute."), id);
+
+ ta = xzalloc (sizeof (struct target_attribute));
+ ta->name = xstrdup (name);
+ ta->id = id;
+ ta->type = type;
+ ta->target_only_cond_check = target_only_cond_check;
+
+ if (*tap)
+ (*tap)->next = ta;
+ else
+ target_attributes_list = ta;
+ *tap = ta;
+
+ user_data = &ta;
+}
+
+static void
+target_attribute_access_children_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ int i, len, ta_access = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "read") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta_access |= TARGET_ATTRIBUTE_ACCESS_READ;
+ }
+ else if (strcmp (attrs[i].name, "write") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta_access |= TARGET_ATTRIBUTE_ACCESS_WRITE;
+ }
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ if (strcmp (element->name, "agent") == 0)
+ ta->agent_access = ta_access;
+ else
+ ta->gdb_access = ta_access;
+}
+
+static void
+target_attribute_support_attr_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ int i, len = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "software-breakpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT;
+ }
+ else if (strcmp (attrs[i].name, "hardware-breakpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT;
+ }
+ else if (strcmp (attrs[i].name, "hardware-watchpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT;
+ }
+ else if (strcmp (attrs[i].name, "tracepoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT;
+ }
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+}
+
+static void
+target_attribute_address_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ int i, len;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ CORE_ADDR start = 0, end = 0;
+ struct target_attribute_address *ta_addr;
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "start") == 0)
+ start = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "end") == 0)
+ end = * (ULONGEST *) attrs[i].value;
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ ta_addr = xmalloc (sizeof (struct target_attribute_address));
+ ta_addr->start = start;
+ ta_addr->end = end;
+
+ ta_addr->prev = ta->addresses;
+ ta->addresses = ta_addr;
+}
+
+const struct gdb_xml_enum target_attribute_type_enums[] = {
+ { "int8", TARGET_ATTRIBUTE_TYPE_INT8 },
+ { "uint8", TARGET_ATTRIBUTE_TYPE_UINT8 },
+ { "int16", TARGET_ATTRIBUTE_TYPE_INT16 },
+ { "uint16", TARGET_ATTRIBUTE_TYPE_UINT16 },
+ { "int32", TARGET_ATTRIBUTE_TYPE_INT32 },
+ { "uint32", TARGET_ATTRIBUTE_TYPE_UINT32 },
+ { "int64", TARGET_ATTRIBUTE_TYPE_INT64 },
+ { "uint64", TARGET_ATTRIBUTE_TYPE_UINT64 },
+ { NULL, 0 }
+};
+
+static const struct gdb_xml_attribute target_attribute_attr[] = {
+ { "name", GDB_XML_AF_NONE, NULL, NULL },
+ { "id", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "type", GDB_XML_AF_NONE, gdb_xml_parse_attr_enum,
+ target_attribute_type_enums },
+ { "target-only-cond-check", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute
+ target_attribute_access_children_attr[] = {
+ { "read", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "write", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_access_children[] = {
+ { "agent", target_attribute_access_children_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_access_children_handler, NULL },
+ { "gdb", target_attribute_access_children_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_access_children_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute target_attribute_support_attr[] = {
+ { "software-breakpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "hardware-breakpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "hardware-watchpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "tracepoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute target_attribute_address_attr[] = {
+ { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_addresses_children[] = {
+ { "address", target_attribute_address_attr, NULL,
+ GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+ target_attribute_address_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_elements[] = {
+ { "access", NULL, target_attribute_access_children,
+ GDB_XML_EF_NONE, NULL, NULL },
+ { "support", target_attribute_support_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_support_attr_handler, NULL },
+ { "addresses", NULL, target_attribute_addresses_children,
+ GDB_XML_EF_OPTIONAL, NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attributes_children[] = {
+ { "target-attribute", target_attribute_attr, target_attribute_elements,
+ GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+ target_attribute_attr_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attributes_elements[] = {
+ { "target-attributes", NULL, target_attributes_children,
+ GDB_XML_EF_NONE, NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+void
+add_xml_target_attributes (const char *text)
+{
+ struct target_attribute *ta = NULL;
+ struct cleanup *back_to = make_cleanup (clear_target_attributes, NULL);
+
+ clear_target_attributes(NULL);
+ if (gdb_xml_parse_quick (_("target attributes"), NULL,
+ target_attributes_elements, text, &ta) == 0)
+ {
+ discard_cleanups (back_to);
+ trace_variable_number_check ();
+ }
+ else
+ do_cleanups (back_to);
+}
+
+#endif
+
+struct type *
+target_attribute_type (struct gdbarch *gdbarch, struct target_attribute *ta)
+{
+ struct type *ret = builtin_type (gdbarch)->builtin_uint64;
+
+ switch (ta->type)
+ {
+ case TARGET_ATTRIBUTE_TYPE_INT8:
+ ret = builtin_type (gdbarch)->builtin_int8;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT8:
+ ret = builtin_type (gdbarch)->builtin_uint8;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT16:
+ ret = builtin_type (gdbarch)->builtin_int16;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT16:
+ ret = builtin_type (gdbarch)->builtin_uint16;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT32:
+ ret = builtin_type (gdbarch)->builtin_int32;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT32:
+ ret = builtin_type (gdbarch)->builtin_uint32;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT64:
+ ret = builtin_type (gdbarch)->builtin_int64;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT64:
+ ret = builtin_type (gdbarch)->builtin_uint64;
+ break;
+ }
+
+ return ret;
+}
+
+static void
+load_target_attributes_command (char *exp, int from_tty)
+{
+ char *text = xml_fetch_content_from_file (exp, NULL);
+
+ if (text == NULL)
+ error (_("Could not open \"%s\""), exp);
+ add_xml_target_attributes (text);
+}
+
+static void
+clear_target_attributes_command (char *exp, int from_tty)
+{
+ clear_target_attributes (NULL);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_targets_attributes;
+
+void
+_initialize_targets_attributes (void)
+{
+ add_cmd ("load-target-attributes", class_maintenance,
+ load_target_attributes_command,
+ _("Load target attributes from a XML file."),
+ &maintenancelist);
+
+ add_cmd ("clear-target-attributes", class_maintenance,
+ clear_target_attributes_command,
+ _("Remove all target attributes."),
+ &maintenancelist);
+
+ add_info ("target-attributes", info_target_attributes, _("\
+Status of target attributes."));
+}
--- /dev/null
+++ b/target-attributes.h
@@ -0,0 +1,104 @@
+/* Target attributes for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef TARGET_ATTRIBUTES_H
+#define TARGET_ATTRIBUTES_H 1
+
+enum
+{
+ TARGET_ATTRIBUTE_TYPE_INT8,
+ TARGET_ATTRIBUTE_TYPE_UINT8,
+ TARGET_ATTRIBUTE_TYPE_INT16,
+ TARGET_ATTRIBUTE_TYPE_UINT16,
+ TARGET_ATTRIBUTE_TYPE_INT32,
+ TARGET_ATTRIBUTE_TYPE_UINT32,
+ TARGET_ATTRIBUTE_TYPE_INT64,
+ TARGET_ATTRIBUTE_TYPE_UINT64,
+};
+
+#define TARGET_ATTRIBUTE_ACCESS_READ 0x1
+#define TARGET_ATTRIBUTE_ACCESS_WRITE 0x2
+
+#define TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT 0x1
+#define TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT 0x2
+#define TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT 0x4
+#define TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT 0x8
+
+struct target_attribute_address
+ {
+ struct target_attribute_address *prev;
+ CORE_ADDR start;
+ CORE_ADDR end;
+ };
+
+/* This is the core struct of a target attribute.
+ When GDB get a target attribute from XML,
+ it will alloc a struct for it. */
+
+struct target_attribute
+ {
+ struct target_attribute *next;
+ char *name;
+ int id;
+ int type;
+ int target_only_cond_check;
+ unsigned int agent_access;
+ unsigned int gdb_access;
+ unsigned int support;
+ struct target_attribute_address *addresses;
+ };
+
+/* This is the error report string for function
+ check_agent_target_attribute.
+ Because some function call check_agent_target_attribute
+ with TRY_CATCH. Use this string report error. */
+
+extern char *check_agent_target_attribute_error;
+
+extern struct target_attribute *find_target_attribute_name (const char *name);
+extern struct target_attribute *find_target_attribute_id (int id);
+
+/* Set BL for function check_agent_target_attribute
+ before translate a string to agent expression bytecode. */
+
+extern struct cleanup *set_check_agent_target_attribute
+ (struct bp_location *bl);
+
+/* The function that translate a string to agent expression bytecode call
+ check_agent_target_attribute to check if TA is OK to use with
+ BL that set by set_check_agent_target_attribute. */
+
+extern void check_agent_target_attribute (struct target_attribute *ta,
+ int write);
+
+/* Remove all the target attributes inside the GDB. */
+
+extern void clear_target_attributes (void *unused);
+
+/* Parse target attributes out from XML formart string TEXT
+ and add them to GDB. */
+
+extern void add_xml_target_attributes (const char *text);
+
+/* Return the type of TA. */
+
+extern struct type *target_attribute_type (struct gdbarch *gdbarch,
+ struct target_attribute *ta);
+
+#endif /* TARGET_ATTRIBUTES_H */
--- a/target.h
+++ b/target.h
@@ -286,7 +286,9 @@ enum target_object
/* Darwin dynamic linker info data. */
TARGET_OBJECT_DARWIN_DYLD_INFO,
/* OpenVMS Unwind Information Block. */
- TARGET_OBJECT_OPENVMS_UIB
+ TARGET_OBJECT_OPENVMS_UIB,
+ /* Target attributes. */
+ TARGET_OBJECT_ATTRIBUTES,
/* Possible future objects: TARGET_OBJECT_FILE, ... */
};
--- a/tracepoint.c
+++ b/tracepoint.c
@@ -53,6 +53,7 @@
#include "exceptions.h"
#include "cli/cli-utils.h"
#include "probe.h"
+#include "target-attributes.h"
/* readline include files */
#include "readline/readline.h"
@@ -348,6 +349,21 @@ find_trace_state_variable (const char *n
return NULL;
}
+/* Look for a trace state variable of the given number. */
+
+static struct trace_state_variable *
+find_trace_state_variable_number (int number)
+{
+ struct trace_state_variable *tsv;
+ int ix;
+
+ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ if (number == tsv->number)
+ return tsv;
+
+ return NULL;
+}
+
static void
delete_trace_state_variable (const char *name)
{
@@ -368,6 +384,41 @@ delete_trace_state_variable (const char
warning (_("No trace variable named \"$%s\", not deleting"), name);
}
+static int
+trace_variable_number_check_1 (struct trace_state_variable *tsv)
+{
+ if (find_target_attribute_id (tsv->number))
+ {
+ int new_number = tsv->number + 1;
+ tsv->number = 0;
+ while (find_target_attribute_id (new_number)
+ || find_trace_state_variable_number (new_number))
+ new_number++;
+ tsv->number = new_number;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+trace_variable_number_check (void)
+{
+ struct trace_state_variable *tsv;
+ int ix;
+
+ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ {
+ if (trace_variable_number_check_1 (tsv))
+ {
+ warning (_("\
+number of trace variable $%s is same with a tsv compatible \n\
+target attribute. So it is changed to %d."), tsv->name, tsv->number);
+ }
+ }
+}
+
/* The 'tvariable' command collects a name and optional expression to
evaluate into an initial value. */
@@ -428,6 +479,8 @@ trace_variable_command (char *args, int
observer_notify_tsv_created (tsv->name, initval);
+ trace_variable_number_check_1 (tsv);
+
printf_filtered (_("Trace state variable $%s "
"created, with initial value %s.\n"),
tsv->name, plongest (tsv->initial_value));
@@ -3616,6 +3669,8 @@ merge_uploaded_trace_state_variables (st
if (tsv->number == 0)
tsv->number = highest++;
+ trace_variable_number_check();
+
free_uploaded_tsvs (uploaded_tsvs);
}
--- a/tracepoint.h
+++ b/tracepoint.h
@@ -250,6 +250,8 @@ extern void while_stepping_pseudocommand
extern struct trace_state_variable *find_trace_state_variable (const char *name);
extern struct trace_state_variable *create_trace_state_variable (const char *name);
+extern void trace_variable_number_check(void);
+
extern int encode_source_string (int num, ULONGEST addr,
char *srctype, char *src,
char *buf, int buf_size);
^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH] target attributes [1/5] core and load from target function
2012-11-21 8:56 ` Hui Zhu
@ 2012-11-30 6:03 ` Abid, Hafiz
2013-02-18 10:02 ` Hui Zhu
0 siblings, 1 reply; 9+ messages in thread
From: Abid, Hafiz @ 2012-11-30 6:03 UTC (permalink / raw)
To: Hui Zhu, Qi, Yao; +Cc: Zhu, Hui, gdb-patches ml
Hi,
>+ ta = xzalloc (sizeof (struct target_attribute));
>+ ta->name = xstrdup (name);
This name is not freed and will leak.
>+ if (*tap)
>+ (*tap)->next = ta;
>+ else
>+ target_attributes_list = ta;
>+ *tap = ta;
>+
>+ user_data = &ta;
So you are assigning ta to (*tap) and (*tap)->next. Then user_data is also being assigned. It did not look right to me. I wanted to bring it in your attention in case it is a typo.
>+ unsigned int agent_access;
>+ unsigned int gdb_access;
I can understand the access mode for GDB. But what agent_access means and how it will effect a user?
> -----Original Message-----
> From: gdb-patches-owner@sourceware.org [mailto:gdb-patches-
> owner@sourceware.org] On Behalf Of Hui Zhu
> Sent: Wednesday, November 21, 2012 8:55 AM
> To: Qi, Yao
> Cc: Zhu, Hui; gdb-patches ml
> Subject: Re: [PATCH] target attributes [1/5] core and load from target
> function
>
> On Sun, Sep 2, 2012 at 6:37 PM, Hui Zhu <teawater@gmail.com> wrote:
> > On Wed, Aug 29, 2012 at 10:43 PM, Yao Qi <yao@codesourcery.com>
> wrote:
> >> On 08/29/2012 04:11 PM, Hui Zhu wrote:
> >>> +static void
> >>> +target_attribute_address_handler (struct gdb_xml_parser *parser,
> >>> + const struct gdb_xml_element
> *element,
> >>> + void *user_data,
> >>> + VEC(gdb_xml_value_s) *attributes) {
> >>> + int i, len;
> >>> + struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s,
> >>> +attributes);
> >>> + struct target_attribute *ta = *(struct target_attribute
> >>> +**)user_data;
> >>> + CORE_ADDR start, end;
> >>> + struct target_attribute_address *ta_addr;
> >>
> >> I happen to see some compilation warnings on my new Fedora 16 box,
> >> while these warnings don't appear on my Ubuntu box.
> >>
> >> ... -Werror -c -o target-memory.o -MT target-memory.o -MMD -MP -MF
> >> .deps/target-memory.Tpo ../../../git/gdb/target-memory.c
> >> ../../../git/gdb/target-attributes.c: In function
> 'target_attribute_address_handler':
> >> ../../../git/gdb/target-attributes.c:487:16: error: 'end' may be
> used
> >> uninitialized in this function [-Werror=uninitialized]
> >> ../../../git/gdb/target-attributes.c:486:18: error: 'start' may be
> >> used uninitialized in this function [-Werror=uninitialized]
> >> ../../../git/gdb/target-attributes.c: In function
> 'target_attribute_attr_handler':
> >> ../../../git/gdb/target-attributes.c:376:12: error: 'type' may be
> >> used uninitialized in this function [-Werror=uninitialized]
> >> ../../../git/gdb/target-attributes.c: In function
> 'target_attribute_type':
> >> ../../../git/gdb/target-attributes.c:632:3: error: 'ret' may be used
> >> uninitialized in this function [-Werror=uninitialized]
> >> cc1: all warnings being treated as errors
> >> make: *** [target-attributes.o] Error 1
> >>
> >> The gcc I am using is 4.6.3
> >> $ gcc --version
> >> gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
> >>
> >> We have to get these warnings fixed.
> >>
> >>> +
> >>> + len = VEC_length (gdb_xml_value_s, attributes); for (i = 0; i <
> >>> + len; i++)
> >>> + {
> >>> + if (strcmp (attrs[i].name, "start") == 0)
> >>> + start = * (ULONGEST *) attrs[i].value;
> >>> + else if (strcmp (attrs[i].name, "end") == 0)
> >>> + end = * (ULONGEST *) attrs[i].value;
> >>> + else
> >>> + gdb_xml_error (parser, _("Unknown attribute name '%s'."),
> >>> + attrs[i].name);
> >>> + }
> >>> +
> >>> + ta_addr = xmalloc (sizeof (struct target_attribute_address));
> >>> + ta_addr->start = start; ta_addr->end = end;
> >>> +
> >>> + ta_addr->prev = ta->addresses;
> >>> + ta->addresses = ta_addr;
> >>> +}
> >>
> >> --
> >> Yao
> >
> > Thanks. I post a new version.
> >
> > Best,
> > Hui
>
> Got some error when built with trunk. Post a new version for this
> error.
>
> Thanks,
> Hui
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] target attributes [1/5] core and load from target function
2012-11-30 6:03 ` Abid, Hafiz
@ 2013-02-18 10:02 ` Hui Zhu
2013-02-18 11:45 ` Abid, Hafiz
0 siblings, 1 reply; 9+ messages in thread
From: Hui Zhu @ 2013-02-18 10:02 UTC (permalink / raw)
To: Abid, Hafiz; +Cc: Qi, Yao, Zhu, Hui, gdb-patches ml
[-- Attachment #1: Type: text/plain, Size: 5424 bytes --]
On Fri, Nov 30, 2012 at 2:03 PM, Abid, Hafiz <Hafiz_Abid@mentor.com> wrote:
> Hi,
>
>>+ ta = xzalloc (sizeof (struct target_attribute));
>>+ ta->name = xstrdup (name);
> This name is not freed and will leak.
Added xfree in clear_target_attributes.
>
>>+ if (*tap)
>>+ (*tap)->next = ta;
>>+ else
>>+ target_attributes_list = ta;
>>+ *tap = ta;
>>+
>>+ user_data = &ta;
>
> So you are assigning ta to (*tap) and (*tap)->next. Then user_data is also being assigned. It did not look right to me. I wanted to bring it in your attention in case it is a typo.
user_data will always point to the last one of target_attributes_list.
Could you tell me which part is wrong?
>
>>+ unsigned int agent_access;
>>+ unsigned int gdb_access;
> I can understand the access mode for GDB. But what agent_access means and how it will effect a user?
There is the introduce of agent
http://sourceware.org/gdb/current/onlinedocs/gdb/Agent-Expressions.html
Post a new version according to your review.
Thanks,
Hui
2013-02-18 Hui Zhu <hui_zhu@mentor.com>
* Makefile.in (SFILES): Add target-attributes.c.
(HFILES_NO_SRCDIR): Add target-attributes.h.
(COMMON_OBS): Add target-attributes.o.
* breakpoint.h (breakpoint): Add target_only_cond_check.
* remote.c (target-attributes.h): New include.
(PACKET_qXfer_target_attributes_read): New enum.
(remote_start_remote): Add handler for target attributes.
(remote_protocol_features): Add "qXfer:target-attributes:read".
(remote_xfer_partial): Add handler for TARGET_OBJECT_ATTRIBUTES.
(_initialize_remote): Add command
"set remote target-attributes-packet".
(target-attributes.c, target-attributes.h): New files.
* tracepoint.c (target-attributes.h): New include.
(find_trace_state_variable_number,
trace_variable_number_check_1,
trace_variable_number_check): New functions.
(trace_variable_command): Call trace_variable_number_check_1.
(merge_uploaded_trace_state_variables): Call
trace_variable_number_check.
tracepoint.h (trace_variable_number_check): New extern.
>
>> -----Original Message-----
>> From: gdb-patches-owner@sourceware.org [mailto:gdb-patches-
>> owner@sourceware.org] On Behalf Of Hui Zhu
>> Sent: Wednesday, November 21, 2012 8:55 AM
>> To: Qi, Yao
>> Cc: Zhu, Hui; gdb-patches ml
>> Subject: Re: [PATCH] target attributes [1/5] core and load from target
>> function
>>
>> On Sun, Sep 2, 2012 at 6:37 PM, Hui Zhu <teawater@gmail.com> wrote:
>> > On Wed, Aug 29, 2012 at 10:43 PM, Yao Qi <yao@codesourcery.com>
>> wrote:
>> >> On 08/29/2012 04:11 PM, Hui Zhu wrote:
>> >>> +static void
>> >>> +target_attribute_address_handler (struct gdb_xml_parser *parser,
>> >>> + const struct gdb_xml_element
>> *element,
>> >>> + void *user_data,
>> >>> + VEC(gdb_xml_value_s) *attributes) {
>> >>> + int i, len;
>> >>> + struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s,
>> >>> +attributes);
>> >>> + struct target_attribute *ta = *(struct target_attribute
>> >>> +**)user_data;
>> >>> + CORE_ADDR start, end;
>> >>> + struct target_attribute_address *ta_addr;
>> >>
>> >> I happen to see some compilation warnings on my new Fedora 16 box,
>> >> while these warnings don't appear on my Ubuntu box.
>> >>
>> >> ... -Werror -c -o target-memory.o -MT target-memory.o -MMD -MP -MF
>> >> .deps/target-memory.Tpo ../../../git/gdb/target-memory.c
>> >> ../../../git/gdb/target-attributes.c: In function
>> 'target_attribute_address_handler':
>> >> ../../../git/gdb/target-attributes.c:487:16: error: 'end' may be
>> used
>> >> uninitialized in this function [-Werror=uninitialized]
>> >> ../../../git/gdb/target-attributes.c:486:18: error: 'start' may be
>> >> used uninitialized in this function [-Werror=uninitialized]
>> >> ../../../git/gdb/target-attributes.c: In function
>> 'target_attribute_attr_handler':
>> >> ../../../git/gdb/target-attributes.c:376:12: error: 'type' may be
>> >> used uninitialized in this function [-Werror=uninitialized]
>> >> ../../../git/gdb/target-attributes.c: In function
>> 'target_attribute_type':
>> >> ../../../git/gdb/target-attributes.c:632:3: error: 'ret' may be used
>> >> uninitialized in this function [-Werror=uninitialized]
>> >> cc1: all warnings being treated as errors
>> >> make: *** [target-attributes.o] Error 1
>> >>
>> >> The gcc I am using is 4.6.3
>> >> $ gcc --version
>> >> gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
>> >>
>> >> We have to get these warnings fixed.
>> >>
>> >>> +
>> >>> + len = VEC_length (gdb_xml_value_s, attributes); for (i = 0; i <
>> >>> + len; i++)
>> >>> + {
>> >>> + if (strcmp (attrs[i].name, "start") == 0)
>> >>> + start = * (ULONGEST *) attrs[i].value;
>> >>> + else if (strcmp (attrs[i].name, "end") == 0)
>> >>> + end = * (ULONGEST *) attrs[i].value;
>> >>> + else
>> >>> + gdb_xml_error (parser, _("Unknown attribute name '%s'."),
>> >>> + attrs[i].name);
>> >>> + }
>> >>> +
>> >>> + ta_addr = xmalloc (sizeof (struct target_attribute_address));
>> >>> + ta_addr->start = start; ta_addr->end = end;
>> >>> +
>> >>> + ta_addr->prev = ta->addresses;
>> >>> + ta->addresses = ta_addr;
>> >>> +}
>> >>
>> >> --
>> >> Yao
>> >
>> > Thanks. I post a new version.
>> >
>> > Best,
>> > Hui
>>
>> Got some error when built with trunk. Post a new version for this
>> error.
>>
>> Thanks,
>> Hui
[-- Attachment #2: target_attribute_load.txt --]
[-- Type: text/plain, Size: 31770 bytes --]
--- a/Makefile.in
+++ b/Makefile.in
@@ -742,7 +742,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
solib.c solib-target.c source.c \
stabsread.c stack.c probe.c stap-probe.c std-regs.c \
symfile.c symfile-mem.c symmisc.c symtab.c \
- target.c target-descriptions.c target-memory.c \
+ target.c target-attributes.c target-descriptions.c target-memory.c \
thread.c top.c tracepoint.c \
trad-frame.c \
tramp-frame.c \
@@ -835,7 +835,7 @@ gnulib/import/stddef.in.h gnulib/import/
common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
common/format.h common/host-defs.h utils.h common/queue.h \
common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h \
-gdb_bfd.h sparc-ravenscar-thread.h ppc-ravenscar-thread.h
+gdb_bfd.h sparc-ravenscar-thread.h ppc-ravenscar-thread.h target-attributes.h
# Header files that already have srcdir in them, or which are in objdir.
@@ -924,7 +924,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
solib.o solib-target.o \
prologue-value.o memory-map.o memrange.o \
xml-support.o xml-syscall.o xml-utils.o \
- target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
+ target-attributes.o target-descriptions.o target-memory.o \
+ xml-tdesc.o xml-builtin.o \
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
gdb_vecs.o jit.o progspace.o skip.o probe.o \
common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o \
--- a/breakpoint.h
+++ b/breakpoint.h
@@ -726,6 +726,11 @@ struct breakpoint
there is no condition. */
char *cond_string;
+ /* If True, the GDB side cannot do the condition check for
+ the condition of this breakpoint and this condition only can
+ be checked in agent side. */
+ int target_only_cond_check;
+
/* String form of extra parameters, or NULL if there are none. */
char *extra_string;
--- a/remote.c
+++ b/remote.c
@@ -44,6 +44,7 @@
#include "cli/cli-setshow.h"
#include "target-descriptions.h"
#include "gdb_bfd.h"
+#include "target-attributes.h"
#include <ctype.h>
#include <sys/time.h>
@@ -1284,6 +1285,7 @@ enum {
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
PACKET_QAgent,
+ PACKET_qXfer_target_attributes_read,
PACKET_MAX
};
@@ -3559,6 +3561,22 @@ remote_start_remote (int from_tty, struc
remote_check_symbols (symfile_objfile);
}
+ if (remote_protocol_packets[PACKET_qXfer_target_attributes_read].support
+ != PACKET_DISABLE)
+ {
+ char *text;
+
+ text = target_read_stralloc (¤t_target, TARGET_OBJECT_ATTRIBUTES,
+ NULL);
+ if (text != NULL)
+ {
+ struct cleanup *back_to = make_cleanup (xfree, text);
+
+ add_xml_target_attributes (text);
+ do_cleanups (back_to);
+ }
+ }
+
/* Possibly the target has been engaged in a trace run started
previously; find out where things are at. */
if (remote_get_trace_status (current_trace_status ()) != -1)
@@ -3995,6 +4013,8 @@ static struct protocol_feature remote_pr
{ "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent},
{ "tracenz", PACKET_DISABLE,
remote_string_tracing_feature, -1 },
+ { "qXfer:target-attributes:read", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_target_attributes_read },
};
static char *remote_support_xml;
@@ -8796,6 +8816,12 @@ remote_xfer_partial (struct target_ops *
return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len,
&remote_protocol_packets[PACKET_qXfer_uib]);
+ case TARGET_OBJECT_ATTRIBUTES:
+ gdb_assert (annex == NULL);
+ return remote_read_qxfer
+ (ops, "target-attributes", annex, readbuf, offset, len,
+ &remote_protocol_packets[PACKET_qXfer_target_attributes_read]);
+
default:
return -1;
}
@@ -11755,6 +11781,10 @@ Show the maximum size of the address (in
add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
"QAgent", "agent", 0);
+ add_packet_config_cmd
+ (&remote_protocol_packets[PACKET_qXfer_target_attributes_read],
+ "qXfer:target-attributes:read", "target-attributes", 0);
+
/* Keep the old ``set remote Z-packet ...'' working. Each individual
Z sub-packet has its own set and show commands, but users may
have sets to this variable in their .gdbinit files (or in their
--- /dev/null
+++ b/target-attributes.c
@@ -0,0 +1,670 @@
+/* Target attributes for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "ui-out.h"
+#include "tracepoint.h"
+#include "gdbcmd.h"
+#include "target-attributes.h"
+
+static struct target_attribute *target_attributes_list;
+
+struct target_attribute *
+find_target_attribute_name (const char *name)
+{
+ struct target_attribute *ta;
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ if (strcmp (ta->name, name) == 0)
+ return ta;
+ }
+
+ return NULL;
+}
+
+struct target_attribute *
+find_target_attribute_id (int id)
+{
+ struct target_attribute *ta;
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ if (id == ta->id)
+ return ta;
+ }
+
+ return NULL;
+}
+
+static struct bp_location *check_agent_target_attribute_bl = NULL;
+char *check_agent_target_attribute_error = NULL;
+
+static void
+clear_check_agent_target_attribute (void *unused)
+{
+ check_agent_target_attribute_bl = NULL;
+}
+
+struct cleanup *
+set_check_agent_target_attribute (struct bp_location *bl)
+{
+ check_agent_target_attribute_bl = bl;
+ check_agent_target_attribute_error = NULL;
+
+ return make_cleanup (clear_check_agent_target_attribute, NULL);
+}
+
+void
+check_agent_target_attribute (struct target_attribute *ta, int write)
+{
+ static char error_str[256];
+ check_agent_target_attribute_error = error_str;
+
+ if (write)
+ {
+ if ((ta->agent_access & TARGET_ATTRIBUTE_ACCESS_WRITE) == 0)
+ {
+ snprintf (error_str, 256, _("$%s cannot be written in agent code."),
+ ta->name);
+ error (_("$%s cannot be written in agent code."), ta->name);
+ }
+ }
+ else
+ {
+ if ((ta->agent_access & TARGET_ATTRIBUTE_ACCESS_READ) == 0)
+ {
+ snprintf (error_str, 256, _("$%s cannot be read in agent code."),
+ ta->name);
+ error (_("$%s cannot be read in agent code."), ta->name);
+ }
+ }
+
+ if (check_agent_target_attribute_bl)
+ {
+ struct target_attribute_address *ta_addr;
+
+ if (ta->target_only_cond_check)
+ check_agent_target_attribute_bl->owner->target_only_cond_check = 1;
+
+ switch (check_agent_target_attribute_bl->loc_type)
+ {
+ case bp_loc_software_breakpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in software breakpoint."),
+ ta->name);
+ error (_("$%s cannot be used in software breakpoint."), ta->name);
+ }
+ break;
+ case bp_loc_hardware_breakpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in hardware breakpoint."),
+ ta->name);
+ error (_("$%s cannot be used in hardware breakpoint."),
+ ta->name);
+ }
+ break;
+ case bp_loc_hardware_watchpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in hardware watchpoint."),
+ ta->name);
+ error (_("$%s cannot be used in hardware watchpoint."),
+ ta->name);
+ }
+ break;
+ default:
+ if (check_agent_target_attribute_bl->owner->type == bp_tracepoint
+ || check_agent_target_attribute_bl->owner->type
+ == bp_fast_tracepoint
+ || check_agent_target_attribute_bl->owner->type
+ == bp_static_tracepoint)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in tracepoint."), ta->name);
+ if ((ta->support & TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT) == 0)
+ error (_("$%s cannot be used in tracepoint."), ta->name);
+ }
+ else
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in breakpoint %d."),
+ ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ error (_("$%s cannot be used in breakpoint %d."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ }
+ break;
+ }
+
+ if (ta->addresses)
+ {
+ for (ta_addr = ta->addresses; ta_addr; ta_addr = ta_addr->prev)
+ {
+ if (check_agent_target_attribute_bl->address >= ta_addr->start
+ && check_agent_target_attribute_bl->address <= ta_addr->end)
+ break;
+ }
+ if (!ta_addr)
+ {
+ snprintf (error_str, 256,
+ _("\
+$%s cannot be used in breakpoint %d because the address limit."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ error (_("\
+$%s cannot be used in breakpoint %d because the address limit."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ }
+ }
+ }
+
+ check_agent_target_attribute_error = NULL;
+}
+
+void
+clear_target_attributes (void *unused)
+{
+ struct target_attribute *ta, *tmp;
+
+ for (ta = target_attributes_list; ta;)
+ {
+ struct target_attribute_address *ta_addr, *tmp_addr;
+
+ tmp = ta;
+ ta = ta->next;
+
+ for (ta_addr = tmp->addresses; ta_addr;)
+ {
+ tmp_addr = ta_addr;
+ ta_addr = ta_addr->prev;
+ xfree (tmp_addr);
+ }
+
+ xfree (tmp->name)
+ xfree (tmp);
+ }
+
+ target_attributes_list = NULL;
+}
+
+static void
+info_target_attributes (char *args, int from_tty)
+{
+ struct target_attribute *ta;
+ struct cleanup *back_to;
+ struct ui_out *uiout = current_uiout;
+ int count = 0;
+
+ if (target_attributes_list == NULL)
+ {
+ ui_out_message (uiout, 0, _("No target attributes.\n"));
+ return;
+ }
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ count++;
+
+ back_to = make_cleanup_ui_out_table_begin_end (uiout, 6,
+ count, "target-attributes");
+ ui_out_table_header (uiout, 15, ui_left, "name", "Name");
+ ui_out_table_header (uiout, 15, ui_left, "type", "Type");
+ ui_out_table_header (uiout, 15, ui_left, "target-only-cond-check",
+ "Target-only-cond-check");
+ ui_out_table_header (uiout, 15, ui_left, "agent access", "Agent access");
+ ui_out_table_header (uiout, 15, ui_left, "gdb access", "GDB access");
+ ui_out_table_header (uiout, 15, ui_left, "breakpoint type",
+ "Breakpoint type");
+
+ ui_out_table_body (uiout);
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ struct target_attribute_address *ta_addr;
+ char buf[512];
+ struct cleanup *back_to2
+ = make_cleanup_ui_out_tuple_begin_end (uiout, "attributes");
+
+ snprintf (buf, 512, "$%s", ta->name);
+ ui_out_field_string (uiout, "name", buf);
+
+ switch (ta->type)
+ {
+ case TARGET_ATTRIBUTE_TYPE_INT8:
+ ui_out_field_string (uiout, "type", "int8");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT8:
+ ui_out_field_string (uiout, "type", "uint8");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT16:
+ ui_out_field_string (uiout, "type", "int16");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT16:
+ ui_out_field_string (uiout, "type", "uint16");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT32:
+ ui_out_field_string (uiout, "type", "int32");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT32:
+ ui_out_field_string (uiout, "type", "uint32");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT64:
+ ui_out_field_string (uiout, "type", "int64");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT64:
+ ui_out_field_string (uiout, "type", "uint64");
+ break;
+ }
+
+ ui_out_field_string (uiout, "target-only-cond-check",
+ ta->target_only_cond_check ? "yes" : "no");
+
+ snprintf (buf, 512, "%s%s",
+ (ta->agent_access
+ & TARGET_ATTRIBUTE_ACCESS_READ) ? "read " : "",
+ (ta->agent_access
+ & TARGET_ATTRIBUTE_ACCESS_WRITE) ? "write" : "");
+ ui_out_field_string (uiout, "agent access", buf);
+
+ snprintf (buf, 512, "%s%s",
+ (ta->gdb_access & TARGET_ATTRIBUTE_ACCESS_READ) ? "read " : "",
+ (ta->gdb_access
+ & TARGET_ATTRIBUTE_ACCESS_WRITE) ? "write" : "");
+ ui_out_field_string (uiout, "gdb access", buf);
+
+ snprintf (buf, 512, "%s%s%s%s",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT)
+ ? "software-breakpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT)
+ ? "hardware-breakpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT)
+ ? "hardware-watchpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT)
+ ? "tracepoint " : "");
+ ui_out_field_string (uiout, "breakpoint type", buf);
+
+ ui_out_text (uiout, "\n");
+
+ for (ta_addr = ta->addresses; ta_addr; ta_addr = ta_addr->prev)
+ {
+ ui_out_spaces (uiout, 2);
+ ui_out_message (uiout, 0, "start:%s end:%s\n",
+ paddress (target_gdbarch (), ta_addr->start),
+ paddress (target_gdbarch (), ta_addr->end));
+ }
+ do_cleanups (back_to2);
+ }
+
+ do_cleanups (back_to);
+}
+
+#if !defined(HAVE_LIBEXPAT)
+
+void
+add_xml_target_attributes (const char *text)
+{
+ if (strlen (text) > 0)
+ warning (_("Can not parse XML target attributes; XML support "
+ "was disabled at compile time"));
+}
+
+#else
+
+#include "xml-support.h"
+
+static void
+target_attribute_attr_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ char *name = NULL;
+ int i, len, id = -1, type = 0, target_only_cond_check = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+ struct target_attribute *ta, **tap = user_data;
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "name") == 0)
+ name = attrs[i].value;
+ else if (strcmp (attrs[i].name, "id") == 0)
+ id = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "type") == 0)
+ type = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "target-only-cond-check") == 0)
+ target_only_cond_check = * (ULONGEST *) attrs[i].value;
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ if (!name || id < 0)
+ gdb_xml_error (parser, _("\"name\" or \"id\" is missed."));
+
+ if (find_target_attribute_name (name))
+ gdb_xml_error (parser,_("\
+name \"%s\" is same with a target attribute."), name);
+ if (find_target_attribute_id (id))
+ gdb_xml_error (parser,_("id \"%d\" is same with a target attribute."), id);
+
+ ta = xzalloc (sizeof (struct target_attribute));
+ ta->name = xstrdup (name);
+ ta->id = id;
+ ta->type = type;
+ ta->target_only_cond_check = target_only_cond_check;
+
+ if (*tap)
+ (*tap)->next = ta;
+ else
+ target_attributes_list = ta;
+ *tap = ta;
+
+ user_data = &ta;
+}
+
+static void
+target_attribute_access_children_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ int i, len, ta_access = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "read") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta_access |= TARGET_ATTRIBUTE_ACCESS_READ;
+ }
+ else if (strcmp (attrs[i].name, "write") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta_access |= TARGET_ATTRIBUTE_ACCESS_WRITE;
+ }
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ if (strcmp (element->name, "agent") == 0)
+ ta->agent_access = ta_access;
+ else
+ ta->gdb_access = ta_access;
+}
+
+static void
+target_attribute_support_attr_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ int i, len = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "software-breakpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT;
+ }
+ else if (strcmp (attrs[i].name, "hardware-breakpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT;
+ }
+ else if (strcmp (attrs[i].name, "hardware-watchpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT;
+ }
+ else if (strcmp (attrs[i].name, "tracepoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT;
+ }
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+}
+
+static void
+target_attribute_address_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ int i, len;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ CORE_ADDR start = 0, end = 0;
+ struct target_attribute_address *ta_addr;
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "start") == 0)
+ start = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "end") == 0)
+ end = * (ULONGEST *) attrs[i].value;
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ ta_addr = xmalloc (sizeof (struct target_attribute_address));
+ ta_addr->start = start;
+ ta_addr->end = end;
+
+ ta_addr->prev = ta->addresses;
+ ta->addresses = ta_addr;
+}
+
+const struct gdb_xml_enum target_attribute_type_enums[] = {
+ { "int8", TARGET_ATTRIBUTE_TYPE_INT8 },
+ { "uint8", TARGET_ATTRIBUTE_TYPE_UINT8 },
+ { "int16", TARGET_ATTRIBUTE_TYPE_INT16 },
+ { "uint16", TARGET_ATTRIBUTE_TYPE_UINT16 },
+ { "int32", TARGET_ATTRIBUTE_TYPE_INT32 },
+ { "uint32", TARGET_ATTRIBUTE_TYPE_UINT32 },
+ { "int64", TARGET_ATTRIBUTE_TYPE_INT64 },
+ { "uint64", TARGET_ATTRIBUTE_TYPE_UINT64 },
+ { NULL, 0 }
+};
+
+static const struct gdb_xml_attribute target_attribute_attr[] = {
+ { "name", GDB_XML_AF_NONE, NULL, NULL },
+ { "id", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "type", GDB_XML_AF_NONE, gdb_xml_parse_attr_enum,
+ target_attribute_type_enums },
+ { "target-only-cond-check", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute
+ target_attribute_access_children_attr[] = {
+ { "read", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "write", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_access_children[] = {
+ { "agent", target_attribute_access_children_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_access_children_handler, NULL },
+ { "gdb", target_attribute_access_children_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_access_children_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute target_attribute_support_attr[] = {
+ { "software-breakpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "hardware-breakpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "hardware-watchpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "tracepoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute target_attribute_address_attr[] = {
+ { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_addresses_children[] = {
+ { "address", target_attribute_address_attr, NULL,
+ GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+ target_attribute_address_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_elements[] = {
+ { "access", NULL, target_attribute_access_children,
+ GDB_XML_EF_NONE, NULL, NULL },
+ { "support", target_attribute_support_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_support_attr_handler, NULL },
+ { "addresses", NULL, target_attribute_addresses_children,
+ GDB_XML_EF_OPTIONAL, NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attributes_children[] = {
+ { "target-attribute", target_attribute_attr, target_attribute_elements,
+ GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+ target_attribute_attr_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attributes_elements[] = {
+ { "target-attributes", NULL, target_attributes_children,
+ GDB_XML_EF_NONE, NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+void
+add_xml_target_attributes (const char *text)
+{
+ struct target_attribute *ta = NULL;
+ struct cleanup *back_to = make_cleanup (clear_target_attributes, NULL);
+
+ clear_target_attributes(NULL);
+ if (gdb_xml_parse_quick (_("target attributes"), NULL,
+ target_attributes_elements, text, &ta) == 0)
+ {
+ discard_cleanups (back_to);
+ trace_variable_number_check ();
+ }
+ else
+ do_cleanups (back_to);
+}
+
+#endif
+
+struct type *
+target_attribute_type (struct gdbarch *gdbarch, struct target_attribute *ta)
+{
+ struct type *ret = builtin_type (gdbarch)->builtin_uint64;
+
+ switch (ta->type)
+ {
+ case TARGET_ATTRIBUTE_TYPE_INT8:
+ ret = builtin_type (gdbarch)->builtin_int8;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT8:
+ ret = builtin_type (gdbarch)->builtin_uint8;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT16:
+ ret = builtin_type (gdbarch)->builtin_int16;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT16:
+ ret = builtin_type (gdbarch)->builtin_uint16;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT32:
+ ret = builtin_type (gdbarch)->builtin_int32;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT32:
+ ret = builtin_type (gdbarch)->builtin_uint32;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT64:
+ ret = builtin_type (gdbarch)->builtin_int64;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT64:
+ ret = builtin_type (gdbarch)->builtin_uint64;
+ break;
+ }
+
+ return ret;
+}
+
+static void
+load_target_attributes_command (char *exp, int from_tty)
+{
+ char *text = xml_fetch_content_from_file (exp, NULL);
+
+ if (text == NULL)
+ error (_("Could not open \"%s\""), exp);
+ add_xml_target_attributes (text);
+}
+
+static void
+clear_target_attributes_command (char *exp, int from_tty)
+{
+ clear_target_attributes (NULL);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_targets_attributes;
+
+void
+_initialize_targets_attributes (void)
+{
+ add_cmd ("load-target-attributes", class_maintenance,
+ load_target_attributes_command,
+ _("Load target attributes from a XML file."),
+ &maintenancelist);
+
+ add_cmd ("clear-target-attributes", class_maintenance,
+ clear_target_attributes_command,
+ _("Remove all target attributes."),
+ &maintenancelist);
+
+ add_info ("target-attributes", info_target_attributes, _("\
+Status of target attributes."));
+}
--- /dev/null
+++ b/target-attributes.h
@@ -0,0 +1,104 @@
+/* Target attributes for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef TARGET_ATTRIBUTES_H
+#define TARGET_ATTRIBUTES_H 1
+
+enum
+{
+ TARGET_ATTRIBUTE_TYPE_INT8,
+ TARGET_ATTRIBUTE_TYPE_UINT8,
+ TARGET_ATTRIBUTE_TYPE_INT16,
+ TARGET_ATTRIBUTE_TYPE_UINT16,
+ TARGET_ATTRIBUTE_TYPE_INT32,
+ TARGET_ATTRIBUTE_TYPE_UINT32,
+ TARGET_ATTRIBUTE_TYPE_INT64,
+ TARGET_ATTRIBUTE_TYPE_UINT64,
+};
+
+#define TARGET_ATTRIBUTE_ACCESS_READ 0x1
+#define TARGET_ATTRIBUTE_ACCESS_WRITE 0x2
+
+#define TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT 0x1
+#define TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT 0x2
+#define TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT 0x4
+#define TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT 0x8
+
+struct target_attribute_address
+ {
+ struct target_attribute_address *prev;
+ CORE_ADDR start;
+ CORE_ADDR end;
+ };
+
+/* This is the core struct of a target attribute.
+ When GDB get a target attribute from XML,
+ it will alloc a struct for it. */
+
+struct target_attribute
+ {
+ struct target_attribute *next;
+ char *name;
+ int id;
+ int type;
+ int target_only_cond_check;
+ unsigned int agent_access;
+ unsigned int gdb_access;
+ unsigned int support;
+ struct target_attribute_address *addresses;
+ };
+
+/* This is the error report string for function
+ check_agent_target_attribute.
+ Because some function call check_agent_target_attribute
+ with TRY_CATCH. Use this string report error. */
+
+extern char *check_agent_target_attribute_error;
+
+extern struct target_attribute *find_target_attribute_name (const char *name);
+extern struct target_attribute *find_target_attribute_id (int id);
+
+/* Set BL for function check_agent_target_attribute
+ before translate a string to agent expression bytecode. */
+
+extern struct cleanup *set_check_agent_target_attribute
+ (struct bp_location *bl);
+
+/* The function that translate a string to agent expression bytecode call
+ check_agent_target_attribute to check if TA is OK to use with
+ BL that set by set_check_agent_target_attribute. */
+
+extern void check_agent_target_attribute (struct target_attribute *ta,
+ int write);
+
+/* Remove all the target attributes inside the GDB. */
+
+extern void clear_target_attributes (void *unused);
+
+/* Parse target attributes out from XML formart string TEXT
+ and add them to GDB. */
+
+extern void add_xml_target_attributes (const char *text);
+
+/* Return the type of TA. */
+
+extern struct type *target_attribute_type (struct gdbarch *gdbarch,
+ struct target_attribute *ta);
+
+#endif /* TARGET_ATTRIBUTES_H */
--- a/target.h
+++ b/target.h
@@ -286,7 +286,9 @@ enum target_object
/* Darwin dynamic linker info data. */
TARGET_OBJECT_DARWIN_DYLD_INFO,
/* OpenVMS Unwind Information Block. */
- TARGET_OBJECT_OPENVMS_UIB
+ TARGET_OBJECT_OPENVMS_UIB,
+ /* Target attributes. */
+ TARGET_OBJECT_ATTRIBUTES,
/* Possible future objects: TARGET_OBJECT_FILE, ... */
};
--- a/tracepoint.c
+++ b/tracepoint.c
@@ -53,6 +53,7 @@
#include "exceptions.h"
#include "cli/cli-utils.h"
#include "probe.h"
+#include "target-attributes.h"
/* readline include files */
#include "readline/readline.h"
@@ -342,6 +343,21 @@ find_trace_state_variable (const char *n
return NULL;
}
+/* Look for a trace state variable of the given number. */
+
+static struct trace_state_variable *
+find_trace_state_variable_number (int number)
+{
+ struct trace_state_variable *tsv;
+ int ix;
+
+ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ if (number == tsv->number)
+ return tsv;
+
+ return NULL;
+}
+
static void
delete_trace_state_variable (const char *name)
{
@@ -386,6 +402,41 @@ validate_trace_state_variable_name (cons
error (_("$%s is not a valid trace state variable name"), name);
}
+static int
+trace_variable_number_check_1 (struct trace_state_variable *tsv)
+{
+ if (find_target_attribute_id (tsv->number))
+ {
+ int new_number = tsv->number + 1;
+ tsv->number = 0;
+ while (find_target_attribute_id (new_number)
+ || find_trace_state_variable_number (new_number))
+ new_number++;
+ tsv->number = new_number;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+trace_variable_number_check (void)
+{
+ struct trace_state_variable *tsv;
+ int ix;
+
+ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ {
+ if (trace_variable_number_check_1 (tsv))
+ {
+ warning (_("\
+number of trace variable $%s is same with a tsv compatible \n\
+target attribute. So it is changed to %d."), tsv->name, tsv->number);
+ }
+ }
+}
+
/* The 'tvariable' command collects a name and optional expression to
evaluate into an initial value. */
@@ -443,6 +494,8 @@ trace_variable_command (char *args, int
observer_notify_tsv_created (tsv);
+ trace_variable_number_check_1 (tsv);
+
printf_filtered (_("Trace state variable $%s "
"created, with initial value %s.\n"),
tsv->name, plongest (tsv->initial_value));
@@ -3674,6 +3727,8 @@ merge_uploaded_trace_state_variables (st
if (tsv->number == 0)
tsv->number = highest++;
+ trace_variable_number_check();
+
free_uploaded_tsvs (uploaded_tsvs);
}
--- a/tracepoint.h
+++ b/tracepoint.h
@@ -248,6 +248,8 @@ extern void validate_trace_state_variabl
extern struct trace_state_variable *find_trace_state_variable (const char *name);
extern struct trace_state_variable *create_trace_state_variable (const char *name);
+extern void trace_variable_number_check(void);
+
extern int encode_source_string (int num, ULONGEST addr,
char *srctype, char *src,
char *buf, int buf_size);
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] target attributes [1/5] core and load from target function
2013-02-18 10:02 ` Hui Zhu
@ 2013-02-18 11:45 ` Abid, Hafiz
2013-02-19 16:11 ` Hui Zhu
0 siblings, 1 reply; 9+ messages in thread
From: Abid, Hafiz @ 2013-02-18 11:45 UTC (permalink / raw)
To: Hui Zhu; +Cc: Abid, Hafiz, Qi, Yao, Zhu, Hui, gdb-patches ml
On 18/02/13 10:01:10, Hui Zhu wrote:
> On Fri, Nov 30, 2012 at 2:03 PM, Abid, Hafiz <Hafiz_Abid@mentor.com>
> wrote:
> > Hi,
> >
> >>+ ta = xzalloc (sizeof (struct target_attribute));
> >>+ ta->name = xstrdup (name);
> > This name is not freed and will leak.
>
> Added xfree in clear_target_attributes.
>
> >
> >>+ if (*tap)
> >>+ (*tap)->next = ta;
> >>+ else
> >>+ target_attributes_list = ta;
> >>+ *tap = ta;
> >>+
> >>+ user_data = &ta;
> >
> > So you are assigning ta to (*tap) and (*tap)->next. Then user_data
> is also being assigned. It did not look right to me. I wanted to
> bring it in your attention in case it is a typo.
>
> user_data will always point to the last one of target_attributes_list.
> Could you tell me which part is wrong?
This code may be right. It just looked a bit confusing. Also tap and
user_data point to samething. One of the following 2 assignment seems
redundant.
*tap = ta;
user_data = &ta;
>
> >
> >>+ unsigned int agent_access;
> >>+ unsigned int gdb_access;
> > I can understand the access mode for GDB. But what agent_access
> means and how it will effect a user?
>
> There is the introduce of agent
> http://sourceware.org/gdb/current/onlinedocs/gdb/Agent-Expressions.html
>
> Post a new version according to your review.
>
> Thanks,
> Hui
>
> 2013-02-18 Hui Zhu <hui_zhu@mentor.com>
>
> * Makefile.in (SFILES): Add target-attributes.c.
> (HFILES_NO_SRCDIR): Add target-attributes.h.
> (COMMON_OBS): Add target-attributes.o.
> * breakpoint.h (breakpoint): Add target_only_cond_check.
> * remote.c (target-attributes.h): New include.
> (PACKET_qXfer_target_attributes_read): New enum.
> (remote_start_remote): Add handler for target attributes.
> (remote_protocol_features): Add "qXfer:target-attributes:read".
> (remote_xfer_partial): Add handler for TARGET_OBJECT_ATTRIBUTES.
> (_initialize_remote): Add command
> "set remote target-attributes-packet".
> (target-attributes.c, target-attributes.h): New files.
> * tracepoint.c (target-attributes.h): New include.
> (find_trace_state_variable_number,
> trace_variable_number_check_1,
> trace_variable_number_check): New functions.
> (trace_variable_command): Call trace_variable_number_check_1.
> (merge_uploaded_trace_state_variables): Call
> trace_variable_number_check.
> tracepoint.h (trace_variable_number_check): New extern.
>
> >
> >> -----Original Message-----
> >> From: gdb-patches-owner@sourceware.org [mailto:gdb-patches-
> >> owner@sourceware.org] On Behalf Of Hui Zhu
> >> Sent: Wednesday, November 21, 2012 8:55 AM
> >> To: Qi, Yao
> >> Cc: Zhu, Hui; gdb-patches ml
> >> Subject: Re: [PATCH] target attributes [1/5] core and load from
> target
> >> function
> >>
> >> On Sun, Sep 2, 2012 at 6:37 PM, Hui Zhu <teawater@gmail.com> wrote:
> >> > On Wed, Aug 29, 2012 at 10:43 PM, Yao Qi <yao@codesourcery.com>
> >> wrote:
> >> >> On 08/29/2012 04:11 PM, Hui Zhu wrote:
> >> >>> +static void
> >> >>> +target_attribute_address_handler (struct gdb_xml_parser
> *parser,
> >> >>> + const struct gdb_xml_element
> >> *element,
> >> >>> + void *user_data,
> >> >>> + VEC(gdb_xml_value_s)
> *attributes) {
> >> >>> + int i, len;
> >> >>> + struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s,
> >> >>> +attributes);
> >> >>> + struct target_attribute *ta = *(struct target_attribute
> >> >>> +**)user_data;
> >> >>> + CORE_ADDR start, end;
> >> >>> + struct target_attribute_address *ta_addr;
> >> >>
> >> >> I happen to see some compilation warnings on my new Fedora 16
> box,
> >> >> while these warnings don't appear on my Ubuntu box.
> >> >>
> >> >> ... -Werror -c -o target-memory.o -MT target-memory.o -MMD -MP
> -MF
> >> >> .deps/target-memory.Tpo ../../../git/gdb/target-memory.c
> >> >> ../../../git/gdb/target-attributes.c: In function
> >> 'target_attribute_address_handler':
> >> >> ../../../git/gdb/target-attributes.c:487:16: error: 'end' may be
> >> used
> >> >> uninitialized in this function [-Werror=uninitialized]
> >> >> ../../../git/gdb/target-attributes.c:486:18: error: 'start' may
> be
> >> >> used uninitialized in this function [-Werror=uninitialized]
> >> >> ../../../git/gdb/target-attributes.c: In function
> >> 'target_attribute_attr_handler':
> >> >> ../../../git/gdb/target-attributes.c:376:12: error: 'type' may
> be
> >> >> used uninitialized in this function [-Werror=uninitialized]
> >> >> ../../../git/gdb/target-attributes.c: In function
> >> 'target_attribute_type':
> >> >> ../../../git/gdb/target-attributes.c:632:3: error: 'ret' may be
> used
> >> >> uninitialized in this function [-Werror=uninitialized]
> >> >> cc1: all warnings being treated as errors
> >> >> make: *** [target-attributes.o] Error 1
> >> >>
> >> >> The gcc I am using is 4.6.3
> >> >> $ gcc --version
> >> >> gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
> >> >>
> >> >> We have to get these warnings fixed.
> >> >>
> >> >>> +
> >> >>> + len = VEC_length (gdb_xml_value_s, attributes); for (i =
> 0; i <
> >> >>> + len; i++)
> >> >>> + {
> >> >>> + if (strcmp (attrs[i].name, "start") == 0)
> >> >>> + start = * (ULONGEST *) attrs[i].value;
> >> >>> + else if (strcmp (attrs[i].name, "end") == 0)
> >> >>> + end = * (ULONGEST *) attrs[i].value;
> >> >>> + else
> >> >>> + gdb_xml_error (parser, _("Unknown attribute name
> '%s'."),
> >> >>> + attrs[i].name);
> >> >>> + }
> >> >>> +
> >> >>> + ta_addr = xmalloc (sizeof (struct
> target_attribute_address));
> >> >>> + ta_addr->start = start; ta_addr->end = end;
> >> >>> +
> >> >>> + ta_addr->prev = ta->addresses;
> >> >>> + ta->addresses = ta_addr;
> >> >>> +}
> >> >>
> >> >> --
> >> >> Yao
> >> >
> >> > Thanks. I post a new version.
> >> >
> >> > Best,
> >> > Hui
> >>
> >> Got some error when built with trunk. Post a new version for this
> >> error.
> >>
> >> Thanks,
> >> Hui
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] target attributes [1/5] core and load from target function
2013-02-18 11:45 ` Abid, Hafiz
@ 2013-02-19 16:11 ` Hui Zhu
2013-02-26 3:34 ` Hui Zhu
0 siblings, 1 reply; 9+ messages in thread
From: Hui Zhu @ 2013-02-19 16:11 UTC (permalink / raw)
To: Abid, Hafiz; +Cc: Qi, Yao, Zhu, Hui, gdb-patches ml
[-- Attachment #1: Type: text/plain, Size: 7824 bytes --]
On Mon, Feb 18, 2013 at 7:45 PM, Abid, Hafiz <hafiz_abid@mentor.com> wrote:
> On 18/02/13 10:01:10, Hui Zhu wrote:
>>
>> On Fri, Nov 30, 2012 at 2:03 PM, Abid, Hafiz <Hafiz_Abid@mentor.com>
>> wrote:
>> > Hi,
>> >
>> >>+ ta = xzalloc (sizeof (struct target_attribute));
>> >>+ ta->name = xstrdup (name);
>> > This name is not freed and will leak.
>>
>> Added xfree in clear_target_attributes.
>>
>> >
>> >>+ if (*tap)
>> >>+ (*tap)->next = ta;
>> >>+ else
>> >>+ target_attributes_list = ta;
>> >>+ *tap = ta;
>> >>+
>> >>+ user_data = &ta;
>> >
>> > So you are assigning ta to (*tap) and (*tap)->next. Then user_data is
>> > also being assigned. It did not look right to me. I wanted to bring it in
>> > your attention in case it is a typo.
>>
>> user_data will always point to the last one of target_attributes_list.
>> Could you tell me which part is wrong?
>
> This code may be right. It just looked a bit confusing. Also tap and
> user_data point to samething. One of the following 2 assignment seems
> redundant.
> *tap = ta;
> user_data = &ta;
>
>
Thanks for help me on this issue. I make clear about this part of
code and I change this part of code to:
if (*tap)
{
/* Add new TA to the tail of TARGET_ATTRIBUTES_LIST. */
(*tap)->next = ta;
}
else
{
/* The fist time call target_attribute_attr_handler.
Just get USER_DATA from gdb_xml_parse_quick. */
target_attributes_list = ta;
}
/* Let USER_DATA save the address of new TA. */
*tap = ta;
Thanks,
Hui
2013-02-19 Hui Zhu <hui_zhu@mentor.com>
* Makefile.in (SFILES): Add target-attributes.c.
(HFILES_NO_SRCDIR): Add target-attributes.h.
(COMMON_OBS): Add target-attributes.o.
* breakpoint.h (breakpoint): Add target_only_cond_check.
* remote.c (target-attributes.h): New include.
(PACKET_qXfer_target_attributes_read): New enum.
(remote_start_remote): Add handler for target attributes.
(remote_protocol_features): Add "qXfer:target-attributes:read".
(remote_xfer_partial): Add handler for TARGET_OBJECT_ATTRIBUTES.
(_initialize_remote): Add command
"set remote target-attributes-packet".
(target-attributes.c, target-attributes.h): New files.
* tracepoint.c (target-attributes.h): New include.
(find_trace_state_variable_number,
trace_variable_number_check_1,
trace_variable_number_check): New functions.
(trace_variable_command): Call trace_variable_number_check_1.
(merge_uploaded_trace_state_variables): Call
trace_variable_number_check.
tracepoint.h (trace_variable_number_check): New extern.
>>
>> >
>> >>+ unsigned int agent_access;
>> >>+ unsigned int gdb_access;
>> > I can understand the access mode for GDB. But what agent_access means
>> > and how it will effect a user?
>>
>> There is the introduce of agent
>> http://sourceware.org/gdb/current/onlinedocs/gdb/Agent-Expressions.html
>>
>> Post a new version according to your review.
>>
>> Thanks,
>> Hui
>>
>> 2013-02-18 Hui Zhu <hui_zhu@mentor.com>
>>
>> * Makefile.in (SFILES): Add target-attributes.c.
>> (HFILES_NO_SRCDIR): Add target-attributes.h.
>> (COMMON_OBS): Add target-attributes.o.
>> * breakpoint.h (breakpoint): Add target_only_cond_check.
>> * remote.c (target-attributes.h): New include.
>> (PACKET_qXfer_target_attributes_read): New enum.
>> (remote_start_remote): Add handler for target attributes.
>> (remote_protocol_features): Add "qXfer:target-attributes:read".
>> (remote_xfer_partial): Add handler for TARGET_OBJECT_ATTRIBUTES.
>> (_initialize_remote): Add command
>> "set remote target-attributes-packet".
>> (target-attributes.c, target-attributes.h): New files.
>> * tracepoint.c (target-attributes.h): New include.
>> (find_trace_state_variable_number,
>> trace_variable_number_check_1,
>> trace_variable_number_check): New functions.
>> (trace_variable_command): Call trace_variable_number_check_1.
>> (merge_uploaded_trace_state_variables): Call
>> trace_variable_number_check.
>> tracepoint.h (trace_variable_number_check): New extern.
>>
>> >
>> >> -----Original Message-----
>> >> From: gdb-patches-owner@sourceware.org [mailto:gdb-patches-
>> >> owner@sourceware.org] On Behalf Of Hui Zhu
>> >> Sent: Wednesday, November 21, 2012 8:55 AM
>> >> To: Qi, Yao
>> >> Cc: Zhu, Hui; gdb-patches ml
>> >> Subject: Re: [PATCH] target attributes [1/5] core and load from target
>> >> function
>> >>
>> >> On Sun, Sep 2, 2012 at 6:37 PM, Hui Zhu <teawater@gmail.com> wrote:
>> >> > On Wed, Aug 29, 2012 at 10:43 PM, Yao Qi <yao@codesourcery.com>
>> >> wrote:
>> >> >> On 08/29/2012 04:11 PM, Hui Zhu wrote:
>> >> >>> +static void
>> >> >>> +target_attribute_address_handler (struct gdb_xml_parser *parser,
>> >> >>> + const struct gdb_xml_element
>> >> *element,
>> >> >>> + void *user_data,
>> >> >>> + VEC(gdb_xml_value_s) *attributes) {
>> >> >>> + int i, len;
>> >> >>> + struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s,
>> >> >>> +attributes);
>> >> >>> + struct target_attribute *ta = *(struct target_attribute
>> >> >>> +**)user_data;
>> >> >>> + CORE_ADDR start, end;
>> >> >>> + struct target_attribute_address *ta_addr;
>> >> >>
>> >> >> I happen to see some compilation warnings on my new Fedora 16 box,
>> >> >> while these warnings don't appear on my Ubuntu box.
>> >> >>
>> >> >> ... -Werror -c -o target-memory.o -MT target-memory.o -MMD -MP -MF
>> >> >> .deps/target-memory.Tpo ../../../git/gdb/target-memory.c
>> >> >> ../../../git/gdb/target-attributes.c: In function
>> >> 'target_attribute_address_handler':
>> >> >> ../../../git/gdb/target-attributes.c:487:16: error: 'end' may be
>> >> used
>> >> >> uninitialized in this function [-Werror=uninitialized]
>> >> >> ../../../git/gdb/target-attributes.c:486:18: error: 'start' may be
>> >> >> used uninitialized in this function [-Werror=uninitialized]
>> >> >> ../../../git/gdb/target-attributes.c: In function
>> >> 'target_attribute_attr_handler':
>> >> >> ../../../git/gdb/target-attributes.c:376:12: error: 'type' may be
>> >> >> used uninitialized in this function [-Werror=uninitialized]
>> >> >> ../../../git/gdb/target-attributes.c: In function
>> >> 'target_attribute_type':
>> >> >> ../../../git/gdb/target-attributes.c:632:3: error: 'ret' may be used
>> >> >> uninitialized in this function [-Werror=uninitialized]
>> >> >> cc1: all warnings being treated as errors
>> >> >> make: *** [target-attributes.o] Error 1
>> >> >>
>> >> >> The gcc I am using is 4.6.3
>> >> >> $ gcc --version
>> >> >> gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
>> >> >>
>> >> >> We have to get these warnings fixed.
>> >> >>
>> >> >>> +
>> >> >>> + len = VEC_length (gdb_xml_value_s, attributes); for (i = 0; i <
>> >> >>> + len; i++)
>> >> >>> + {
>> >> >>> + if (strcmp (attrs[i].name, "start") == 0)
>> >> >>> + start = * (ULONGEST *) attrs[i].value;
>> >> >>> + else if (strcmp (attrs[i].name, "end") == 0)
>> >> >>> + end = * (ULONGEST *) attrs[i].value;
>> >> >>> + else
>> >> >>> + gdb_xml_error (parser, _("Unknown attribute name '%s'."),
>> >> >>> + attrs[i].name);
>> >> >>> + }
>> >> >>> +
>> >> >>> + ta_addr = xmalloc (sizeof (struct target_attribute_address));
>> >> >>> + ta_addr->start = start; ta_addr->end = end;
>> >> >>> +
>> >> >>> + ta_addr->prev = ta->addresses;
>> >> >>> + ta->addresses = ta_addr;
>> >> >>> +}
>> >> >>
>> >> >> --
>> >> >> Yao
>> >> >
>> >> > Thanks. I post a new version.
>> >> >
>> >> > Best,
>> >> > Hui
>> >>
>> >> Got some error when built with trunk. Post a new version for this
>> >> error.
>> >>
>> >> Thanks,
>> >> Hui
>>
>
[-- Attachment #2: target_attribute_load.txt --]
[-- Type: text/plain, Size: 32016 bytes --]
--- a/Makefile.in
+++ b/Makefile.in
@@ -742,7 +742,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
solib.c solib-target.c source.c \
stabsread.c stack.c probe.c stap-probe.c std-regs.c \
symfile.c symfile-mem.c symmisc.c symtab.c \
- target.c target-descriptions.c target-memory.c \
+ target.c target-attributes.c target-descriptions.c target-memory.c \
thread.c top.c tracepoint.c \
trad-frame.c \
tramp-frame.c \
@@ -835,7 +835,7 @@ gnulib/import/stddef.in.h gnulib/import/
common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
common/format.h common/host-defs.h utils.h common/queue.h \
common/linux-osdata.h gdb-dlfcn.h auto-load.h probe.h stap-probe.h \
-gdb_bfd.h sparc-ravenscar-thread.h ppc-ravenscar-thread.h
+gdb_bfd.h sparc-ravenscar-thread.h ppc-ravenscar-thread.h target-attributes.h
# Header files that already have srcdir in them, or which are in objdir.
@@ -924,7 +924,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
solib.o solib-target.o \
prologue-value.o memory-map.o memrange.o \
xml-support.o xml-syscall.o xml-utils.o \
- target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
+ target-attributes.o target-descriptions.o target-memory.o \
+ xml-tdesc.o xml-builtin.o \
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
gdb_vecs.o jit.o progspace.o skip.o probe.o \
common-utils.o buffer.o ptid.o gdb-dlfcn.o common-agent.o \
--- a/breakpoint.h
+++ b/breakpoint.h
@@ -726,6 +726,11 @@ struct breakpoint
there is no condition. */
char *cond_string;
+ /* If True, the GDB side cannot do the condition check for
+ the condition of this breakpoint and this condition only can
+ be checked in agent side. */
+ int target_only_cond_check;
+
/* String form of extra parameters, or NULL if there are none. */
char *extra_string;
--- a/remote.c
+++ b/remote.c
@@ -44,6 +44,7 @@
#include "cli/cli-setshow.h"
#include "target-descriptions.h"
#include "gdb_bfd.h"
+#include "target-attributes.h"
#include <ctype.h>
#include <sys/time.h>
@@ -1284,6 +1285,7 @@ enum {
PACKET_qXfer_fdpic,
PACKET_QDisableRandomization,
PACKET_QAgent,
+ PACKET_qXfer_target_attributes_read,
PACKET_MAX
};
@@ -3559,6 +3561,22 @@ remote_start_remote (int from_tty, struc
remote_check_symbols (symfile_objfile);
}
+ if (remote_protocol_packets[PACKET_qXfer_target_attributes_read].support
+ != PACKET_DISABLE)
+ {
+ char *text;
+
+ text = target_read_stralloc (¤t_target, TARGET_OBJECT_ATTRIBUTES,
+ NULL);
+ if (text != NULL)
+ {
+ struct cleanup *back_to = make_cleanup (xfree, text);
+
+ add_xml_target_attributes (text);
+ do_cleanups (back_to);
+ }
+ }
+
/* Possibly the target has been engaged in a trace run started
previously; find out where things are at. */
if (remote_get_trace_status (current_trace_status ()) != -1)
@@ -3995,6 +4013,8 @@ static struct protocol_feature remote_pr
{ "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent},
{ "tracenz", PACKET_DISABLE,
remote_string_tracing_feature, -1 },
+ { "qXfer:target-attributes:read", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_target_attributes_read },
};
static char *remote_support_xml;
@@ -8796,6 +8816,12 @@ remote_xfer_partial (struct target_ops *
return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len,
&remote_protocol_packets[PACKET_qXfer_uib]);
+ case TARGET_OBJECT_ATTRIBUTES:
+ gdb_assert (annex == NULL);
+ return remote_read_qxfer
+ (ops, "target-attributes", annex, readbuf, offset, len,
+ &remote_protocol_packets[PACKET_qXfer_target_attributes_read]);
+
default:
return -1;
}
@@ -11755,6 +11781,10 @@ Show the maximum size of the address (in
add_packet_config_cmd (&remote_protocol_packets[PACKET_QAgent],
"QAgent", "agent", 0);
+ add_packet_config_cmd
+ (&remote_protocol_packets[PACKET_qXfer_target_attributes_read],
+ "qXfer:target-attributes:read", "target-attributes", 0);
+
/* Keep the old ``set remote Z-packet ...'' working. Each individual
Z sub-packet has its own set and show commands, but users may
have sets to this variable in their .gdbinit files (or in their
--- /dev/null
+++ b/target-attributes.c
@@ -0,0 +1,676 @@
+/* Target attributes for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "ui-out.h"
+#include "tracepoint.h"
+#include "gdbcmd.h"
+#include "target-attributes.h"
+
+static struct target_attribute *target_attributes_list;
+
+struct target_attribute *
+find_target_attribute_name (const char *name)
+{
+ struct target_attribute *ta;
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ if (strcmp (ta->name, name) == 0)
+ return ta;
+ }
+
+ return NULL;
+}
+
+struct target_attribute *
+find_target_attribute_id (int id)
+{
+ struct target_attribute *ta;
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ if (id == ta->id)
+ return ta;
+ }
+
+ return NULL;
+}
+
+static struct bp_location *check_agent_target_attribute_bl = NULL;
+char *check_agent_target_attribute_error = NULL;
+
+static void
+clear_check_agent_target_attribute (void *unused)
+{
+ check_agent_target_attribute_bl = NULL;
+}
+
+struct cleanup *
+set_check_agent_target_attribute (struct bp_location *bl)
+{
+ check_agent_target_attribute_bl = bl;
+ check_agent_target_attribute_error = NULL;
+
+ return make_cleanup (clear_check_agent_target_attribute, NULL);
+}
+
+void
+check_agent_target_attribute (struct target_attribute *ta, int write)
+{
+ static char error_str[256];
+ check_agent_target_attribute_error = error_str;
+
+ if (write)
+ {
+ if ((ta->agent_access & TARGET_ATTRIBUTE_ACCESS_WRITE) == 0)
+ {
+ snprintf (error_str, 256, _("$%s cannot be written in agent code."),
+ ta->name);
+ error (_("$%s cannot be written in agent code."), ta->name);
+ }
+ }
+ else
+ {
+ if ((ta->agent_access & TARGET_ATTRIBUTE_ACCESS_READ) == 0)
+ {
+ snprintf (error_str, 256, _("$%s cannot be read in agent code."),
+ ta->name);
+ error (_("$%s cannot be read in agent code."), ta->name);
+ }
+ }
+
+ if (check_agent_target_attribute_bl)
+ {
+ struct target_attribute_address *ta_addr;
+
+ if (ta->target_only_cond_check)
+ check_agent_target_attribute_bl->owner->target_only_cond_check = 1;
+
+ switch (check_agent_target_attribute_bl->loc_type)
+ {
+ case bp_loc_software_breakpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in software breakpoint."),
+ ta->name);
+ error (_("$%s cannot be used in software breakpoint."), ta->name);
+ }
+ break;
+ case bp_loc_hardware_breakpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in hardware breakpoint."),
+ ta->name);
+ error (_("$%s cannot be used in hardware breakpoint."),
+ ta->name);
+ }
+ break;
+ case bp_loc_hardware_watchpoint:
+ if ((ta->support
+ & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT) == 0)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in hardware watchpoint."),
+ ta->name);
+ error (_("$%s cannot be used in hardware watchpoint."),
+ ta->name);
+ }
+ break;
+ default:
+ if (check_agent_target_attribute_bl->owner->type == bp_tracepoint
+ || check_agent_target_attribute_bl->owner->type
+ == bp_fast_tracepoint
+ || check_agent_target_attribute_bl->owner->type
+ == bp_static_tracepoint)
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in tracepoint."), ta->name);
+ if ((ta->support & TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT) == 0)
+ error (_("$%s cannot be used in tracepoint."), ta->name);
+ }
+ else
+ {
+ snprintf (error_str, 256,
+ _("$%s cannot be used in breakpoint %d."),
+ ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ error (_("$%s cannot be used in breakpoint %d."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ }
+ break;
+ }
+
+ if (ta->addresses)
+ {
+ for (ta_addr = ta->addresses; ta_addr; ta_addr = ta_addr->prev)
+ {
+ if (check_agent_target_attribute_bl->address >= ta_addr->start
+ && check_agent_target_attribute_bl->address <= ta_addr->end)
+ break;
+ }
+ if (!ta_addr)
+ {
+ snprintf (error_str, 256,
+ _("\
+$%s cannot be used in breakpoint %d because the address limit."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ error (_("\
+$%s cannot be used in breakpoint %d because the address limit."), ta->name,
+ check_agent_target_attribute_bl->owner->number);
+ }
+ }
+ }
+
+ check_agent_target_attribute_error = NULL;
+}
+
+void
+clear_target_attributes (void *unused)
+{
+ struct target_attribute *ta, *tmp;
+
+ for (ta = target_attributes_list; ta;)
+ {
+ struct target_attribute_address *ta_addr, *tmp_addr;
+
+ tmp = ta;
+ ta = ta->next;
+
+ for (ta_addr = tmp->addresses; ta_addr;)
+ {
+ tmp_addr = ta_addr;
+ ta_addr = ta_addr->prev;
+ xfree (tmp_addr);
+ }
+
+ xfree (tmp->name);
+ xfree (tmp);
+ }
+
+ target_attributes_list = NULL;
+}
+
+static void
+info_target_attributes (char *args, int from_tty)
+{
+ struct target_attribute *ta;
+ struct cleanup *back_to;
+ struct ui_out *uiout = current_uiout;
+ int count = 0;
+
+ if (target_attributes_list == NULL)
+ {
+ ui_out_message (uiout, 0, _("No target attributes.\n"));
+ return;
+ }
+
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ count++;
+
+ back_to = make_cleanup_ui_out_table_begin_end (uiout, 6,
+ count, "target-attributes");
+ ui_out_table_header (uiout, 15, ui_left, "name", "Name");
+ ui_out_table_header (uiout, 15, ui_left, "type", "Type");
+ ui_out_table_header (uiout, 15, ui_left, "target-only-cond-check",
+ "Target-only-cond-check");
+ ui_out_table_header (uiout, 15, ui_left, "agent access", "Agent access");
+ ui_out_table_header (uiout, 15, ui_left, "gdb access", "GDB access");
+ ui_out_table_header (uiout, 15, ui_left, "breakpoint type",
+ "Breakpoint type");
+
+ ui_out_table_body (uiout);
+ for (ta = target_attributes_list; ta; ta = ta->next)
+ {
+ struct target_attribute_address *ta_addr;
+ char buf[512];
+ struct cleanup *back_to2
+ = make_cleanup_ui_out_tuple_begin_end (uiout, "attributes");
+
+ snprintf (buf, 512, "$%s", ta->name);
+ ui_out_field_string (uiout, "name", buf);
+
+ switch (ta->type)
+ {
+ case TARGET_ATTRIBUTE_TYPE_INT8:
+ ui_out_field_string (uiout, "type", "int8");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT8:
+ ui_out_field_string (uiout, "type", "uint8");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT16:
+ ui_out_field_string (uiout, "type", "int16");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT16:
+ ui_out_field_string (uiout, "type", "uint16");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT32:
+ ui_out_field_string (uiout, "type", "int32");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT32:
+ ui_out_field_string (uiout, "type", "uint32");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT64:
+ ui_out_field_string (uiout, "type", "int64");
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT64:
+ ui_out_field_string (uiout, "type", "uint64");
+ break;
+ }
+
+ ui_out_field_string (uiout, "target-only-cond-check",
+ ta->target_only_cond_check ? "yes" : "no");
+
+ snprintf (buf, 512, "%s%s",
+ (ta->agent_access
+ & TARGET_ATTRIBUTE_ACCESS_READ) ? "read " : "",
+ (ta->agent_access
+ & TARGET_ATTRIBUTE_ACCESS_WRITE) ? "write" : "");
+ ui_out_field_string (uiout, "agent access", buf);
+
+ snprintf (buf, 512, "%s%s",
+ (ta->gdb_access & TARGET_ATTRIBUTE_ACCESS_READ) ? "read " : "",
+ (ta->gdb_access
+ & TARGET_ATTRIBUTE_ACCESS_WRITE) ? "write" : "");
+ ui_out_field_string (uiout, "gdb access", buf);
+
+ snprintf (buf, 512, "%s%s%s%s",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT)
+ ? "software-breakpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT)
+ ? "hardware-breakpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT)
+ ? "hardware-watchpoint " : "",
+ (ta->support & TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT)
+ ? "tracepoint " : "");
+ ui_out_field_string (uiout, "breakpoint type", buf);
+
+ ui_out_text (uiout, "\n");
+
+ for (ta_addr = ta->addresses; ta_addr; ta_addr = ta_addr->prev)
+ {
+ ui_out_spaces (uiout, 2);
+ ui_out_message (uiout, 0, "start:%s end:%s\n",
+ paddress (target_gdbarch (), ta_addr->start),
+ paddress (target_gdbarch (), ta_addr->end));
+ }
+ do_cleanups (back_to2);
+ }
+
+ do_cleanups (back_to);
+}
+
+#if !defined(HAVE_LIBEXPAT)
+
+void
+add_xml_target_attributes (const char *text)
+{
+ if (strlen (text) > 0)
+ warning (_("Can not parse XML target attributes; XML support "
+ "was disabled at compile time"));
+}
+
+#else
+
+#include "xml-support.h"
+
+static void
+target_attribute_attr_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ char *name = NULL;
+ int i, len, id = -1, type = 0, target_only_cond_check = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+ struct target_attribute *ta, **tap = user_data;
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "name") == 0)
+ name = attrs[i].value;
+ else if (strcmp (attrs[i].name, "id") == 0)
+ id = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "type") == 0)
+ type = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "target-only-cond-check") == 0)
+ target_only_cond_check = * (ULONGEST *) attrs[i].value;
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ if (!name || id < 0)
+ gdb_xml_error (parser, _("\"name\" or \"id\" is missed."));
+
+ if (find_target_attribute_name (name))
+ gdb_xml_error (parser,_("\
+name \"%s\" is same with a target attribute."), name);
+ if (find_target_attribute_id (id))
+ gdb_xml_error (parser,_("id \"%d\" is same with a target attribute."), id);
+
+ ta = xzalloc (sizeof (struct target_attribute));
+ ta->name = xstrdup (name);
+ ta->id = id;
+ ta->type = type;
+ ta->target_only_cond_check = target_only_cond_check;
+
+ if (*tap)
+ {
+ /* Add new TA to the tail of TARGET_ATTRIBUTES_LIST. */
+ (*tap)->next = ta;
+ }
+ else
+ {
+ /* The fist time call target_attribute_attr_handler.
+ Just get USER_DATA from gdb_xml_parse_quick. */
+ target_attributes_list = ta;
+ }
+ /* Let USER_DATA save the address of new TA. */
+ *tap = ta;
+}
+
+static void
+target_attribute_access_children_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ int i, len, ta_access = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "read") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta_access |= TARGET_ATTRIBUTE_ACCESS_READ;
+ }
+ else if (strcmp (attrs[i].name, "write") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta_access |= TARGET_ATTRIBUTE_ACCESS_WRITE;
+ }
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ if (strcmp (element->name, "agent") == 0)
+ ta->agent_access = ta_access;
+ else
+ ta->gdb_access = ta_access;
+}
+
+static void
+target_attribute_support_attr_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ int i, len = 0;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "software-breakpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT;
+ }
+ else if (strcmp (attrs[i].name, "hardware-breakpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT;
+ }
+ else if (strcmp (attrs[i].name, "hardware-watchpoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT;
+ }
+ else if (strcmp (attrs[i].name, "tracepoint") == 0)
+ {
+ if (* (ULONGEST *) attrs[i].value)
+ ta->support |= TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT;
+ }
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+}
+
+static void
+target_attribute_address_handler (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data,
+ VEC(gdb_xml_value_s) *attributes)
+{
+ int i, len;
+ struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
+ struct target_attribute *ta = *(struct target_attribute **)user_data;
+ CORE_ADDR start = 0, end = 0;
+ struct target_attribute_address *ta_addr;
+
+ len = VEC_length (gdb_xml_value_s, attributes);
+ for (i = 0; i < len; i++)
+ {
+ if (strcmp (attrs[i].name, "start") == 0)
+ start = * (ULONGEST *) attrs[i].value;
+ else if (strcmp (attrs[i].name, "end") == 0)
+ end = * (ULONGEST *) attrs[i].value;
+ else
+ gdb_xml_error (parser, _("Unknown attribute name '%s'."),
+ attrs[i].name);
+ }
+
+ ta_addr = xmalloc (sizeof (struct target_attribute_address));
+ ta_addr->start = start;
+ ta_addr->end = end;
+
+ ta_addr->prev = ta->addresses;
+ ta->addresses = ta_addr;
+}
+
+const struct gdb_xml_enum target_attribute_type_enums[] = {
+ { "int8", TARGET_ATTRIBUTE_TYPE_INT8 },
+ { "uint8", TARGET_ATTRIBUTE_TYPE_UINT8 },
+ { "int16", TARGET_ATTRIBUTE_TYPE_INT16 },
+ { "uint16", TARGET_ATTRIBUTE_TYPE_UINT16 },
+ { "int32", TARGET_ATTRIBUTE_TYPE_INT32 },
+ { "uint32", TARGET_ATTRIBUTE_TYPE_UINT32 },
+ { "int64", TARGET_ATTRIBUTE_TYPE_INT64 },
+ { "uint64", TARGET_ATTRIBUTE_TYPE_UINT64 },
+ { NULL, 0 }
+};
+
+static const struct gdb_xml_attribute target_attribute_attr[] = {
+ { "name", GDB_XML_AF_NONE, NULL, NULL },
+ { "id", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "type", GDB_XML_AF_NONE, gdb_xml_parse_attr_enum,
+ target_attribute_type_enums },
+ { "target-only-cond-check", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute
+ target_attribute_access_children_attr[] = {
+ { "read", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "write", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_access_children[] = {
+ { "agent", target_attribute_access_children_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_access_children_handler, NULL },
+ { "gdb", target_attribute_access_children_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_access_children_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute target_attribute_support_attr[] = {
+ { "software-breakpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "hardware-breakpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "hardware-watchpoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { "tracepoint", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_enum,
+ gdb_xml_enums_boolean },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute target_attribute_address_attr[] = {
+ { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+ { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_addresses_children[] = {
+ { "address", target_attribute_address_attr, NULL,
+ GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+ target_attribute_address_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attribute_elements[] = {
+ { "access", NULL, target_attribute_access_children,
+ GDB_XML_EF_NONE, NULL, NULL },
+ { "support", target_attribute_support_attr, NULL,
+ GDB_XML_EF_OPTIONAL, target_attribute_support_attr_handler, NULL },
+ { "addresses", NULL, target_attribute_addresses_children,
+ GDB_XML_EF_OPTIONAL, NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attributes_children[] = {
+ { "target-attribute", target_attribute_attr, target_attribute_elements,
+ GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
+ target_attribute_attr_handler, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element target_attributes_elements[] = {
+ { "target-attributes", NULL, target_attributes_children,
+ GDB_XML_EF_NONE, NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+void
+add_xml_target_attributes (const char *text)
+{
+ struct target_attribute *ta = NULL;
+ struct cleanup *back_to = make_cleanup (clear_target_attributes, NULL);
+
+ clear_target_attributes(NULL);
+ if (gdb_xml_parse_quick (_("target attributes"), NULL,
+ target_attributes_elements, text, &ta) == 0)
+ {
+ discard_cleanups (back_to);
+ trace_variable_number_check ();
+ }
+ else
+ do_cleanups (back_to);
+}
+
+#endif
+
+struct type *
+target_attribute_type (struct gdbarch *gdbarch, struct target_attribute *ta)
+{
+ struct type *ret = builtin_type (gdbarch)->builtin_uint64;
+
+ switch (ta->type)
+ {
+ case TARGET_ATTRIBUTE_TYPE_INT8:
+ ret = builtin_type (gdbarch)->builtin_int8;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT8:
+ ret = builtin_type (gdbarch)->builtin_uint8;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT16:
+ ret = builtin_type (gdbarch)->builtin_int16;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT16:
+ ret = builtin_type (gdbarch)->builtin_uint16;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT32:
+ ret = builtin_type (gdbarch)->builtin_int32;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT32:
+ ret = builtin_type (gdbarch)->builtin_uint32;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_INT64:
+ ret = builtin_type (gdbarch)->builtin_int64;
+ break;
+ case TARGET_ATTRIBUTE_TYPE_UINT64:
+ ret = builtin_type (gdbarch)->builtin_uint64;
+ break;
+ }
+
+ return ret;
+}
+
+static void
+load_target_attributes_command (char *exp, int from_tty)
+{
+ char *text = xml_fetch_content_from_file (exp, NULL);
+
+ if (text == NULL)
+ error (_("Could not open \"%s\""), exp);
+ add_xml_target_attributes (text);
+}
+
+static void
+clear_target_attributes_command (char *exp, int from_tty)
+{
+ clear_target_attributes (NULL);
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_targets_attributes;
+
+void
+_initialize_targets_attributes (void)
+{
+ add_cmd ("load-target-attributes", class_maintenance,
+ load_target_attributes_command,
+ _("Load target attributes from a XML file."),
+ &maintenancelist);
+
+ add_cmd ("clear-target-attributes", class_maintenance,
+ clear_target_attributes_command,
+ _("Remove all target attributes."),
+ &maintenancelist);
+
+ add_info ("target-attributes", info_target_attributes, _("\
+Status of target attributes."));
+}
--- /dev/null
+++ b/target-attributes.h
@@ -0,0 +1,104 @@
+/* Target attributes for GDB, the GNU debugger.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef TARGET_ATTRIBUTES_H
+#define TARGET_ATTRIBUTES_H 1
+
+enum
+{
+ TARGET_ATTRIBUTE_TYPE_INT8,
+ TARGET_ATTRIBUTE_TYPE_UINT8,
+ TARGET_ATTRIBUTE_TYPE_INT16,
+ TARGET_ATTRIBUTE_TYPE_UINT16,
+ TARGET_ATTRIBUTE_TYPE_INT32,
+ TARGET_ATTRIBUTE_TYPE_UINT32,
+ TARGET_ATTRIBUTE_TYPE_INT64,
+ TARGET_ATTRIBUTE_TYPE_UINT64,
+};
+
+#define TARGET_ATTRIBUTE_ACCESS_READ 0x1
+#define TARGET_ATTRIBUTE_ACCESS_WRITE 0x2
+
+#define TARGET_ATTRIBUTE_SUPPORT_SOFTWARE_BREAKPOINT 0x1
+#define TARGET_ATTRIBUTE_SUPPORT_HARDWARE_BREAKPOINT 0x2
+#define TARGET_ATTRIBUTE_SUPPORT_HARDWARE_WATCHPOINT 0x4
+#define TARGET_ATTRIBUTE_SUPPORT_TRACEPOINT 0x8
+
+struct target_attribute_address
+ {
+ struct target_attribute_address *prev;
+ CORE_ADDR start;
+ CORE_ADDR end;
+ };
+
+/* This is the core struct of a target attribute.
+ When GDB get a target attribute from XML,
+ it will alloc a struct for it. */
+
+struct target_attribute
+ {
+ struct target_attribute *next;
+ char *name;
+ int id;
+ int type;
+ int target_only_cond_check;
+ unsigned int agent_access;
+ unsigned int gdb_access;
+ unsigned int support;
+ struct target_attribute_address *addresses;
+ };
+
+/* This is the error report string for function
+ check_agent_target_attribute.
+ Because some function call check_agent_target_attribute
+ with TRY_CATCH. Use this string report error. */
+
+extern char *check_agent_target_attribute_error;
+
+extern struct target_attribute *find_target_attribute_name (const char *name);
+extern struct target_attribute *find_target_attribute_id (int id);
+
+/* Set BL for function check_agent_target_attribute
+ before translate a string to agent expression bytecode. */
+
+extern struct cleanup *set_check_agent_target_attribute
+ (struct bp_location *bl);
+
+/* The function that translate a string to agent expression bytecode call
+ check_agent_target_attribute to check if TA is OK to use with
+ BL that set by set_check_agent_target_attribute. */
+
+extern void check_agent_target_attribute (struct target_attribute *ta,
+ int write);
+
+/* Remove all the target attributes inside the GDB. */
+
+extern void clear_target_attributes (void *unused);
+
+/* Parse target attributes out from XML formart string TEXT
+ and add them to GDB. */
+
+extern void add_xml_target_attributes (const char *text);
+
+/* Return the type of TA. */
+
+extern struct type *target_attribute_type (struct gdbarch *gdbarch,
+ struct target_attribute *ta);
+
+#endif /* TARGET_ATTRIBUTES_H */
--- a/target.h
+++ b/target.h
@@ -286,7 +286,9 @@ enum target_object
/* Darwin dynamic linker info data. */
TARGET_OBJECT_DARWIN_DYLD_INFO,
/* OpenVMS Unwind Information Block. */
- TARGET_OBJECT_OPENVMS_UIB
+ TARGET_OBJECT_OPENVMS_UIB,
+ /* Target attributes. */
+ TARGET_OBJECT_ATTRIBUTES,
/* Possible future objects: TARGET_OBJECT_FILE, ... */
};
--- a/tracepoint.c
+++ b/tracepoint.c
@@ -53,6 +53,7 @@
#include "exceptions.h"
#include "cli/cli-utils.h"
#include "probe.h"
+#include "target-attributes.h"
/* readline include files */
#include "readline/readline.h"
@@ -342,6 +343,21 @@ find_trace_state_variable (const char *n
return NULL;
}
+/* Look for a trace state variable of the given number. */
+
+static struct trace_state_variable *
+find_trace_state_variable_number (int number)
+{
+ struct trace_state_variable *tsv;
+ int ix;
+
+ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ if (number == tsv->number)
+ return tsv;
+
+ return NULL;
+}
+
static void
delete_trace_state_variable (const char *name)
{
@@ -386,6 +402,41 @@ validate_trace_state_variable_name (cons
error (_("$%s is not a valid trace state variable name"), name);
}
+static int
+trace_variable_number_check_1 (struct trace_state_variable *tsv)
+{
+ if (find_target_attribute_id (tsv->number))
+ {
+ int new_number = tsv->number + 1;
+ tsv->number = 0;
+ while (find_target_attribute_id (new_number)
+ || find_trace_state_variable_number (new_number))
+ new_number++;
+ tsv->number = new_number;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+trace_variable_number_check (void)
+{
+ struct trace_state_variable *tsv;
+ int ix;
+
+ for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
+ {
+ if (trace_variable_number_check_1 (tsv))
+ {
+ warning (_("\
+number of trace variable $%s is same with a tsv compatible \n\
+target attribute. So it is changed to %d."), tsv->name, tsv->number);
+ }
+ }
+}
+
/* The 'tvariable' command collects a name and optional expression to
evaluate into an initial value. */
@@ -443,6 +494,8 @@ trace_variable_command (char *args, int
observer_notify_tsv_created (tsv);
+ trace_variable_number_check_1 (tsv);
+
printf_filtered (_("Trace state variable $%s "
"created, with initial value %s.\n"),
tsv->name, plongest (tsv->initial_value));
@@ -3674,6 +3727,8 @@ merge_uploaded_trace_state_variables (st
if (tsv->number == 0)
tsv->number = highest++;
+ trace_variable_number_check();
+
free_uploaded_tsvs (uploaded_tsvs);
}
--- a/tracepoint.h
+++ b/tracepoint.h
@@ -248,6 +248,8 @@ extern void validate_trace_state_variabl
extern struct trace_state_variable *find_trace_state_variable (const char *name);
extern struct trace_state_variable *create_trace_state_variable (const char *name);
+extern void trace_variable_number_check(void);
+
extern int encode_source_string (int num, ULONGEST addr,
char *srctype, char *src,
char *buf, int buf_size);
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] target attributes [1/5] core and load from target function
2013-02-19 16:11 ` Hui Zhu
@ 2013-02-26 3:34 ` Hui Zhu
0 siblings, 0 replies; 9+ messages in thread
From: Hui Zhu @ 2013-02-26 3:34 UTC (permalink / raw)
To: Abid, Hafiz; +Cc: Qi, Yao, Zhu, Hui, gdb-patches ml
Ping in http://www.sourceware.org/ml/gdb-patches/2013-02/msg00500.html
Thanks,
Hui
On Wed, Feb 20, 2013 at 12:10 AM, Hui Zhu <teawater@gmail.com> wrote:
> On Mon, Feb 18, 2013 at 7:45 PM, Abid, Hafiz <hafiz_abid@mentor.com> wrote:
>> On 18/02/13 10:01:10, Hui Zhu wrote:
>>>
>>> On Fri, Nov 30, 2012 at 2:03 PM, Abid, Hafiz <Hafiz_Abid@mentor.com>
>>> wrote:
>>> > Hi,
>>> >
>>> >>+ ta = xzalloc (sizeof (struct target_attribute));
>>> >>+ ta->name = xstrdup (name);
>>> > This name is not freed and will leak.
>>>
>>> Added xfree in clear_target_attributes.
>>>
>>> >
>>> >>+ if (*tap)
>>> >>+ (*tap)->next = ta;
>>> >>+ else
>>> >>+ target_attributes_list = ta;
>>> >>+ *tap = ta;
>>> >>+
>>> >>+ user_data = &ta;
>>> >
>>> > So you are assigning ta to (*tap) and (*tap)->next. Then user_data is
>>> > also being assigned. It did not look right to me. I wanted to bring it in
>>> > your attention in case it is a typo.
>>>
>>> user_data will always point to the last one of target_attributes_list.
>>> Could you tell me which part is wrong?
>>
>> This code may be right. It just looked a bit confusing. Also tap and
>> user_data point to samething. One of the following 2 assignment seems
>> redundant.
>> *tap = ta;
>> user_data = &ta;
>>
>>
>
> Thanks for help me on this issue. I make clear about this part of
> code and I change this part of code to:
> if (*tap)
> {
> /* Add new TA to the tail of TARGET_ATTRIBUTES_LIST. */
> (*tap)->next = ta;
> }
> else
> {
> /* The fist time call target_attribute_attr_handler.
> Just get USER_DATA from gdb_xml_parse_quick. */
> target_attributes_list = ta;
> }
> /* Let USER_DATA save the address of new TA. */
> *tap = ta;
>
> Thanks,
> Hui
>
> 2013-02-19 Hui Zhu <hui_zhu@mentor.com>
>
> * Makefile.in (SFILES): Add target-attributes.c.
> (HFILES_NO_SRCDIR): Add target-attributes.h.
> (COMMON_OBS): Add target-attributes.o.
> * breakpoint.h (breakpoint): Add target_only_cond_check.
> * remote.c (target-attributes.h): New include.
> (PACKET_qXfer_target_attributes_read): New enum.
> (remote_start_remote): Add handler for target attributes.
> (remote_protocol_features): Add "qXfer:target-attributes:read".
> (remote_xfer_partial): Add handler for TARGET_OBJECT_ATTRIBUTES.
> (_initialize_remote): Add command
> "set remote target-attributes-packet".
> (target-attributes.c, target-attributes.h): New files.
> * tracepoint.c (target-attributes.h): New include.
> (find_trace_state_variable_number,
> trace_variable_number_check_1,
> trace_variable_number_check): New functions.
> (trace_variable_command): Call trace_variable_number_check_1.
> (merge_uploaded_trace_state_variables): Call
> trace_variable_number_check.
> tracepoint.h (trace_variable_number_check): New extern.
>
>>>
>>> >
>>> >>+ unsigned int agent_access;
>>> >>+ unsigned int gdb_access;
>>> > I can understand the access mode for GDB. But what agent_access means
>>> > and how it will effect a user?
>>>
>>> There is the introduce of agent
>>> http://sourceware.org/gdb/current/onlinedocs/gdb/Agent-Expressions.html
>>>
>>> Post a new version according to your review.
>>>
>>> Thanks,
>>> Hui
>>>
>>> 2013-02-18 Hui Zhu <hui_zhu@mentor.com>
>>>
>>> * Makefile.in (SFILES): Add target-attributes.c.
>>> (HFILES_NO_SRCDIR): Add target-attributes.h.
>>> (COMMON_OBS): Add target-attributes.o.
>>> * breakpoint.h (breakpoint): Add target_only_cond_check.
>>> * remote.c (target-attributes.h): New include.
>>> (PACKET_qXfer_target_attributes_read): New enum.
>>> (remote_start_remote): Add handler for target attributes.
>>> (remote_protocol_features): Add "qXfer:target-attributes:read".
>>> (remote_xfer_partial): Add handler for TARGET_OBJECT_ATTRIBUTES.
>>> (_initialize_remote): Add command
>>> "set remote target-attributes-packet".
>>> (target-attributes.c, target-attributes.h): New files.
>>> * tracepoint.c (target-attributes.h): New include.
>>> (find_trace_state_variable_number,
>>> trace_variable_number_check_1,
>>> trace_variable_number_check): New functions.
>>> (trace_variable_command): Call trace_variable_number_check_1.
>>> (merge_uploaded_trace_state_variables): Call
>>> trace_variable_number_check.
>>> tracepoint.h (trace_variable_number_check): New extern.
>>>
>>> >
>>> >> -----Original Message-----
>>> >> From: gdb-patches-owner@sourceware.org [mailto:gdb-patches-
>>> >> owner@sourceware.org] On Behalf Of Hui Zhu
>>> >> Sent: Wednesday, November 21, 2012 8:55 AM
>>> >> To: Qi, Yao
>>> >> Cc: Zhu, Hui; gdb-patches ml
>>> >> Subject: Re: [PATCH] target attributes [1/5] core and load from target
>>> >> function
>>> >>
>>> >> On Sun, Sep 2, 2012 at 6:37 PM, Hui Zhu <teawater@gmail.com> wrote:
>>> >> > On Wed, Aug 29, 2012 at 10:43 PM, Yao Qi <yao@codesourcery.com>
>>> >> wrote:
>>> >> >> On 08/29/2012 04:11 PM, Hui Zhu wrote:
>>> >> >>> +static void
>>> >> >>> +target_attribute_address_handler (struct gdb_xml_parser *parser,
>>> >> >>> + const struct gdb_xml_element
>>> >> *element,
>>> >> >>> + void *user_data,
>>> >> >>> + VEC(gdb_xml_value_s) *attributes) {
>>> >> >>> + int i, len;
>>> >> >>> + struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s,
>>> >> >>> +attributes);
>>> >> >>> + struct target_attribute *ta = *(struct target_attribute
>>> >> >>> +**)user_data;
>>> >> >>> + CORE_ADDR start, end;
>>> >> >>> + struct target_attribute_address *ta_addr;
>>> >> >>
>>> >> >> I happen to see some compilation warnings on my new Fedora 16 box,
>>> >> >> while these warnings don't appear on my Ubuntu box.
>>> >> >>
>>> >> >> ... -Werror -c -o target-memory.o -MT target-memory.o -MMD -MP -MF
>>> >> >> .deps/target-memory.Tpo ../../../git/gdb/target-memory.c
>>> >> >> ../../../git/gdb/target-attributes.c: In function
>>> >> 'target_attribute_address_handler':
>>> >> >> ../../../git/gdb/target-attributes.c:487:16: error: 'end' may be
>>> >> used
>>> >> >> uninitialized in this function [-Werror=uninitialized]
>>> >> >> ../../../git/gdb/target-attributes.c:486:18: error: 'start' may be
>>> >> >> used uninitialized in this function [-Werror=uninitialized]
>>> >> >> ../../../git/gdb/target-attributes.c: In function
>>> >> 'target_attribute_attr_handler':
>>> >> >> ../../../git/gdb/target-attributes.c:376:12: error: 'type' may be
>>> >> >> used uninitialized in this function [-Werror=uninitialized]
>>> >> >> ../../../git/gdb/target-attributes.c: In function
>>> >> 'target_attribute_type':
>>> >> >> ../../../git/gdb/target-attributes.c:632:3: error: 'ret' may be used
>>> >> >> uninitialized in this function [-Werror=uninitialized]
>>> >> >> cc1: all warnings being treated as errors
>>> >> >> make: *** [target-attributes.o] Error 1
>>> >> >>
>>> >> >> The gcc I am using is 4.6.3
>>> >> >> $ gcc --version
>>> >> >> gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
>>> >> >>
>>> >> >> We have to get these warnings fixed.
>>> >> >>
>>> >> >>> +
>>> >> >>> + len = VEC_length (gdb_xml_value_s, attributes); for (i = 0; i <
>>> >> >>> + len; i++)
>>> >> >>> + {
>>> >> >>> + if (strcmp (attrs[i].name, "start") == 0)
>>> >> >>> + start = * (ULONGEST *) attrs[i].value;
>>> >> >>> + else if (strcmp (attrs[i].name, "end") == 0)
>>> >> >>> + end = * (ULONGEST *) attrs[i].value;
>>> >> >>> + else
>>> >> >>> + gdb_xml_error (parser, _("Unknown attribute name '%s'."),
>>> >> >>> + attrs[i].name);
>>> >> >>> + }
>>> >> >>> +
>>> >> >>> + ta_addr = xmalloc (sizeof (struct target_attribute_address));
>>> >> >>> + ta_addr->start = start; ta_addr->end = end;
>>> >> >>> +
>>> >> >>> + ta_addr->prev = ta->addresses;
>>> >> >>> + ta->addresses = ta_addr;
>>> >> >>> +}
>>> >> >>
>>> >> >> --
>>> >> >> Yao
>>> >> >
>>> >> > Thanks. I post a new version.
>>> >> >
>>> >> > Best,
>>> >> > Hui
>>> >>
>>> >> Got some error when built with trunk. Post a new version for this
>>> >> error.
>>> >>
>>> >> Thanks,
>>> >> Hui
>>>
>>
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-02-26 3:34 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-29 8:12 [PATCH] target attributes [1/5] core and load from target function Hui Zhu
2012-08-29 14:43 ` Yao Qi
2012-09-02 10:39 ` Hui Zhu
2012-11-21 8:56 ` Hui Zhu
2012-11-30 6:03 ` Abid, Hafiz
2013-02-18 10:02 ` Hui Zhu
2013-02-18 11:45 ` Abid, Hafiz
2013-02-19 16:11 ` Hui Zhu
2013-02-26 3:34 ` Hui Zhu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).