Run --gc-sections tests only if supported.
[deliverable/binutils-gdb.git] / gdb / utils.c
index 11c34bf7bd9e7e82c55d9d3094294437320805ca..21682d0e8e527ff8caffb9c27fb8732cc532be75 100644 (file)
@@ -431,6 +431,39 @@ make_cleanup_restore_ui_file (struct ui_file **variable)
   return make_cleanup_dtor (do_restore_ui_file, (void *) c, xfree);
 }
 
+/* Helper for make_cleanup_value_free_to_mark.  */
+
+static void
+do_value_free_to_mark (void *value)
+{
+  value_free_to_mark ((struct value *) value);
+}
+
+/* Free all values allocated since MARK was obtained by value_mark
+   (except for those released) when the cleanup is run.  */
+
+struct cleanup *
+make_cleanup_value_free_to_mark (struct value *mark)
+{
+  return make_my_cleanup (&cleanup_chain, do_value_free_to_mark, mark);
+}
+
+/* Helper for make_cleanup_value_free.  */
+
+static void
+do_value_free (void *value)
+{
+  value_free (value);
+}
+
+/* Free VALUE.  */
+
+struct cleanup *
+make_cleanup_value_free (struct value *value)
+{
+  return make_my_cleanup (&cleanup_chain, do_value_free, value);
+}
+
 struct cleanup *
 make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
                  void *arg,  void (*free_arg) (void *))
@@ -685,268 +718,6 @@ make_command_stats_cleanup (int msg_type)
 
   return make_cleanup_dtor (report_command_stats, new_stat, xfree);
 }
