[PR ld/22269] arm: Avoid dynamic relocs for undefweak symbols in static PIE
[deliverable/binutils-gdb.git] / gdb / extension.c
index 1146cc7d03c552aa64445b78d0fcc4da091c8018..f9418de4311572b4d009a0da337aa0ab3418066d 100644 (file)
@@ -1,6 +1,6 @@
 /* Interface between gdb and its extension languages.
 
-   Copyright (C) 2014 Free Software Foundation, Inc.
+   Copyright (C) 2014-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
 #include "defs.h"
 #include <signal.h>
+#include "target.h"
 #include "auto-load.h"
 #include "breakpoint.h"
 #include "event-top.h"
 #include "extension.h"
 #include "extension-priv.h"
-#include "observer.h"
+#include "observable.h"
 #include "cli/cli-script.h"
 #include "python/python.h"
 #include "guile/guile.h"
@@ -61,6 +62,7 @@ static const struct extension_language_script_ops
 {
   source_gdb_script,
   source_gdb_objfile_script,
+  NULL, /* objfile_script_executor */
   auto_load_gdb_scripts_enabled
 };
 
@@ -152,6 +154,9 @@ get_ext_lang_of_file (const char *file)
   int i;
   const struct extension_language_defn *extlang;
 
+  if (has_extension (file, extension_language_gdb.suffix))
+    return &extension_language_gdb;
+
   ALL_EXTENSION_LANGUAGES (i, extlang)
     {
       if (has_extension (file, extlang->suffix))
@@ -286,6 +291,21 @@ ext_lang_objfile_script_sourcer (const struct extension_language_defn *extlang)
   return extlang->script_ops->objfile_script_sourcer;
 }
 
+/* Return the objfile script "executor" function for EXTLANG.
+   This is the function that executes a script for a particular objfile.
+   If support for this language isn't compiled in, NULL is returned.
+   The extension language is not required to implement this function.  */
+
+objfile_script_executor_func *
+ext_lang_objfile_script_executor
+  (const struct extension_language_defn *extlang)
+{
+  if (extlang->script_ops == NULL)
+    return NULL;
+
+  return extlang->script_ops->objfile_script_executor;
+}
+
 /* Return non-zero if auto-loading of EXTLANG scripts is enabled.
    Zero is returned if support for this language isn't compiled in.  */
 
@@ -388,21 +408,16 @@ auto_load_ext_lang_scripts_for_objfile (struct objfile *objfile)
    We don't know in advance which extension language will provide a
    pretty-printer for the type, so all are initialized.  */
 
-struct ext_lang_type_printers *
-start_ext_lang_type_printers (void)
+ext_lang_type_printers::ext_lang_type_printers ()
 {
-  struct ext_lang_type_printers *printers
-    = XCNEW (struct ext_lang_type_printers);
   int i;
   const struct extension_language_defn *extlang;
 
   ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
     {
       if (extlang->ops->start_type_printers != NULL)
-       extlang->ops->start_type_printers (extlang, printers);
+       extlang->ops->start_type_printers (extlang, this);
     }
-
-  return printers;
 }
 
 /* Iteratively try the type pretty-printers specified by PRINTERS
@@ -443,11 +458,7 @@ apply_ext_lang_type_printers (struct ext_lang_type_printers *printers,
   return NULL;
 }
 
-/* Call this after pretty-printing a type to release all memory held
-   by PRINTERS.  */
-
-void
-free_ext_lang_type_printers (struct ext_lang_type_printers *printers)
+ext_lang_type_printers::~ext_lang_type_printers ()
 {
   int i;
   const struct extension_language_defn *extlang;
@@ -455,17 +466,15 @@ free_ext_lang_type_printers (struct ext_lang_type_printers *printers)
   ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
     {
       if (extlang->ops->free_type_printers != NULL)
-       extlang->ops->free_type_printers (extlang, printers);
+       extlang->ops->free_type_printers (extlang, this);
     }
-
-  xfree (printers);
 }
 \f
