aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmair Javaid <omair.javaid@linaro.org>2018-01-22 02:57:19 +0500
committerMatthias Welwarsky <matthias@welwarsky.de>2018-03-10 13:23:25 +0000
commitb4a01f8cdc943fe03a827513aad2f4df2d2a7399 (patch)
tree3d65940d8008a58ee099413d24956f049df4c765
parentdb268a3115b28c3c50c76a67d34113d619a54f89 (diff)
downloadriscv-openocd-b4a01f8cdc943fe03a827513aad2f4df2d2a7399.zip
riscv-openocd-b4a01f8cdc943fe03a827513aad2f4df2d2a7399.tar.gz
riscv-openocd-b4a01f8cdc943fe03a827513aad2f4df2d2a7399.tar.bz2
Allow generation of nested target defined types in gdb target xml
This patch adds support to generate multiple nested architecture defined data types in gdb target xml generated by openOCD. Architecture defined structs, unions, vectors nested in one or more architecture defined types can be generated now. Example: <vector id="v2d" type="ieee_double" count="2"/> <vector id="v2u" type="uint64" count="2"/> <vector id="v2i" type="int64" count="2"/> <union id="vnd"> <field name="f" type="v2d"/> <field name="u" type="v2u"/> <field name="s" type="v2i"/> </union> Change-Id: I0f3c5c6daf3d22cde7e4b7b4165d2e97e25872f7 Signed-off-by: Omair Javaid <omair.javaid@linaro.org> Reviewed-on: http://openocd.zylin.com/4372 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
-rw-r--r--src/server/gdb_server.c75
1 files changed, 71 insertions, 4 deletions
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index a15c5bb..5319106 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1946,12 +1946,45 @@ static const char *gdb_get_reg_type_name(enum reg_type type)
return "int"; /* "int" as default value */
}
+static int lookup_add_arch_defined_types(char const **arch_defined_types_list[], const char *type_id,
+ int *num_arch_defined_types)
+{
+ int tbl_sz = *num_arch_defined_types;
+
+ if (type_id != NULL && (strcmp(type_id, ""))) {
+ for (int j = 0; j < (tbl_sz + 1); j++) {
+ if (!((*arch_defined_types_list)[j])) {
+ (*arch_defined_types_list)[tbl_sz++] = type_id;
+ *arch_defined_types_list = realloc(*arch_defined_types_list,
+ sizeof(char *) * (tbl_sz + 1));
+ (*arch_defined_types_list)[tbl_sz] = NULL;
+ *num_arch_defined_types = tbl_sz;
+ return 1;
+ } else {
+ if (!strcmp((*arch_defined_types_list)[j], type_id))
+ return 0;
+ }
+ }
+ }
+
+ return -1;
+}
+
static int gdb_generate_reg_type_description(struct target *target,
- char **tdesc, int *pos, int *size, struct reg_data_type *type)
+ char **tdesc, int *pos, int *size, struct reg_data_type *type,
+ char const **arch_defined_types_list[], int * num_arch_defined_types)
{
int retval = ERROR_OK;
if (type->type_class == REG_TYPE_CLASS_VECTOR) {
+ struct reg_data_type *data_type = type->reg_type_vector->type;
+ if (data_type->type == REG_TYPE_ARCH_DEFINED) {
+ if (lookup_add_arch_defined_types(arch_defined_types_list, data_type->id,
+ num_arch_defined_types))
+ gdb_generate_reg_type_description(target, tdesc, pos, size, data_type,
+ arch_defined_types_list,
+ num_arch_defined_types);
+ }
/* <vector id="id" type="type" count="count"/> */
xml_printf(&retval, tdesc, pos, size,
"<vector id=\"%s\" type=\"%s\" count=\"%d\"/>\n",
@@ -1959,6 +1992,20 @@ static int gdb_generate_reg_type_description(struct target *target,
type->reg_type_vector->count);
} else if (type->type_class == REG_TYPE_CLASS_UNION) {
+ struct reg_data_type_union_field *field;
+ field = type->reg_type_union->fields;
+ while (field != NULL) {
+ struct reg_data_type *data_type = field->type;
+ if (data_type->type == REG_TYPE_ARCH_DEFINED) {
+ if (lookup_add_arch_defined_types(arch_defined_types_list, data_type->id,
+ num_arch_defined_types))
+ gdb_generate_reg_type_description(target, tdesc, pos, size, data_type,
+ arch_defined_types_list,
+ num_arch_defined_types);
+ }
+
+ field = field->next;
+ }
/* <union id="id">
* <field name="name" type="type"/> ...
* </union> */
@@ -1966,7 +2013,6 @@ static int gdb_generate_reg_type_description(struct target *target,
"<union id=\"%s\">\n",
type->id);
- struct reg_data_type_union_field *field;
field = type->reg_type_union->fields;
while (field != NULL) {
xml_printf(&retval, tdesc, pos, size,
@@ -1999,6 +2045,17 @@ static int gdb_generate_reg_type_description(struct target *target,
field = field->next;
}
} else {
+ while (field != NULL) {
+ struct reg_data_type *data_type = field->type;
+ if (data_type->type == REG_TYPE_ARCH_DEFINED) {
+ if (lookup_add_arch_defined_types(arch_defined_types_list, data_type->id,
+ num_arch_defined_types))
+ gdb_generate_reg_type_description(target, tdesc, pos, size, data_type,
+ arch_defined_types_list,
+ num_arch_defined_types);
+ }
+ }
+
/* <struct id="id">
* <field name="name" type="type"/> ...
* </struct> */
@@ -2091,11 +2148,15 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o
struct reg **reg_list = NULL;
int reg_list_size;
char const **features = NULL;
+ char const **arch_defined_types = NULL;
int feature_list_size = 0;
+ int num_arch_defined_types = 0;
char *tdesc = NULL;
int pos = 0;
int size = 0;
+ arch_defined_types = calloc(1, sizeof(char *));
+
retval = target_get_gdb_reg_list(target, &reg_list,
&reg_list_size, REG_CLASS_ALL);
@@ -2148,8 +2209,13 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o
if (reg_list[i]->reg_data_type != NULL) {
if (reg_list[i]->reg_data_type->type == REG_TYPE_ARCH_DEFINED) {
/* generate <type... first, if there are architecture-defined types. */
- gdb_generate_reg_type_description(target, &tdesc, &pos, &size,
- reg_list[i]->reg_data_type);
+ if (lookup_add_arch_defined_types(&arch_defined_types,
+ reg_list[i]->reg_data_type->id,
+ &num_arch_defined_types))
+ gdb_generate_reg_type_description(target, &tdesc, &pos, &size,
+ reg_list[i]->reg_data_type,
+ &arch_defined_types,
+ &num_arch_defined_types);
type_str = reg_list[i]->reg_data_type->id;
} else {
@@ -2199,6 +2265,7 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o
error:
free(features);
free(reg_list);
+ free(arch_defined_types);
if (retval == ERROR_OK)
*tdesc_out = tdesc;