Make the objfile destructor private
[deliverable/binutils-gdb.git] / gdb / compile / compile-object-run.c
index d34c9eda90abb6385f39edcf5377ef1ed52d7e7d..72f3060243e8094901e0be206f38bd3ed1740968 100644 (file)
@@ -1,6 +1,6 @@
 /* Call module for 'compile' command.
 
-   Copyright (C) 2014-2015 Free Software Foundation, Inc.
+   Copyright (C) 2014-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -24,6 +24,9 @@
 #include "objfiles.h"
 #include "compile-internal.h"
 #include "dummy-frame.h"
+#include "block.h"
+#include "valprint.h"
+#include "compile.h"
 
 /* Helper for do_module_cleanup.  */
 
@@ -36,6 +39,17 @@ struct do_module_cleanup
   /* .c file OBJFILE was built from.  It needs to be xfree-d.  */
   char *source_file;
 
+  /* Copy from struct compile_module.  */
+  enum compile_i_scope_types scope;
+  void *scope_data;
+
+  /* Copy from struct compile_module.  */
+  struct type *out_value_type;
+  CORE_ADDR out_value_addr;
+
+  /* Copy from struct compile_module.  */
+  struct munmap_list *munmap_list_head;
+
   /* objfile_name of our objfile.  */
   char objfile_name_string[1];
 };
@@ -45,19 +59,34 @@ struct do_module_cleanup
 
 static dummy_frame_dtor_ftype do_module_cleanup;
 static void
-do_module_cleanup (void *arg)
+do_module_cleanup (void *arg, int registers_valid)
 {
-  struct do_module_cleanup *data = arg;
-  struct objfile *objfile;
+  struct do_module_cleanup *data = (struct do_module_cleanup *) arg;
 
   if (data->executedp != NULL)
-    *data->executedp = 1;
+    {
+      *data->executedp = 1;
 
-  ALL_OBJFILES (objfile)
+      /* This code cannot be in compile_object_run as OUT_VALUE_TYPE
+        no longer exists there.  */
+      if (data->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
+         || data->scope == COMPILE_I_PRINT_VALUE_SCOPE)
+       {
+         struct value *addr_value;
+         struct type *ptr_type = lookup_pointer_type (data->out_value_type);
+
+         addr_value = value_from_pointer (ptr_type, data->out_value_addr);
+
+         /* SCOPE_DATA would be stale unless EXECUTEDP != NULL.  */
+         compile_print_value (value_ind (addr_value), data->scope_data);
+       }
+    }
+
+  for (objfile *objfile : current_program_space->objfiles ())
     if ((objfile->flags & OBJF_USERLOADED) == 0
         && (strcmp (objfile_name (objfile), data->objfile_name_string) == 0))
       {
-       free_objfile (objfile);
+       objfile->unlink ();
 
        /* It may be a bit too pervasive in this dummy_frame dtor callback.  */
        clear_symtab_users (0);
@@ -69,6 +98,8 @@ do_module_cleanup (void *arg)
   unlink (data->source_file);
   xfree (data->source_file);
 
+  delete data->munmap_list_head;
+
   /* Delete the .o file.  */
   unlink (data->objfile_name_string);
   xfree (data);
@@ -84,55 +115,77 @@ void
 compile_object_run (struct compile_module *module)
 {
   struct value *func_val;
-  struct frame_id dummy_id;
-  struct cleanup *cleanups;
   struct do_module_cleanup *data;
-  volatile struct gdb_exception ex;
   const char *objfile_name_s = objfile_name (module->objfile);
   int dtor_found, executed = 0;
-  CORE_ADDR func_addr = module->func_addr;
+  struct symbol *func_sym = module->func_sym;
   CORE_ADDR regs_addr = module->regs_addr;
+  struct objfile *objfile = module->objfile;
 
-  data = xmalloc (sizeof (*data) + strlen (objfile_name_s));
+  data = (struct do_module_cleanup *) xmalloc (sizeof (*data)
+                                              + strlen (objfile_name_s));
   data->executedp = &executed;
   data->source_file = xstrdup (module->source_file);
   strcpy (data->objfile_name_string, objfile_name_s);
+  data->scope = module->scope;
+  data->scope_data = module->scope_data;
+  data->out_value_type = module->out_value_type;
+  data->out_value_addr = module->out_value_addr;
+  data->munmap_list_head = module->munmap_list_head;
 
   xfree (module->source_file);
   xfree (module);
+  module = NULL;
 
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
+  try
     {
-      func_val = value_from_pointer
-                (builtin_type (target_gdbarch ())->builtin_func_ptr,
-                 func_addr);
-
-      if (regs_addr == 0)
-       call_function_by_hand_dummy (func_val, 0, NULL,
-                                    do_module_cleanup, data);
-      else
+      struct type *func_type = SYMBOL_TYPE (func_sym);
+      htab_t copied_types;
+      int current_arg = 0;
+      struct value **vargs;
+
+      /* OBJFILE may disappear while FUNC_TYPE still will be in use.  */
+      copied_types = create_copied_types_hash (objfile);
+      func_type = copy_type_recursive (objfile, func_type, copied_types);
+      htab_delete (copied_types);
+
+      gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC);
+      func_val = value_from_pointer (lookup_pointer_type (func_type),
+                                  BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (func_sym)));
+
+      vargs = XALLOCAVEC (struct value *, TYPE_NFIELDS (func_type));
+      if (TYPE_NFIELDS (func_type) >= 1)
        {
-         struct value *arg_val;
-
-         arg_val = value_from_pointer
-                   (builtin_type (target_gdbarch ())->builtin_func_ptr,
-                    regs_addr);
-         call_function_by_hand_dummy (func_val, 1, &arg_val,
-                                      do_module_cleanup, data);
+         gdb_assert (regs_addr != 0);
+         vargs[current_arg] = value_from_pointer
+                         (TYPE_FIELD_TYPE (func_type, current_arg), regs_addr);
+         ++current_arg;
+       }
+      if (TYPE_NFIELDS (func_type) >= 2)
+       {
+         gdb_assert (data->out_value_addr != 0);
+         vargs[current_arg] = value_from_pointer
+              (TYPE_FIELD_TYPE (func_type, current_arg), data->out_value_addr);
+         ++current_arg;
        }
+      gdb_assert (current_arg == TYPE_NFIELDS (func_type));
+      auto args = gdb::make_array_view (vargs, TYPE_NFIELDS (func_type));
+      call_function_by_hand_dummy (func_val, NULL, args,
+                                  do_module_cleanup, data);
     }
-  dtor_found = find_dummy_frame_dtor (do_module_cleanup, data);
-  if (!executed)
-    data->executedp = NULL;
-  if (ex.reason >= 0)
-    gdb_assert (!dtor_found && executed);
-  else
+  catch (const gdb_exception_error &ex)
     {
-      /* In the case od DTOR_FOUND or in the case of EXECUTED nothing
+      /* In the case of DTOR_FOUND or in the case of EXECUTED nothing
         needs to be done.  */
+      dtor_found = find_dummy_frame_dtor (do_module_cleanup, data);
+      if (!executed)
+       data->executedp = NULL;
       gdb_assert (!(dtor_found && executed));
       if (!dtor_found && !executed)
-       do_module_cleanup (data);
-      throw_exception (ex);
+       do_module_cleanup (data, 0);
+      throw;
     }
+
+  dtor_found = find_dummy_frame_dtor (do_module_cleanup, data);
+  gdb_assert (!dtor_found && executed);
 }
This page took 0.027387 seconds and 4 git commands to generate.