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, ®_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
>>>
>>>
>>
>
------------------------------------------------------------------------------
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