Resolve more problems with readelf uncovered by fuzzing binary files.
[deliverable/binutils-gdb.git] / gdb / progspace.c
index 926c4ead38eff0ed0cd4414e5607ce12d7d80cb1..48cb34a5ce51842d64c1029d81856741bac7cb76 100644 (file)
@@ -1,6 +1,6 @@
 /* Program and address space management, for GDB, the GNU debugger.
 
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -37,21 +37,32 @@ struct program_space *current_program_space;
 /* The last address space number assigned.  */
 static int highest_address_space_num;
 
-/* Prototypes for local functions */
-
-static void program_space_alloc_data (struct program_space *);
-static void program_space_free_data (struct program_space *);
 \f
 
-/* An address space.  Currently this is not used for much other than
-   for comparing if pspaces/inferior/threads see the same address
+/* Keep a registry of per-program_space data-pointers required by other GDB
+   modules.  */
+
+DEFINE_REGISTRY (program_space, REGISTRY_ACCESS_FIELD)
+
+/* An address space.  It is used for comparing if pspaces/inferior/threads
+   see the same address space and for associating caches to each address
    space.  */
 
 struct address_space
 {
   int num;
+
+  /* Per aspace data-pointers required by other GDB modules.  */
+  REGISTRY_FIELDS;
 };
 
+/* Keep a registry of per-address_space data-pointers required by other GDB
+   modules.  */
+
+DEFINE_REGISTRY (address_space, REGISTRY_ACCESS_FIELD)
+
+\f
+
 /* Create a new address space object, and add it to the list.  */
 
 struct address_space *
@@ -59,8 +70,9 @@ new_address_space (void)
 {
   struct address_space *aspace;
 
-  aspace = XZALLOC (struct address_space);
+  aspace = XCNEW (struct address_space);
   aspace->num = ++highest_address_space_num;
+  address_space_alloc_data (aspace);
 
   return aspace;
 }