-/* Try to pretty-print a value of type TYPE located at VALADDR
-   + EMBEDDED_OFFSET, which came from the inferior at address ADDRESS
-   + EMBEDDED_OFFSET, onto stdio stream STREAM according to OPTIONS.
-   VAL is the whole object that came from ADDRESS.  VALADDR must point to
-   the head of VAL's contents buffer.
+/* Try to pretty-print a value of type TYPE located at VAL's contents
+   buffer + EMBEDDED_OFFSET, which came from the inferior at address
+   ADDRESS + EMBEDDED_OFFSET, onto stdio stream STREAM according to
+   OPTIONS.
+   VAL is the whole object that came from ADDRESS.
    Returns non-zero if the value was successfully pretty-printed.
 
    Extension languages are tried in the order specified by
@@ -479,10 +488,10 @@ free_ext_lang_type_printers (struct ext_lang_type_printers *printers)
    errors that trigger an exception in the extension language.  */
 
 int
-apply_ext_lang_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
-                                  int embedded_offset, CORE_ADDR address,
+apply_ext_lang_val_pretty_printer (struct type *type,
+                                  LONGEST embedded_offset, CORE_ADDR address,
                                   struct ui_file *stream, int recurse,
-                                  const struct value *val,
+                                  struct value *val,
                                   const struct value_print_options *options,
                                   const struct language_defn *language)
 {
@@ -495,7 +504,7 @@ apply_ext_lang_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
 
       if (extlang->ops->apply_val_pretty_printer == NULL)
        continue;
-      rc = extlang->ops->apply_val_pretty_printer (extlang, type, valaddr,
+      rc = extlang->ops->apply_val_pretty_printer (extlang, type,
                                                   embedded_offset, address,
                                                   stream, recurse, val,
                                                   options, language);
@@ -536,7 +545,8 @@ apply_ext_lang_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
    rather than trying filters in other extension languages.  */
 
 enum ext_lang_bt_status
-apply_ext_lang_frame_filter (struct frame_info *frame, int flags,
+apply_ext_lang_frame_filter (struct frame_info *frame,
+                            frame_filter_flags flags,
                             enum ext_lang_frame_args args_type,
                             struct ui_out *out,
                             int frame_low, int frame_high)
@@ -691,7 +701,7 @@ static void
 install_gdb_sigint_handler (struct signal_handler *previous)
 {
   /* Save here to simplify comparison.  */
-  RETSIGTYPE (*handle_sigint_for_compare) () = handle_sigint;
+  sighandler_t handle_sigint_for_compare = handle_sigint;
 
   previous->handler = signal (SIGINT, handle_sigint);
   if (previous->handler != handle_sigint_for_compare)
@@ -730,19 +740,24 @@ set_active_ext_lang (const struct extension_language_defn *now_active)
     = XCNEW (struct active_ext_lang_state);
 
   previous->ext_lang = active_ext_lang;
+  previous->sigint_handler.handler_saved = 0;
   active_ext_lang = now_active;
 
-  /* If the newly active extension language uses cooperative SIGINT handling
-     then ensure GDB's SIGINT handler is installed.  */
-  if (now_active->language == EXT_LANG_GDB
-      || now_active->ops->check_quit_flag != NULL)
-    install_gdb_sigint_handler (&previous->sigint_handler);
-
-  /* If there's a SIGINT recorded in the cooperative extension languages,
-     move it to the new language, or save it in GDB's global flag if the newly
-     active extension language doesn't use cooperative SIGINT handling.  */
-  if (check_quit_flag ())
-    set_quit_flag ();
+  if (target_terminal::is_ours ())
+    {
+      /* If the newly active extension language uses cooperative SIGINT
+        handling then ensure GDB's SIGINT handler is installed.  */
+      if (now_active->language == EXT_LANG_GDB
+         || now_active->ops->check_quit_flag != NULL)
+       install_gdb_sigint_handler (&previous->sigint_handler);
+
+      /* If there's a SIGINT recorded in the cooperative extension languages,
+        move it to the new language, or save it in GDB's global flag if the
+        newly active extension language doesn't use cooperative SIGINT
+        handling.  */
+      if (check_quit_flag ())
+       set_quit_flag ();
+    }
 
   return previous;
 }
@@ -752,40 +767,22 @@ set_active_ext_lang (const struct extension_language_defn *now_active)
 void
 restore_active_ext_lang (struct active_ext_lang_state *previous)
 {
-  const struct extension_language_defn *current = active_ext_lang;
-
   active_ext_lang = previous->ext_lang;
 
-  /* Restore the previous SIGINT handler if one was saved.  */
-  if (previous->sigint_handler.handler_saved)
-    install_sigint_handler (&previous->sigint_handler);
-
-  /* If there's a SIGINT recorded in the cooperative extension languages,
-     move it to the new language, or save it in GDB's global flag if the newly
-     active extension language doesn't use cooperative SIGINT handling.  */
-  if (check_quit_flag ())
-    set_quit_flag ();
-
-  xfree (previous);
-}
-
-/* Clear the quit flag.
-   The flag is cleared in all extension languages,
-   not just the currently active one.  */
-
-void
-clear_quit_flag (void)
-{
-  int i;
-  const struct extension_language_defn *extlang;
-
-  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+  if (target_terminal::is_ours ())
     {
-      if (extlang->ops->clear_quit_flag != NULL)
-       extlang->ops->clear_quit_flag (extlang);
+      /* Restore the previous SIGINT handler if one was saved.  */
+      if (previous->sigint_handler.handler_saved)
+       install_sigint_handler (&previous->sigint_handler);
+
+      /* If there's a SIGINT recorded in the cooperative extension languages,
+        move it to the new language, or save it in GDB's global flag if the
+        newly active extension language doesn't use cooperative SIGINT
+        handling.  */
+      if (check_quit_flag ())
+       set_quit_flag ();
     }
-
-  quit_flag = 0;
+  xfree (previous);
 }
 
 /* Set the quit flag.
@@ -803,7 +800,16 @@ set_quit_flag (void)
       && active_ext_lang->ops->set_quit_flag != NULL)
     active_ext_lang->ops->set_quit_flag (active_ext_lang);
   else
-    quit_flag = 1;
+    {
+      quit_flag = 1;
+
+      /* Now wake up the event loop, or any interruptible_select.  Do
+        this after setting the flag, because signals on Windows
+        actually run on a separate thread, and thus otherwise the
+        main code could be woken up and find quit_flag still
+        clear.  */
+      quit_serial_event_set ();
+    }
 }
 
 /* Return true if the quit flag has been set, false otherwise.
@@ -827,13 +833,76 @@ check_quit_flag (void)
   /* This is written in a particular way to avoid races.  */
   if (quit_flag)
     {
+      /* No longer need to wake up the event loop or any
+        interruptible_select.  The caller handles the quit
+        request.  */
+      quit_serial_event_clear ();
       quit_flag = 0;
       result = 1;
     }
 
   return result;
 }
