diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 2b3057a1a..13e5aca6a 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -2196,6 +2196,7 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o int retval = ERROR_OK; struct reg **reg_list = NULL; int reg_list_size; + char const *architecture; char const **features = NULL; char const **arch_defined_types = NULL; int feature_list_size = 0; @@ -2237,6 +2238,12 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o "\n" "\n"); + /* generate architecture element if supported by target */ + architecture = target_get_gdb_arch(target); + if (architecture != NULL) + xml_printf(&retval, &tdesc, &pos, &size, + "%s\n", architecture); + /* generate target description according to register list */ if (features != NULL) { while (features[current_feature]) { @@ -2386,6 +2393,8 @@ static int gdb_target_description_supported(struct target *target, int *supporte char const **features = NULL; int feature_list_size = 0; + char const *architecture = target_get_gdb_arch(target); + retval = target_get_gdb_reg_list(target, ®_list, ®_list_size, REG_CLASS_ALL); if (retval != ERROR_OK) { @@ -2407,7 +2416,7 @@ static int gdb_target_description_supported(struct target *target, int *supporte } if (supported) { - if (feature_list_size) + if (architecture || feature_list_size) *supported = 1; else *supported = 0; diff --git a/src/target/target.c b/src/target/target.c index 3aaebcd49..c1ccf962e 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1199,6 +1199,13 @@ int target_hit_watchpoint(struct target *target, return target->type->hit_watchpoint(target, hit_watchpoint); } +const char *target_get_gdb_arch(struct target *target) +{ + if (target->type->get_gdb_arch == NULL) + return NULL; + return target->type->get_gdb_arch(target); +} + int target_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class) diff --git a/src/target/target.h b/src/target/target.h index fe7e1a7db..5457f0abf 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -472,6 +472,13 @@ int target_remove_watchpoint(struct target *target, int target_hit_watchpoint(struct target *target, struct watchpoint **watchpoint); +/** + * Obtain the architecture for GDB. + * + * This routine is a wrapper for target->type->get_gdb_arch. + */ +const char *target_get_gdb_arch(struct target *target); + /** * Obtain the registers for GDB. * diff --git a/src/target/target_type.h b/src/target/target_type.h index fbbd57d98..a8928911f 100644 --- a/src/target/target_type.h +++ b/src/target/target_type.h @@ -88,6 +88,15 @@ struct target_type { int (*deassert_reset)(struct target *target); int (*soft_reset_halt)(struct target *target); + /** + * Target architecture for GDB. + * + * The string returned by this function will not be automatically freed; + * if dynamic allocation is used for this value, it must be managed by + * the target, ideally by caching the result for subsequent calls. + */ + const char *(*get_gdb_arch)(struct target *target); + /** * Target register access for GDB. Do @b not call this function * directly, use target_get_gdb_reg_list() instead.