@@ -72,7 +84,7 @@ new_address_space (void)
 struct address_space *
 maybe_new_address_space (void)
 {
-  int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch);
+  int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch ());
 
   if (shared_aspace)
     {
@@ -86,6 +98,7 @@ maybe_new_address_space (void)
 static void
 free_address_space (struct address_space *aspace)
 {
+  address_space_free_data (aspace);
   xfree (aspace);
 }
 
@@ -113,7 +126,7 @@ add_program_space (struct address_space *aspace)
 {
   struct program_space *pspace;
 
-  pspace = XZALLOC (struct program_space);
+  pspace = XCNEW (struct program_space);
 
   pspace->num = ++last_program_space_num;
   pspace->aspace = aspace;
@@ -145,10 +158,10 @@ release_program_space (struct program_space *pspace)
   no_shared_libraries (NULL, 0);
   exec_close ();
   free_all_objfiles ();
-  if (!gdbarch_has_shared_address_space (target_gdbarch))
+  if (!gdbarch_has_shared_address_space (target_gdbarch ()))
     free_address_space (pspace->aspace);
-  resize_section_table (&pspace->target_sections,
-                       -resize_section_table (&pspace->target_sections, 0));
+  clear_section_table (&pspace->target_sections);
+  clear_program_space_solib_cache (pspace);
     /* Discard any data modules have associated with the PSPACE.  */
   program_space_free_data (pspace);
   xfree (pspace);
@@ -156,48 +169,23 @@ release_program_space (struct program_space *pspace)
   do_cleanups (old_chain);
 }
 
-/* Unlinks PSPACE from the pspace list, and releases it.  */
-
-void
-remove_program_space (struct program_space *pspace)
-{
-  struct program_space *ss, **ss_link;
-
-  ss = program_spaces;
-  ss_link = &program_spaces;
-  while (ss)
-    {
-      if (ss != pspace)
-       {
-         ss_link = &ss->next;
-         ss = *ss_link;
-         continue;
-       }
-
-      *ss_link = ss->next;
-      release_program_space (ss);
-      ss = *ss_link;
-    }
-}
-
 /* Copies program space SRC to DEST.  Copies the main executable file,
    and the main symbol file.  Returns DEST.  */
 
 struct program_space *
 clone_program_space (struct program_space *dest, struct program_space *src)
 {
-  struct program_space *new_pspace;
   struct cleanup *old_chain;
 
   old_chain = save_current_program_space ();
 
   set_current_program_space (dest);
 
-  if (src->ebfd != NULL)
-    exec_file_attach (bfd_get_filename (src->ebfd), 0);
+  if (src->pspace_exec_filename != NULL)
+    exec_file_attach (src->pspace_exec_filename, 0);
 
   if (src->symfile_object_file != NULL)
-    symbol_file_add_main (src->symfile_object_file->name, 0);
+    symbol_file_add_main (objfile_name (src->symfile_object_file), 0);
 
   do_cleanups (old_chain);
   return dest;
@@ -228,6 +216,7 @@ static void
 restore_program_space (void *arg)
 {
   struct program_space *saved_pspace = arg;
+
   set_current_program_space (saved_pspace);
 }
 
@@ -240,21 +229,8 @@ save_current_program_space (void)
 {
   struct cleanup *old_chain = make_cleanup (restore_program_space,
                                            current_program_space);
-  return old_chain;
-}
-
-/* Find program space number NUM; returns NULL if not found.  */
 
-static struct program_space *
-find_program_space_by_num (int num)
-{
-  struct program_space *pspace;
-
-  ALL_PSPACES (pspace)
-    if (pspace->num == num)
-      return pspace;
-
-  return NULL;
+  return old_chain;
 }
 
 /* Returns true iff there's no inferior bound to PSPACE.  */
@@ -262,8 +238,6 @@ find_program_space_by_num (int num)
 static int
 pspace_empty_p (struct program_space *pspace)
 {
-  struct inferior *inf;
-
   if (find_inferior_for_program_space (pspace) != NULL)
       return 0;
 
@@ -307,10 +281,6 @@ print_program_space (struct ui_out *uiout, int requested)
   int count = 0;
   struct cleanup *old_chain;
 
-  /* Might as well prune away unneeded ones, so the user doesn't even
-     seem them.  */
-  prune_program_spaces ();
-
   /* Compute number of pspaces we will print.  */
   ALL_PSPACES (pspace)
     {
@@ -347,9 +317,8 @@ print_program_space (struct ui_out *uiout, int requested)
 
       ui_out_field_int (uiout, "id", pspace->num);
 
-      if (pspace->ebfd)
-       ui_out_field_string (uiout, "exec",
-                            bfd_get_filename (pspace->ebfd));
+      if (pspace->pspace_exec_filename)
+       ui_out_field_string (uiout, "exec", pspace->pspace_exec_filename);
       else
        ui_out_field_skip (uiout, "exec");
 
@@ -412,7 +381,7 @@ maintenance_info_program_spaces_command (char *args, int from_tty)
        error (_("program space ID %d not known."), requested);
     }
 
-  print_program_space (uiout, requested);
+  print_program_space (current_uiout, requested);
 }
 
 /* Simply returns the count of program spaces.  */
@@ -443,25 +412,32 @@ number_of_program_spaces (void)
 void
 update_address_spaces (void)
 {
-  int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch);
-  struct address_space *aspace = NULL;
+  int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch ());
   struct program_space *pspace;
+  struct inferior *inf;
 
   init_address_spaces ();
 
-  ALL_PSPACES (pspace)
+  if (shared_aspace)
     {
-      free_address_space (pspace->aspace);
+      struct address_space *aspace = new_address_space ();
 
-      if (shared_aspace)
-       {
-         if (aspace == NULL)
-           aspace = new_address_space ();
-         pspace->aspace = aspace;
-       }
-      else
-       pspace->aspace = new_address_space ();
+      free_address_space (current_program_space->aspace);
+      ALL_PSPACES (pspace)
+       pspace->aspace = aspace;
     }
+  else
+    ALL_PSPACES (pspace)
+      {
+       free_address_space (pspace->aspace);
+       pspace->aspace = new_address_space ();
+      }
+
+  for (inf = inferior_list; inf; inf = inf->next)
+    if (gdbarch_has_global_solist (target_gdbarch ()))
+      inf->aspace = maybe_new_address_space ();
+    else
+      inf->aspace = inf->pspace->aspace;
 }
 
 /* Save the current program space so that it may be restored by a later
@@ -476,14 +452,14 @@ save_current_space_and_thread (void)
   /* If restoring to null thread, we need to restore the pspace as
      well, hence, we need to save the current program space first.  */
   old_chain = save_current_program_space ();