-
-/* Continuations are implemented as cleanups internally.  Inherit from
-   cleanups.  */
-struct continuation
-{
-  struct cleanup base;
-};
-
-/* Add a continuation to the continuation list of THREAD.  The new
-   continuation will be added at the front.  */
-void
-add_continuation (struct thread_info *thread,
-                 void (*continuation_hook) (void *), void *args,
-                 void (*continuation_free_args) (void *))
-{
-  struct cleanup *as_cleanup = &thread->continuations->base;
-  make_cleanup_ftype *continuation_hook_fn = continuation_hook;
-
-  make_my_cleanup2 (&as_cleanup,
-                   continuation_hook_fn,
-                   args,
-                   continuation_free_args);
-
-  thread->continuations = (struct continuation *) as_cleanup;
-}
-
-/* Add a continuation to the continuation list of INFERIOR.  The new
-   continuation will be added at the front.  */
-
-void
-add_inferior_continuation (void (*continuation_hook) (void *), void *args,
-                          void (*continuation_free_args) (void *))
-{
-  struct inferior *inf = current_inferior ();
-  struct cleanup *as_cleanup = &inf->continuations->base;
-  make_cleanup_ftype *continuation_hook_fn = continuation_hook;
-
-  make_my_cleanup2 (&as_cleanup,
-                   continuation_hook_fn,
-                   args,
-                   continuation_free_args);
-
-  inf->continuations = (struct continuation *) as_cleanup;
-}
-
-/* Do all continuations of the current inferior.  */
-
-void
-do_all_inferior_continuations (void)
-{
-  struct cleanup *as_cleanup;
-  struct inferior *inf = current_inferior ();
-
-  if (inf->continuations == NULL)
-    return;
-
-  /* Copy the list header into another pointer, and set the global
-     list header to null, so that the global list can change as a side
-     effect of invoking the continuations and the processing of the
-     preexisting continuations will not be affected.  */
-
-  as_cleanup = &inf->continuations->base;
-  inf->continuations = NULL;
-
-  /* Work now on the list we have set aside.  */
-  do_my_cleanups (&as_cleanup, NULL);
-}
-
-/* Get rid of all the inferior-wide continuations of INF.  */
-
-void
-discard_all_inferior_continuations (struct inferior *inf)
-{
-  struct cleanup *continuation_ptr = &inf->continuations->base;
-
-  discard_my_cleanups (&continuation_ptr, NULL);
-  inf->continuations = NULL;
-}
-
-static void
-restore_thread_cleanup (void *arg)
-{
-  ptid_t *ptid_p = arg;
-
-  switch_to_thread (*ptid_p);
-}
-
-/* Walk down the continuation list of PTID, and execute all the
-   continuations.  There is a problem though.  In some cases new
-   continuations may be added while we are in the middle of this loop.
-   If this happens they will be added in the front, and done before we
-   have a chance of exhausting those that were already there.  We need
-   to then save the beginning of the list in a pointer and do the
-   continuations from there on, instead of using the global beginning
-   of list as our iteration pointer.  */
-static void
-do_all_continuations_ptid (ptid_t ptid,
-                          struct continuation **continuations_p)
-{
-  struct cleanup *old_chain;
-  ptid_t current_thread;
-  struct cleanup *as_cleanup;
-
-  if (*continuations_p == NULL)
-    return;
-
-  current_thread = inferior_ptid;
-
-  /* Restore selected thread on exit.  Don't try to restore the frame
-     as well, because:
-
-    - When running continuations, the selected frame is always #0.
-
-    - The continuations may trigger symbol file loads, which may
-      change the frame layout (frame ids change), which would trigger
-      a warning if we used make_cleanup_restore_current_thread.  */
-
-  old_chain = make_cleanup (restore_thread_cleanup, &current_thread);
-
-  /* Let the continuation see this thread as selected.  */
-  switch_to_thread (ptid);
-
-  /* Copy the list header into another pointer, and set the global
-     list header to null, so that the global list can change as a side
-     effect of invoking the continuations and the processing of the
-     preexisting continuations will not be affected.  */
-
-  as_cleanup = &(*continuations_p)->base;
-  *continuations_p = NULL;
-
-  /* Work now on the list we have set aside.  */
-  do_my_cleanups (&as_cleanup, NULL);
-
-  do_cleanups (old_chain);
-}
-
-/* Callback for iterate over threads.  */
-static int
-do_all_continuations_thread_callback (struct thread_info *thread, void *data)
-{
-  do_all_continuations_ptid (thread->ptid, &thread->continuations);
-  return 0;
-}
-
-/* Do all continuations of thread THREAD.  */
-void
-do_all_continuations_thread (struct thread_info *thread)
-{
-  do_all_continuations_thread_callback (thread, NULL);
-}
-
-/* Do all continuations of all threads.  */
-void
-do_all_continuations (void)
-{
-  iterate_over_threads (do_all_continuations_thread_callback, NULL);
-}
-
-/* Callback for iterate over threads.  */
-static int
-discard_all_continuations_thread_callback (struct thread_info *thread,
-                                          void *data)
-{
-  struct cleanup *continuation_ptr = &thread->continuations->base;
-
-  discard_my_cleanups (&continuation_ptr, NULL);
-  thread->continuations = NULL;
-  return 0;
-}
-
-/* Get rid of all the continuations of THREAD.  */
-void
-discard_all_continuations_thread (struct thread_info *thread)
-{
-  discard_all_continuations_thread_callback (thread, NULL);
-}
-
-/* Get rid of all the continuations of all threads.  */
-void
-discard_all_continuations (void)
-{
-  iterate_over_threads (discard_all_continuations_thread_callback, NULL);
-}
-
-
-/* Add a continuation to the intermediate continuation list of THREAD.
-   The new continuation will be added at the front.  */
-void
-add_intermediate_continuation (struct thread_info *thread,
-                              void (*continuation_hook)
-                              (void *), void *args,
-                              void (*continuation_free_args) (void *))
-{
-  struct cleanup *as_cleanup = &thread->intermediate_continuations->base;
-  make_cleanup_ftype *continuation_hook_fn = continuation_hook;
-
-  make_my_cleanup2 (&as_cleanup,
-                   continuation_hook_fn,
-                   args,
-                   continuation_free_args);
-
-  thread->intermediate_continuations = (struct continuation *) as_cleanup;
-}
-
-/* Walk down the cmd_continuation list, and execute all the
-   continuations.  There is a problem though.  In some cases new
-   continuations may be added while we are in the middle of this
-   loop.  If this happens they will be added in the front, and done
-   before we have a chance of exhausting those that were already
-   there.  We need to then save the beginning of the list in a pointer
-   and do the continuations from there on, instead of using the
-   global beginning of list as our iteration pointer.  */
-static int
-do_all_intermediate_continuations_thread_callback (struct thread_info *thread,
-                                                  void *data)
-{
-  do_all_continuations_ptid (thread->ptid,
-                            &thread->intermediate_continuations);
-  return 0;
-}
-
-/* Do all intermediate continuations of thread THREAD.  */
-void
-do_all_intermediate_continuations_thread (struct thread_info *thread)
-{
-  do_all_intermediate_continuations_thread_callback (thread, NULL);
-}
-
-/* Do all intermediate continuations of all threads.  */
-void
-do_all_intermediate_continuations (void)
-{
-  iterate_over_threads (do_all_intermediate_continuations_thread_callback,
-                       NULL);
-}
-
-/* Callback for iterate over threads.  */
-static int
-discard_all_intermediate_continuations_thread_callback (struct thread_info *thread,
-                                                       void *data)
-{
-  struct cleanup *continuation_ptr = &thread->intermediate_continuations->base;
-
-  discard_my_cleanups (&continuation_ptr, NULL);
-  thread->intermediate_continuations = NULL;
-  return 0;
-}
-
-/* Get rid of all the intermediate continuations of THREAD.  */
-void
-discard_all_intermediate_continuations_thread (struct thread_info *thread)
-{
-  discard_all_intermediate_continuations_thread_callback (thread, NULL);
-}
-
-/* Get rid of all the intermediate continuations of all threads.  */
-void
-discard_all_intermediate_continuations (void)
-{
-  iterate_over_threads (discard_all_intermediate_continuations_thread_callback,
-                       NULL);
-}
 \f
 
 
