aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/gdb_server.c11
-rw-r--r--src/target/target.c7
-rw-r--r--src/target/target.h7
-rw-r--r--src/target/target_type.h9
4 files changed, 33 insertions, 1 deletions
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 2b3057a..13e5aca 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
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n"
"<target version=\"1.0\">\n");
+ /* generate architecture element if supported by target */
+ architecture = target_get_gdb_arch(target);
+ if (architecture != NULL)
+ xml_printf(&retval, &tdesc, &pos, &size,
+ "<architecture>%s</architecture>\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, &reg_list,
&reg_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 3aaebcd..c1ccf96 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 fe7e1a7..5457f0a 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -473,6 +473,13 @@ 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.
*
* This routine is a wrapper for target->type->get_gdb_reg_list.
diff --git a/src/target/target_type.h b/src/target/target_type.h
index fbbd57d..a892891 100644
--- a/src/target/target_type.h
+++ b/src/target/target_type.h
@@ -89,6 +89,15 @@ struct target_type {
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.
*