-  save_current_inferior ();
+  /* There's no need to save the current inferior here.
+     That is handled by make_cleanup_restore_current_thread.  */
   make_cleanup_restore_current_thread ();
 
   return old_chain;
 }
 
-/* Switches full context to program space PSPACE.  Switches to the
-   first thread found bound to PSPACE.  */
+/* See progspace.h  */
 
 void
 switch_to_program_space_and_thread (struct program_space *pspace)
@@ -491,7 +467,7 @@ switch_to_program_space_and_thread (struct program_space *pspace)
   struct inferior *inf;
 
   inf = find_inferior_for_program_space (pspace);
-  if (inf != NULL)
+  if (inf != NULL && inf->pid != 0)
     {
       struct thread_info *tp;
 
@@ -511,103 +487,15 @@ switch_to_program_space_and_thread (struct program_space *pspace)
 
 \f
 
-/* Keep a registry of per-program_space data-pointers required by other GDB
-   modules.  */
-
-struct program_space_data
-{
-  unsigned index;
-  void (*cleanup) (struct program_space *, void *);
-};
-
-struct program_space_data_registration
-{
-  struct program_space_data *data;
-  struct program_space_data_registration *next;
-};
-
-struct program_space_data_registry
-{
-  struct program_space_data_registration *registrations;
-  unsigned num_registrations;
-};
-
-static struct program_space_data_registry program_space_data_registry
-  = { NULL, 0 };
-
-const struct program_space_data *
-register_program_space_data_with_cleanup
-  (void (*cleanup) (struct program_space *, void *))
-{
-  struct program_space_data_registration **curr;
-
-  /* Append new registration.  */
-  for (curr = &program_space_data_registry.registrations;
-       *curr != NULL; curr = &(*curr)->next);
-
-  *curr = XMALLOC (struct program_space_data_registration);
-  (*curr)->next = NULL;
-  (*curr)->data = XMALLOC (struct program_space_data);
-  (*curr)->data->index = program_space_data_registry.num_registrations++;
-  (*curr)->data->cleanup = cleanup;
-
-  return (*curr)->data;
-}
-
-const struct program_space_data *
-register_program_space_data (void)
-{
-  return register_program_space_data_with_cleanup (NULL);
-}
-
-static void
-program_space_alloc_data (struct program_space *pspace)
-{
-  gdb_assert (pspace->data == NULL);
-  pspace->num_data = program_space_data_registry.num_registrations;
-  pspace->data = XCALLOC (pspace->num_data, void *);
-}
-
-static void
-program_space_free_data (struct program_space *pspace)
-{
-  gdb_assert (pspace->data != NULL);
-  clear_program_space_data (pspace);
-  xfree (pspace->data);
-  pspace->data = NULL;
-}
+/* See progspace.h.  */
 
 void
-clear_program_space_data (struct program_space *pspace)
+clear_program_space_solib_cache (struct program_space *pspace)
 {
-  struct program_space_data_registration *registration;
-  int i;
-
-  gdb_assert (pspace->data != NULL);
-
-  for (registration = program_space_data_registry.registrations, i = 0;
-       i < pspace->num_data;
-       registration = registration->next, i++)
-    if (pspace->data[i] != NULL && registration->data->cleanup)
-      registration->data->cleanup (pspace, pspace->data[i]);
-
-  memset (pspace->data, 0, pspace->num_data * sizeof (void *));
-}
+  VEC_free (so_list_ptr, pspace->added_solibs);
 
-void
-set_program_space_data (struct program_space *pspace,
-                      const struct program_space_data *data,
-                      void *value)
-{
-  gdb_assert (data->index < pspace->num_data);
-  pspace->data[data->index] = value;
-}
-
-void *
-program_space_data (struct program_space *pspace, const struct program_space_data *data)
-{
-  gdb_assert (data->index < pspace->num_data);
-  return pspace->data[data->index];
+  free_char_ptr_vec (pspace->deleted_solibs);
+  pspace->deleted_solibs = NULL;
 }
 
 \f
@@ -616,8 +504,8 @@ void
 initialize_progspace (void)
 {
   add_cmd ("program-spaces", class_maintenance,
-          maintenance_info_program_spaces_command, _("\
-Info about currently known program spaces."),
+          maintenance_info_program_spaces_command,
+          _("Info about currently known program spaces."),
           &maintenanceinfolist);
 
   /* There's always one program space.  Note that this function isn't
This page took 0.028693 seconds and 4 git commands to generate.