@@ -1439,7 +1210,7 @@ quit (void)
    memory requested in SIZE.  */
 
 void
-nomem (long size)
+malloc_failure (long size)
 {
   if (size > 0)
     {
@@ -1453,146 +1224,6 @@ nomem (long size)
     }
 }
 
-/* The xmalloc() (libiberty.h) family of memory management routines.
-
-   These are like the ISO-C malloc() family except that they implement
-   consistent semantics and guard against typical memory management
-   problems.  */
-
-/* NOTE: These are declared using PTR to ensure consistency with
-   "libiberty.h".  xfree() is GDB local.  */
-
-PTR                            /* ARI: PTR */
-xmalloc (size_t size)
-{
-  void *val;
-
-  /* See libiberty/xmalloc.c.  This function need's to match that's
-     semantics.  It never returns NULL.  */
-  if (size == 0)
-    size = 1;
-
-  val = malloc (size);         /* ARI: malloc */
-  if (val == NULL)
-    nomem (size);
-
-  return (val);
-}
-
-void *
-xzalloc (size_t size)
-{
-  return xcalloc (1, size);
-}
-
-PTR                            /* ARI: PTR */
-xrealloc (PTR ptr, size_t size)        /* ARI: PTR */
-{
-  void *val;
-
-  /* See libiberty/xmalloc.c.  This function need's to match that's
-     semantics.  It never returns NULL.  */
-  if (size == 0)
-    size = 1;
-
-  if (ptr != NULL)
-    val = realloc (ptr, size); /* ARI: realloc */
-  else
-    val = malloc (size);               /* ARI: malloc */
-  if (val == NULL)
-    nomem (size);
-
-  return (val);
-}
-
-PTR                            /* ARI: PTR */
-xcalloc (size_t number, size_t size)
-{
-  void *mem;
-
-  /* See libiberty/xmalloc.c.  This function need's to match that's
-     semantics.  It never returns NULL.  */
-  if (number == 0 || size == 0)
-    {
-      number = 1;
-      size = 1;
-    }
-
-  mem = calloc (number, size);         /* ARI: xcalloc */
-  if (mem == NULL)
-    nomem (number * size);
-
-  return mem;
-}
-
-void
-xfree (void *ptr)
-{
-  if (ptr != NULL)
-    free (ptr);                /* ARI: free */
-}
-\f
-
-/* Like asprintf/vasprintf but get an internal_error if the call
-   fails.  */
-
-char *
-xstrprintf (const char *format, ...)
-{
-  char *ret;
-  va_list args;
-
-  va_start (args, format);
-  ret = xstrvprintf (format, args);
-  va_end (args);
-  return ret;
-}
-
-void
-xasprintf (char **ret, const char *format, ...)
-{
-  va_list args;
-
-  va_start (args, format);
-  (*ret) = xstrvprintf (format, args);
-  va_end (args);
-}
-
-void
-xvasprintf (char **ret, const char *format, va_list ap)
-{
-  (*ret) = xstrvprintf (format, ap);
-}
-
-char *
-xstrvprintf (const char *format, va_list ap)
-{
-  char *ret = NULL;
-  int status = vasprintf (&ret, format, ap);
-
-  /* NULL is returned when there was a memory allocation problem, or
-     any other error (for instance, a bad format string).  A negative
-     status (the printed length) with a non-NULL buffer should never
-     happen, but just to be sure.  */
-  if (ret == NULL || status < 0)
-    internal_error (__FILE__, __LINE__, _("vasprintf call failed"));
-  return ret;
-}
-
-int
-xsnprintf (char *str, size_t size, const char *format, ...)
-{
-  va_list args;
-  int ret;
-
-  va_start (args, format);
-  ret = vsnprintf (str, size, format, args);
-  gdb_assert (ret < size);
-  va_end (args);
-
-  return ret;
-}
-
 /* My replacement for the read system call.
    Used like `read' but keeps going if `read' returns too soon.  */
 
