+/* Support for inferring a target description based on the current
+ architecture and the size of a 'g' packet. While the 'g' packet
+ can have any size (since optional registers can be left off the
+ end), some sizes are easily recognizable given knowledge of the
+ approximate architecture. */
+
+struct remote_g_packet_guess
+{
+ int bytes;
+ const struct target_desc *tdesc;
+};
+typedef struct remote_g_packet_guess remote_g_packet_guess_s;
+DEF_VEC_O(remote_g_packet_guess_s);
+
+struct remote_g_packet_data
+{
+ VEC(remote_g_packet_guess_s) *guesses;
+};
+
+static struct gdbarch_data *remote_g_packet_data_handle;
+
+static void *
+remote_g_packet_data_init (struct obstack *obstack)
+{
+ return OBSTACK_ZALLOC (obstack, struct remote_g_packet_data);
+}
+
+void
+register_remote_g_packet_guess (struct gdbarch *gdbarch, int bytes,
+ const struct target_desc *tdesc)
+{
+ struct remote_g_packet_data *data
+ = gdbarch_data (gdbarch, remote_g_packet_data_handle);
+ struct remote_g_packet_guess new_guess, *guess;
+ int ix;
+
+ gdb_assert (tdesc != NULL);
+
+ for (ix = 0;
+ VEC_iterate (remote_g_packet_guess_s, data->guesses, ix, guess);
+ ix++)
+ if (guess->bytes == bytes)
+ internal_error (__FILE__, __LINE__,
+ "Duplicate g packet description added for size %d",
+ bytes);
+
+ new_guess.bytes = bytes;
+ new_guess.tdesc = tdesc;
+ VEC_safe_push (remote_g_packet_guess_s, data->guesses, &new_guess);
+}
+
+static const struct target_desc *
+remote_read_description (struct target_ops *target)
+{
+ struct remote_g_packet_data *data
+ = gdbarch_data (current_gdbarch, remote_g_packet_data_handle);
+
+ if (!VEC_empty (remote_g_packet_guess_s, data->guesses))
+ {
+ struct remote_g_packet_guess *guess;
+ int ix;
+ int bytes = send_g_packet ();
+
+ for (ix = 0;
+ VEC_iterate (remote_g_packet_guess_s, data->guesses, ix, guess);
+ ix++)
+ if (guess->bytes == bytes)
+ return guess->tdesc;
+
+ /* We discard the g packet. A minor optimization would be to
+ hold on to it, and fill the register cache once we have selected
+ an architecture, but it's too tricky to do safely. */
+ }
+
+ return NULL;
+}
+