-\f
+
+/* See extension.h.  */
+
+void
+get_matching_xmethod_workers (struct type *type, const char *method_name,
+                             std::vector<xmethod_worker_up> *workers)
+{
+  int i;
+  const struct extension_language_defn *extlang;
+
+  ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
+    {
+      enum ext_lang_rc rc;
+
+      /* If an extension language does not support xmethods, ignore
+        it.  */
+      if (extlang->ops->get_matching_xmethod_workers == NULL)
+       continue;
+
+      rc = extlang->ops->get_matching_xmethod_workers (extlang,
+                                                      type, method_name,
+                                                      workers);
+      if (rc == EXT_LANG_RC_ERROR)
+       error (_("Error while looking for matching xmethod workers "
+                "defined in %s."), extlang->capitalized_name);
+    }
+}
+
+/* See extension.h.  */
+
+std::vector<type *>
+xmethod_worker::get_arg_types ()
+{
+  std::vector<type *> type_array;
+
+  ext_lang_rc rc = do_get_arg_types (&type_array);
+  if (rc == EXT_LANG_RC_ERROR)
+    error (_("Error while looking for arg types of a xmethod worker "
+            "defined in %s."), m_extlang->capitalized_name);
+
+  return type_array;
+}
+
+/* See extension.h.  */
+
+struct type *
+xmethod_worker::get_result_type (value *object, gdb::array_view<value *> args)
+{
+  type *result_type;
+
+  ext_lang_rc rc = do_get_result_type (object, args, &result_type);
+  if (rc == EXT_LANG_RC_ERROR)
+    {
+      error (_("Error while fetching result type of an xmethod worker "
+              "defined in %s."), m_extlang->capitalized_name);
+    }
+
+  return result_type;
+}
+
 /* Called via an observer before gdb prints its prompt.
    Iterate over the extension languages giving them a chance to
    change the prompt.  The first one to change the prompt wins,
@@ -865,10 +934,8 @@ ext_lang_before_prompt (const char *current_gdb_prompt)
     }
 }
 
-extern initialize_file_ftype _initialize_extension;
-
 void
 _initialize_extension (void)
 {
-  observer_attach_before_prompt (ext_lang_before_prompt);
+  gdb::observers::before_prompt.attach (ext_lang_before_prompt);
 }
This page took 0.028967 seconds and 4 git commands to generate.