@@ -1614,7 +1245,7 @@ myread (int desc, char *addr, int len)
     }
   return orglen;
 }
-\f
+
 /* Make a copy of the string at PTR with SIZE characters
    (and add a null character at the end in the copy).
    Uses malloc to get the space.  Returns the address of the copy.  */
@@ -2500,8 +2131,8 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
 
   /* Don't do any filtering if it is disabled.  */
   if (stream != gdb_stdout
-      || ! pagination_enabled
-      || ! input_from_terminal_p ()
+      || !pagination_enabled
+      || batch_flag
       || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)
       || top_level_interpreter () == NULL
       || ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))
@@ -2974,10 +2605,12 @@ strcmp_iw (const char *string1, const char *string2)
        {
          string2++;
        }
-      if (*string1 != *string2)
-       {
-         break;
-       }
+      if (case_sensitivity == case_sensitive_on && *string1 != *string2)
+       break;
+      if (case_sensitivity == case_sensitive_off
+         && (tolower ((unsigned char) *string1)
+             != tolower ((unsigned char) *string2)))
+       break;
       if (*string1 != '\0')
        {
          string1++;
@@ -2998,6 +2631,10 @@ strcmp_iw (const char *string1, const char *string2)
    strcmp_iw(LIST_ELT, NAME), then the place to start looking is right
    where this function would put NAME.
 
+   This function must be neutral to the CASE_SENSITIVITY setting as the user
+   may choose it during later lookup.  Therefore this function always sorts
+   primarily case-insensitively and secondarily case-sensitively.
+
    Here are some examples of why using strcmp to sort is a bad idea:
 
    Whitespace example:
@@ -3023,47 +2660,78 @@ strcmp_iw (const char *string1, const char *string2)
 int
 strcmp_iw_ordered (const char *string1, const char *string2)
 {
-  while ((*string1 != '\0') && (*string2 != '\0'))
+  const char *saved_string1 = string1, *saved_string2 = string2;
+  enum case_sensitivity case_pass = case_sensitive_off;
+
+  for (;;)
     {
-      while (isspace (*string1))
-       {
-         string1++;
-       }
-      while (isspace (*string2))
-       {
-         string2++;
-       }
-      if (*string1 != *string2)
+      /* C1 and C2 are valid only if *string1 != '\0' && *string2 != '\0'.
+        Provide stub characters if we are already at the end of one of the
+        strings.  */
+      char c1 = 'X', c2 = 'X';
+
+      while (*string1 != '\0' && *string2 != '\0')
        {
-         break;
+         while (isspace (*string1))
+           string1++;
+         while (isspace (*string2))
+           string2++;
+
+         switch (case_pass)
+         {
+           case case_sensitive_off:
+             c1 = tolower ((unsigned char) *string1);
+             c2 = tolower ((unsigned char) *string2);
+             break;
+           case case_sensitive_on:
+             c1 = *string1;
+             c2 = *string2;
+             break;
+         }
+         if (c1 != c2)
+           break;
+
+         if (*string1 != '\0')
+           {
+             string1++;
+             string2++;
+           }
        }
-      if (*string1 != '\0')
+
+      switch (*string1)
        {
-         string1++;
-         string2++;
+         /* Characters are non-equal unless they're both '\0'; we want to
+            make sure we get the comparison right according to our
+            comparison in the cases where one of them is '\0' or '('.  */
+       case '\0':
+         if (*string2 == '\0')
+           break;
+         else
+           return -1;
+       case '(':
+         if (*string2 == '\0')
+           return 1;
+         else
+           return -1;
+       default:
+         if (*string2 == '\0' || *string2 == '(')
+           return 1;
+         else if (c1 > c2)
+           return 1;
+         else if (c1 < c2)
+           return -1;
+         /* PASSTHRU */
        }
-    }
 
-  switch (*string1)
-    {
-      /* Characters are non-equal unless they're both '\0'; we want to
-        make sure we get the comparison right according to our
-        comparison in the cases where one of them is '\0' or '('.  */
-    case '\0':
-      if (*string2 == '\0')
+      if (case_pass == case_sensitive_on)
        return 0;
-      else
-       return -1;
-    case '(':
-      if (*string2 == '\0')
-       return 1;
-      else
-       return -1;
-    default:
-      if (*string2 == '(')
-       return 1;
-      else
-       return *string1 - *string2;
+      
+      /* Otherwise the strings were equal in case insensitive way, make
+        a more fine grained comparison in a case sensitive way.  */
+
+      case_pass = case_sensitive_on;
+      string1 = saved_string1;
+      string2 = saved_string2;
     }
 }
 
@@ -3933,7 +3601,7 @@ gdb_buildargv (const char *s)
   char **argv = buildargv (s);
 
   if (s != NULL && argv == NULL)
-    nomem (0);
+    malloc_failure (0);
   return argv;
 }
 
