Great ! Thanks.

2013/6/13 Hsiangkai Wang <[email protected]>

> Hi, Franck,
>
> I agree your enhancement.  I will do some modification and merge your
> patch in commit 1382.
> Thanks.
>
> 2013/6/10 Franck Jullien <[email protected]>
>
>> 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, &reg_list,
>>> &reg_list_size,
>>> -                               reg_class);
>>> +       retval = target_get_gdb_reg_list(target, &reg_list,
>>> &reg_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
>>>
>>>
>>
>
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to