+
+/* Per-inferior data key for auxv. */
+static const struct inferior_data *auxv_inferior_data;
+
+/* Auxiliary Vector information structure. This is used by GDB
+ for caching purposes for each inferior. This helps reduce the
+ overhead of transfering data from a remote target to the local host. */
+struct auxv_info
+{
+ LONGEST length;
+ gdb_byte *data;
+};
+
+/* Handles the cleanup of the auxv cache for inferior INF. ARG is ignored.
+ Frees whatever allocated space there is to be freed and sets INF's auxv cache
+ data pointer to NULL.
+
+ This function is called when the following events occur: inferior_appeared,
+ inferior_exit and executable_changed. */
+
+static void
+auxv_inferior_data_cleanup (struct inferior *inf, void *arg)
+{
+ struct auxv_info *info;
+
+ info = inferior_data (inf, auxv_inferior_data);
+ if (info != NULL)
+ {
+ xfree (info->data);
+ xfree (info);
+ set_inferior_data (inf, auxv_inferior_data, NULL);
+ }
+}
+
+/* Invalidate INF's auxv cache. */
+
+static void
+invalidate_auxv_cache_inf (struct inferior *inf)
+{
+ auxv_inferior_data_cleanup (inf, NULL);
+}
+
+/* Invalidate current inferior's auxv cache. */
+
+static void
+invalidate_auxv_cache (void)
+{
+ invalidate_auxv_cache_inf (current_inferior ());
+}
+
+/* Fetch the auxv object from inferior INF. If auxv is cached already,
+ return a pointer to the cache. If not, fetch the auxv object from the
+ target and cache it. This function always returns a valid INFO pointer. */
+
+static struct auxv_info *
+get_auxv_inferior_data (struct target_ops *ops)
+{
+ struct auxv_info *info;
+ struct inferior *inf = current_inferior ();
+
+ info = inferior_data (inf, auxv_inferior_data);
+ if (info == NULL)
+ {
+ info = XZALLOC (struct auxv_info);
+ info->length = target_read_alloc (ops, TARGET_OBJECT_AUXV,
+ NULL, &info->data);
+ set_inferior_data (inf, auxv_inferior_data, info);
+ }
+
+ return info;
+}
+