@@ -4006,6 +3674,67 @@ parse_pid_to_attach (char *args)
   return pid;
 }
 
+/* Helper for make_bpstat_clear_actions_cleanup.  */
+
+static void
+do_bpstat_clear_actions_cleanup (void *unused)
+{
+  bpstat_clear_actions ();
+}
+
+/* Call bpstat_clear_actions for the case an exception is throw.  You should
+   discard_cleanups if no exception is caught.  */
+
+struct cleanup *
+make_bpstat_clear_actions_cleanup (void)
+{
+  return make_cleanup (do_bpstat_clear_actions_cleanup, NULL);
+}
+
+/* Check for GCC >= 4.x according to the symtab->producer string.  Return minor
+   version (x) of 4.x in such case.  If it is not GCC or it is GCC older than
+   4.x return -1.  If it is GCC 5.x or higher return INT_MAX.  */
+
+int
+producer_is_gcc_ge_4 (const char *producer)
+{
+  const char *cs;
+  int major, minor;
+
+  if (producer == NULL)
+    {
+      /* For unknown compilers expect their behavior is not compliant.  For GCC
+        this case can also happen for -gdwarf-4 type units supported since
+        gcc-4.5.  */
+
+      return -1;
+    }
+
+  /* Skip any identifier after "GNU " - such as "C++" or "Java".  */
+
+  if (strncmp (producer, "GNU ", strlen ("GNU ")) != 0)
+    {
+      /* For non-GCC compilers expect their behavior is not compliant.  */
+
+      return -1;
+    }
+  cs = &producer[strlen ("GNU ")];
+  while (*cs && !isdigit (*cs))
+    cs++;
+  if (sscanf (cs, "%d.%d", &major, &minor) != 2)
+    {
+      /* Not recognized as GCC.  */
+
+      return -1;
+    }
+
+  if (major < 4)
+    return -1;
+  if (major > 4)
+    return INT_MAX;
+  return minor;
+}
+
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 extern initialize_file_ftype _initialize_utils;
 
This page took 0.031693 seconds and 4 git commands to generate.