From b4a01f8cdc943fe03a827513aad2f4df2d2a7399 Mon Sep 17 00:00:00 2001 From: Omair Javaid Date: Mon, 22 Jan 2018 02:57:19 +0500 Subject: [PATCH] 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: Change-Id: I0f3c5c6daf3d22cde7e4b7b4165d2e97e25872f7 Signed-off-by: Omair Javaid Reviewed-on: http://openocd.zylin.com/4372 Tested-by: jenkins Reviewed-by: Matthias Welwarsky --- src/server/gdb_server.c | 75 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index a15c5bb8..5319106a 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); + } /* */ xml_printf(&retval, tdesc, pos, size, "\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; + } /* * ... * */ @@ -1966,7 +2013,6 @@ static int gdb_generate_reg_type_description(struct target *target, "\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); + } + } + /* * ... * */ @@ -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, ®_list, ®_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 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; -- 2.39.5