H
siangkai Wang,
Could you try this patch on your target ? It implies only some minor
changes in your target code.
This way, the tdesc thing will be compatible with my openrisc port.
Thanks.
2013/6/9 <[email protected]>
> From: Franck Jullien <[email protected]>
>
> This patch adds the possibility to create feature sections
> from the feature name. The feature name can be anything.
>
> It also adds a command to save the tdesc file (for debug purpose).
>
> Change-Id: I47f51028c6a1a2a2bb41e61170438e576eb05890
> Signed-off-by: Franck Jullien <[email protected]>
> ---
> src/server/gdb_server.c | 223
> +++++++++++++++++++++++++++++++++--------------
> src/target/register.h | 8 +--
> 2 files changed, 157 insertions(+), 74 deletions(-)
>
> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
> index bcd1a66..5f9552f 100644
> --- a/src/server/gdb_server.c
> +++ b/src/server/gdb_server.c
> @@ -1717,20 +1717,6 @@ static const char *gdb_get_reg_type_name(enum
> reg_type type)
> return "int"; /* "int" as default value */
> }
>
> -static const char *gdb_get_reg_group_name(enum reg_group group)
> -{
> - switch (group) {
> - case REG_GROUP_GENERAL:
> - return "general";
> - case REG_GROUP_FLOAT:
> - return "float";
> - case REG_GROUP_VECTOR:
> - return "vector";
> - }
> -
> - return NULL;
> -}
> -
> static int gdb_generate_reg_type_description(struct target *target,
> char **tdesc, int *pos, int *size, struct reg_data_type
> *type)
> {
> @@ -1828,10 +1814,46 @@ static int
> gdb_generate_reg_type_description(struct target *target,
> return ERROR_OK;
> }
>
> +/* Get a list of available target registers features. feature_list must
> + * be freed by caller.
> + */
> +int get_reg_features_list(struct target *target, char **feature_list[],
> int *feature_list_size,
> + struct reg **reg_list, int reg_list_size)
> +{
> + int tbl_sz = 0;
> +
> + /* Start with only one element */
> + *feature_list = calloc(1, sizeof(char *));
> +
> + for (int i = 0; i < reg_list_size; i++) {
> + if (reg_list[i]->feature->name != NULL &&
> strcmp(reg_list[i]->feature->name, "")) {
> + /* We found a feature, check if the feature is
> already in the
> + * table. If not, allocate a new entry for the
> table and
> + * put the new feature in it.
> + */
> + for (int j = 0; j < (tbl_sz + 1); j++) {
> + if (!((*feature_list)[j])) {
> + (*feature_list)[tbl_sz++] =
> strdup(reg_list[i]->feature->name);
> + *feature_list =
> realloc(*feature_list, sizeof(char *) * (tbl_sz + 1));
> + (*feature_list)[tbl_sz] = NULL;
> + break;
> + } else {
> + if (!strcmp((*feature_list)[j],
> reg_list[i]->feature->name))
> + break;
> + }
> + }
> + }
> + }
> +
> + if (feature_list_size)
> + *feature_list_size = tbl_sz;
> +
> + return ERROR_OK;
> +}
> +
> static int gdb_generate_target_description(struct target *target, char
> **tdesc)
> {
> int retval = ERROR_OK;
> - enum target_register_class reg_class;
> struct reg **reg_list;
> int reg_list_size;
> int pos = 0;
> @@ -1842,75 +1864,97 @@ static int gdb_generate_target_description(struct
> target *target, char **tdesc)
> "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n"
> "<target version=\"1.0\">\n");
>
> - for (reg_class = REG_CLASS_GENERAL; reg_class != REG_CLASS_END;
> reg_class++) {
> - retval = target_get_gdb_reg_list(target, ®_list,
> ®_list_size,
> - reg_class);
> + retval = target_get_gdb_reg_list(target, ®_list, ®_list_size,
> + REG_CLASS_ALL);
> +
> + if (retval != ERROR_OK) {
> + LOG_ERROR("get register list failed");
> + return ERROR_FAIL;
> + }
>
> - if (retval != ERROR_OK) {
> - LOG_ERROR("get register list %d failed",
> reg_class);
> - continue;
> - }
> + if (reg_list_size <= 0)
> + return ERROR_FAIL;
>
> - if (reg_list_size <= 0)
> - continue;
> + char **features = NULL;
> + /* Get a list of available target registers features */
> + retval = get_reg_features_list(target, &features, NULL, reg_list,
> reg_list_size);
> + if (retval != ERROR_OK) {
> + LOG_ERROR("Can't get the registers feature list");
> + return ERROR_FAIL;
> + }
>
> - /* generate target description according to register list
> */
> - xml_printf(&retval, tdesc, &pos, &size,
> - "<feature name=\"%s\">\n",
> - reg_list[0]->feature->name);
> + /* If we found some features associated with registers, create
> sections */
> + int current_feature = 0;
>
> - int i;
> - for (i = 0; i < reg_list_size; i++) {
> - const char *type_str;
> - 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);
> -
> - type_str =
> reg_list[i]->reg_data_type->id;
> + /* generate target description according to register list */
> + if (features != NULL) {
> + while (features[current_feature]) {
> +
> + xml_printf(&retval, tdesc, &pos, &size,
> + "<feature name=\"%s\">\n",
> + features[current_feature]);
> +
> + int i;
> + for (i = 0; i < reg_list_size; i++) {
> +
> + if (strcmp(reg_list[i]->feature->name,
> features[current_feature]))
> + continue;
> +
> + const char *type_str;
> + 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);
> +
> + type_str =
> reg_list[i]->reg_data_type->id;
> + } else {
> + /* predefined type */
> + type_str =
> gdb_get_reg_type_name(
> +
> reg_list[i]->reg_data_type->type);
> + }
> } else {
> - /* predefined type */
> - type_str = gdb_get_reg_type_name(
> -
> reg_list[i]->reg_data_type->type);
> + /* Default type is "int" */
> + type_str = "int";
> }
> - } else {
> - /* Default type is "int" */
> - type_str = "int";
> - }
>
> - xml_printf(&retval, tdesc, &pos, &size,
> - "<reg name=\"%s\"",
> reg_list[i]->name);
> - xml_printf(&retval, tdesc, &pos, &size,
> - " bitsize=\"%d\"",
> reg_list[i]->size);
> - xml_printf(&retval, tdesc, &pos, &size,
> - " regnum=\"%d\"",
> reg_list[i]->number);
> - if (reg_list[i]->caller_save)
> xml_printf(&retval, tdesc, &pos, &size,
> - " save-restore=\"yes\"");
> - else
> + "<reg name=\"%s\"",
> reg_list[i]->name);
> +
> xml_printf(&retval, tdesc, &pos, &size,
> - " save-restore=\"no\"");
> + " bitsize=\"%d\"",
> reg_list[i]->size);
>
> - xml_printf(&retval, tdesc, &pos, &size,
> - " type=\"%s\"", type_str);
> + xml_printf(&retval, tdesc, &pos, &size,
> + " regnum=\"%d\"",
> reg_list[i]->number);
> +
> + if (reg_list[i]->caller_save)
> + xml_printf(&retval, tdesc, &pos,
> &size,
> + "
> save-restore=\"yes\"");
> + else
> + xml_printf(&retval, tdesc, &pos,
> &size,
> + "
> save-restore=\"no\"");
>
> - const char *group_str;
> - group_str =
> gdb_get_reg_group_name(reg_list[i]->group);
> - if (group_str != NULL)
> xml_printf(&retval, tdesc, &pos, &size,
> - " group=\"%s\"",
> group_str);
> + " type=\"%s\"", type_str);
>
> - xml_printf(&retval, tdesc, &pos, &size,
> - "/>\n");
> - }
> + if (reg_list[i]->group != NULL)
> + xml_printf(&retval, tdesc, &pos,
> &size,
> + " group=\"%s\"",
> reg_list[i]->group);
>
> - xml_printf(&retval, tdesc, &pos, &size,
> - "</feature>\n");
> + xml_printf(&retval, tdesc, &pos, &size,
> + "/>\n");
> + }
>
> - free(reg_list);
> + xml_printf(&retval, tdesc, &pos, &size,
> + "</feature>\n");
> +
> + current_feature++;
> + }
> }
>
> + free(reg_list);
> + free(features);
> +
> xml_printf(&retval, tdesc, &pos, &size,
> "</target>\n");
>
> @@ -2658,6 +2702,45 @@
> COMMAND_HANDLER(handle_gdb_target_description_command)
> return ERROR_OK;
> }
>
> +COMMAND_HANDLER(handle_gdb_save_tdesc)
> +{
> + static char *tdesc;
> + static uint32_t tdesc_length;
> + struct target *target = get_current_target(CMD_CTX);
> + char *tdesc_filename;
> +
> + if (tdesc == NULL) {
> + gdb_generate_target_description(target, &tdesc);
> + tdesc_length = strlen(tdesc);
> + }
> +
> + struct fileio fileio;
> + size_t size_written;
> +
> + tdesc_filename = malloc(strlen(target_type_name(target)) + 5);
> + sprintf(tdesc_filename, "%s.xml", target_type_name(target));
> +
> + int retval = fileio_open(&fileio, tdesc_filename, FILEIO_WRITE,
> FILEIO_TEXT);
> +
> + free(tdesc_filename);
> +
> + if (retval != ERROR_OK) {
> + LOG_WARNING("Can't open %s for writing", tdesc_filename);
> + return ERROR_FAIL;
> + }
> +
> + retval = fileio_write(&fileio, tdesc_length, tdesc, &size_written);
> +
> + fileio_close(&fileio);
> +
> + if (retval != ERROR_OK) {
> + LOG_WARNING("Error while writing the tdesc file");
> + return ERROR_FAIL;
> + }
> +
> + return ERROR_OK;
> +}
> +
> static const struct command_registration gdb_command_handlers[] = {
> {
> .name = "gdb_sync",
> @@ -2717,6 +2800,12 @@ static const struct command_registration
> gdb_command_handlers[] = {
> .help = "enable or disable target description",
> .usage = "('enable'|'disable')"
> },
> + {
> + .name = "save_tdesc",
> + .handler = handle_gdb_save_tdesc,
> + .mode = COMMAND_ANY,
> + .help = "print the target description file",
> + },
> COMMAND_REGISTRATION_DONE
> };
>
> diff --git a/src/target/register.h b/src/target/register.h
> index 25824bf..cffcf57 100644
> --- a/src/target/register.h
> +++ b/src/target/register.h
> @@ -44,12 +44,6 @@ enum reg_type {
> REG_TYPE_ARCH_DEFINED,
> };
>
> -enum reg_group {
> - REG_GROUP_GENERAL,
> - REG_GROUP_FLOAT,
> - REG_GROUP_VECTOR,
> -};
> -
> struct reg_feature {
> const char *name;
> };
> @@ -129,7 +123,7 @@ struct reg {
> bool valid;
> uint32_t size;
> struct reg_data_type *reg_data_type;
> - enum reg_group group;
> + const char *group;
> void *arch_info;
> const struct reg_arch_type *type;
> };
> --
> 1.7.1
>
>
------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel