+int
+compare_positive_ints (const void *ap, const void *bp)
+{
+ /* Because we know we're comparing two ints which are positive,
+ there's no danger of overflow here. */
+ return * (int *) ap - * (int *) bp;
+}
+
+/* String compare function for qsort. */
+
+int
+compare_strings (const void *arg1, const void *arg2)
+{
+ const char **s1 = (const char **) arg1;
+ const char **s2 = (const char **) arg2;
+
+ return strcmp (*s1, *s2);
+}
+
+#define AMBIGUOUS_MESS1 ".\nMatching formats:"
+#define AMBIGUOUS_MESS2 \
+ ".\nUse \"set gnutarget format-name\" to specify the format."
+
+const char *
+gdb_bfd_errmsg (bfd_error_type error_tag, char **matching)
+{
+ char *ret, *retp;
+ int ret_len;
+ char **p;
+
+ /* Check if errmsg just need simple return. */
+ if (error_tag != bfd_error_file_ambiguously_recognized || matching == NULL)
+ return bfd_errmsg (error_tag);
+
+ ret_len = strlen (bfd_errmsg (error_tag)) + strlen (AMBIGUOUS_MESS1)
+ + strlen (AMBIGUOUS_MESS2);
+ for (p = matching; *p; p++)
+ ret_len += strlen (*p) + 1;
+ ret = xmalloc (ret_len + 1);
+ retp = ret;
+ make_cleanup (xfree, ret);
+
+ strcpy (retp, bfd_errmsg (error_tag));
+ retp += strlen (retp);
+
+ strcpy (retp, AMBIGUOUS_MESS1);
+ retp += strlen (retp);
+
+ for (p = matching; *p; p++)
+ {
+ sprintf (retp, " %s", *p);
+ retp += strlen (retp);
+ }
+ xfree (matching);
+
+ strcpy (retp, AMBIGUOUS_MESS2);
+
+ return ret;
+}
+
+/* Return ARGS parsed as a valid pid, or throw an error. */
+
+int
+parse_pid_to_attach (char *args)
+{
+ unsigned long pid;
+ char *dummy;
+
+ if (!args)
+ error_no_arg (_("process-id to attach"));
+
+ dummy = args;
+ pid = strtoul (args, &dummy, 0);
+ /* Some targets don't set errno on errors, grrr! */
+ if ((pid == 0 && dummy == args) || dummy != &args[strlen (args)])
+ error (_("Illegal process-id: %s."), 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;
+}
+
+#ifdef HAVE_WAITPID
+
+#ifdef SIGALRM
+
+/* SIGALRM handler for waitpid_with_timeout. */
+
+static void
+sigalrm_handler (int signo)
+{
+ /* Nothing to do. */
+}
+
+#endif
+
+/* Wrapper to wait for child PID to die with TIMEOUT.
+ TIMEOUT is the time to stop waiting in seconds.
+ If TIMEOUT is zero, pass WNOHANG to waitpid.
+ Returns PID if it was successfully waited for, otherwise -1.
+
+ Timeouts are currently implemented with alarm and SIGALRM.
+ If the host does not support them, this waits "forever".
+ It would be odd though for a host to have waitpid and not SIGALRM. */
+
+pid_t
+wait_to_die_with_timeout (pid_t pid, int *status, int timeout)
+{
+ pid_t waitpid_result;
+
+ gdb_assert (pid > 0);
+ gdb_assert (timeout >= 0);
+
+ if (timeout > 0)
+ {
+#ifdef SIGALRM
+#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
+ struct sigaction sa, old_sa;
+
+ sa.sa_handler = sigalrm_handler;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction (SIGALRM, &sa, &old_sa);
+#else
+ void (*ofunc) ();
+
+ ofunc = (void (*)()) signal (SIGALRM, sigalrm_handler);
+#endif
+
+ alarm (timeout);
+#endif
+
+ waitpid_result = waitpid (pid, status, 0);
+
+#ifdef SIGALRM
+ alarm (0);
+#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
+ sigaction (SIGALRM, &old_sa, NULL);
+#else
+ signal (SIGALRM, ofunc);
+#endif
+#endif
+ }
+ else
+ waitpid_result = waitpid (pid, status, WNOHANG);
+
+ if (waitpid_result == pid)
+ return pid;
+ else
+ return -1;
+}
+
+#endif /* HAVE_WAITPID */
+