summaryrefslogtreecommitdiff
path: root/gdb/gdbsupport
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/gdbsupport')
-rw-r--r--gdb/gdbsupport/agent.c282
-rw-r--r--gdb/gdbsupport/agent.h68
-rw-r--r--gdb/gdbsupport/array-view.h259
-rw-r--r--gdb/gdbsupport/ax.def97
-rw-r--r--gdb/gdbsupport/break-common.h31
-rw-r--r--gdb/gdbsupport/btrace-common.c192
-rw-r--r--gdb/gdbsupport/btrace-common.h257
-rw-r--r--gdb/gdbsupport/buffer.c178
-rw-r--r--gdb/gdbsupport/buffer.h68
-rw-r--r--gdb/gdbsupport/byte-vector.h63
-rw-r--r--gdb/gdbsupport/cleanups.c144
-rw-r--r--gdb/gdbsupport/cleanups.h39
-rw-r--r--gdb/gdbsupport/common-debug.c37
-rw-r--r--gdb/gdbsupport/common-debug.h41
-rw-r--r--gdb/gdbsupport/common-defs.h150
-rw-r--r--gdb/gdbsupport/common-exceptions.c235
-rw-r--r--gdb/gdbsupport/common-exceptions.h304
-rw-r--r--gdb/gdbsupport/common-gdbthread.h25
-rw-r--r--gdb/gdbsupport/common-inferior.h41
-rw-r--r--gdb/gdbsupport/common-regcache.c36
-rw-r--r--gdb/gdbsupport/common-regcache.h85
-rw-r--r--gdb/gdbsupport/common-types.h66
-rw-r--r--gdb/gdbsupport/common-utils.c358
-rw-r--r--gdb/gdbsupport/common-utils.h181
-rw-r--r--gdb/gdbsupport/common.host36
-rw-r--r--gdb/gdbsupport/common.m448
-rwxr-xr-xgdb/gdbsupport/create-version.sh38
-rw-r--r--gdb/gdbsupport/def-vector.h36
-rw-r--r--gdb/gdbsupport/default-init-alloc.h67
-rw-r--r--gdb/gdbsupport/enum-flags.h221
-rw-r--r--gdb/gdbsupport/environ.c183
-rw-r--r--gdb/gdbsupport/environ.h103
-rw-r--r--gdb/gdbsupport/errors.c69
-rw-r--r--gdb/gdbsupport/errors.h90
-rw-r--r--gdb/gdbsupport/fileio.c255
-rw-r--r--gdb/gdbsupport/fileio.h73
-rw-r--r--gdb/gdbsupport/filestuff.c503
-rw-r--r--gdb/gdbsupport/filestuff.h142
-rw-r--r--gdb/gdbsupport/filtered-iterator.h87
-rw-r--r--gdb/gdbsupport/format.c350
-rw-r--r--gdb/gdbsupport/format.h96
-rw-r--r--gdb/gdbsupport/forward-scope-exit.h123
-rw-r--r--gdb/gdbsupport/function-view.h323
-rw-r--r--gdb/gdbsupport/gdb_assert.h59
-rw-r--r--gdb/gdbsupport/gdb_locale.h43
-rw-r--r--gdb/gdbsupport/gdb_optional.h219
-rw-r--r--gdb/gdbsupport/gdb_proc_service.h173
-rw-r--r--gdb/gdbsupport/gdb_ref_ptr.h228
-rw-r--r--gdb/gdbsupport/gdb_setjmp.h34
-rw-r--r--gdb/gdbsupport/gdb_signals.h58
-rw-r--r--gdb/gdbsupport/gdb_splay_tree.h42
-rw-r--r--gdb/gdbsupport/gdb_string_view.h562
-rw-r--r--gdb/gdbsupport/gdb_string_view.tcc219
-rw-r--r--gdb/gdbsupport/gdb_sys_time.h38
-rw-r--r--gdb/gdbsupport/gdb_tilde_expand.c95
-rw-r--r--gdb/gdbsupport/gdb_tilde_expand.h31
-rw-r--r--gdb/gdbsupport/gdb_unique_ptr.h67
-rw-r--r--gdb/gdbsupport/gdb_unlinker.h60
-rw-r--r--gdb/gdbsupport/gdb_vecs.c88
-rw-r--r--gdb/gdbsupport/gdb_vecs.h89
-rw-r--r--gdb/gdbsupport/gdb_wait.h113
-rw-r--r--gdb/gdbsupport/hash_enum.h45
-rw-r--r--gdb/gdbsupport/host-defs.h61
-rw-r--r--gdb/gdbsupport/job-control.c86
-rw-r--r--gdb/gdbsupport/job-control.h38
-rw-r--r--gdb/gdbsupport/mingw-strerror.c64
-rw-r--r--gdb/gdbsupport/netstuff.c154
-rw-r--r--gdb/gdbsupport/netstuff.h76
-rw-r--r--gdb/gdbsupport/new-op.c95
-rw-r--r--gdb/gdbsupport/next-iterator.h102
-rw-r--r--gdb/gdbsupport/observable.h119
-rw-r--r--gdb/gdbsupport/offset-type.h133
-rw-r--r--gdb/gdbsupport/pathstuff.c290
-rw-r--r--gdb/gdbsupport/pathstuff.h95
-rw-r--r--gdb/gdbsupport/poison.h248
-rw-r--r--gdb/gdbsupport/posix-strerror.c38
-rw-r--r--gdb/gdbsupport/preprocessor.h35
-rw-r--r--gdb/gdbsupport/print-utils.c326
-rw-r--r--gdb/gdbsupport/print-utils.h82
-rw-r--r--gdb/gdbsupport/ptid.c26
-rw-r--r--gdb/gdbsupport/ptid.h155
-rw-r--r--gdb/gdbsupport/refcounted-object.h70
-rw-r--r--gdb/gdbsupport/rsp-low.c307
-rw-r--r--gdb/gdbsupport/rsp-low.h101
-rw-r--r--gdb/gdbsupport/run-time-clock.c58
-rw-r--r--gdb/gdbsupport/run-time-clock.h75
-rw-r--r--gdb/gdbsupport/safe-iterator.h93
-rw-r--r--gdb/gdbsupport/scope-exit.h186
-rw-r--r--gdb/gdbsupport/scoped_fd.h87
-rw-r--r--gdb/gdbsupport/scoped_mmap.c49
-rw-r--r--gdb/gdbsupport/scoped_mmap.h94
-rw-r--r--gdb/gdbsupport/scoped_restore.h118
-rw-r--r--gdb/gdbsupport/selftest.c111
-rw-r--r--gdb/gdbsupport/selftest.h73
-rw-r--r--gdb/gdbsupport/signals-state-save-restore.c117
-rw-r--r--gdb/gdbsupport/signals-state-save-restore.h40
-rw-r--r--gdb/gdbsupport/signals.c653
-rw-r--r--gdb/gdbsupport/symbol.h37
-rw-r--r--gdb/gdbsupport/tdesc.c401
-rw-r--r--gdb/gdbsupport/tdesc.h408
-rw-r--r--gdb/gdbsupport/traits.h109
-rw-r--r--gdb/gdbsupport/underlying.h32
-rw-r--r--gdb/gdbsupport/valid-expr.h108
-rw-r--r--gdb/gdbsupport/vec.c118
-rw-r--r--gdb/gdbsupport/vec.h1150
-rw-r--r--gdb/gdbsupport/version.h31
-rw-r--r--gdb/gdbsupport/x86-xstate.h88
-rw-r--r--gdb/gdbsupport/xml-utils.c63
-rw-r--r--gdb/gdbsupport/xml-utils.h33
109 files changed, 15376 insertions, 0 deletions
diff --git a/gdb/gdbsupport/agent.c b/gdb/gdbsupport/agent.c
new file mode 100644
index 00000000000..02cad463699
--- /dev/null
+++ b/gdb/gdbsupport/agent.c
@@ -0,0 +1,282 @@
+/* Shared utility routines for GDB to interact with agent.
+
+ Copyright (C) 2009-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "target/target.h"
+#include "gdbsupport/symbol.h"
+#include <unistd.h>
+#include "filestuff.h"
+
+#define IPA_SYM_STRUCT_NAME ipa_sym_addresses_common
+#include "agent.h"
+
+int debug_agent = 0;
+
+/* A stdarg wrapper for debug_vprintf. */
+
+static void ATTRIBUTE_PRINTF (1, 2)
+debug_agent_printf (const char *fmt, ...)
+{
+ va_list ap;
+
+ if (!debug_agent)
+ return;
+ va_start (ap, fmt);
+ debug_vprintf (fmt, ap);
+ va_end (ap);
+}
+
+#define DEBUG_AGENT debug_agent_printf
+
+/* Global flag to determine using agent or not. */
+int use_agent = 0;
+
+/* Addresses of in-process agent's symbols both GDB and GDBserver cares
+ about. */
+
+struct ipa_sym_addresses_common
+{
+ CORE_ADDR addr_helper_thread_id;
+ CORE_ADDR addr_cmd_buf;
+ CORE_ADDR addr_capability;
+};
+
+/* Cache of the helper thread id. FIXME: this global should be made
+ per-process. */
+static uint32_t helper_thread_id = 0;
+
+static struct
+{
+ const char *name;
+ int offset;
+} symbol_list[] = {
+ IPA_SYM(helper_thread_id),
+ IPA_SYM(cmd_buf),
+ IPA_SYM(capability),
+};
+
+static struct ipa_sym_addresses_common ipa_sym_addrs;
+
+static int all_agent_symbols_looked_up = 0;
+
+int
+agent_loaded_p (void)
+{
+ return all_agent_symbols_looked_up;
+}
+
+/* Look up all symbols needed by agent. Return 0 if all the symbols are
+ found, return non-zero otherwise. */
+
+int
+agent_look_up_symbols (void *arg)
+{
+ int i;
+
+ all_agent_symbols_looked_up = 0;
+
+ for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
+ {
+ CORE_ADDR *addrp =
+ (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset);
+ struct objfile *objfile = (struct objfile *) arg;
+
+ if (find_minimal_symbol_address (symbol_list[i].name, addrp,
+ objfile) != 0)
+ {
+ DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name);
+ return -1;
+ }
+ }
+
+ all_agent_symbols_looked_up = 1;
+ return 0;
+}
+
+static unsigned int
+agent_get_helper_thread_id (void)
+{
+ if (helper_thread_id == 0)
+ {
+ if (target_read_uint32 (ipa_sym_addrs.addr_helper_thread_id,
+ &helper_thread_id))
+ warning (_("Error reading helper thread's id in lib"));
+ }
+
+ return helper_thread_id;
+}
+
+#ifdef HAVE_SYS_UN_H
+#include <sys/socket.h>
+#include <sys/un.h>
+#define SOCK_DIR P_tmpdir
+
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
+#endif
+
+#endif
+
+/* Connects to synchronization socket. PID is the pid of inferior, which is
+ used to set up the connection socket. */
+
+static int
+gdb_connect_sync_socket (int pid)
+{
+#ifdef HAVE_SYS_UN_H
+ struct sockaddr_un addr;
+ int res, fd;
+ char path[UNIX_PATH_MAX];
+
+ res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid);
+ if (res >= UNIX_PATH_MAX)
+ return -1;
+
+ res = fd = gdb_socket_cloexec (PF_UNIX, SOCK_STREAM, 0);
+ if (res == -1)
+ {
+ warning (_("error opening sync socket: %s"), strerror (errno));
+ return -1;
+ }
+
+ addr.sun_family = AF_UNIX;
+
+ res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
+ if (res >= UNIX_PATH_MAX)
+ {
+ warning (_("string overflow allocating socket name"));
+ close (fd);
+ return -1;
+ }
+
+ res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
+ if (res == -1)
+ {
+ warning (_("error connecting sync socket (%s): %s. "
+ "Make sure the directory exists and that it is writable."),
+ path, strerror (errno));
+ close (fd);
+ return -1;
+ }
+
+ return fd;
+#else
+ return -1;
+#endif
+}
+
+/* Execute an agent command in the inferior. PID is the value of pid of the
+ inferior. CMD is the buffer for command. GDB or GDBserver will store the
+ command into it and fetch the return result from CMD. The interaction
+ between GDB/GDBserver and the agent is synchronized by a synchronization
+ socket. Return zero if success, otherwise return non-zero. */
+
+int
+agent_run_command (int pid, const char *cmd, int len)
+{
+ int fd;
+ int tid = agent_get_helper_thread_id ();
+ ptid_t ptid = ptid_t (pid, tid, 0);
+
+ int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf,
+ (gdb_byte *) cmd, len);
+
+ if (ret != 0)
+ {
+ warning (_("unable to write"));
+ return -1;
+ }
+
+ DEBUG_AGENT ("agent: resumed helper thread\n");
+
+ /* Resume helper thread. */
+ target_continue_no_signal (ptid);
+
+ fd = gdb_connect_sync_socket (pid);
+ if (fd >= 0)
+ {
+ char buf[1] = "";
+
+ DEBUG_AGENT ("agent: signalling helper thread\n");
+
+ do
+ {
+ ret = write (fd, buf, 1);
+ } while (ret == -1 && errno == EINTR);
+
+ DEBUG_AGENT ("agent: waiting for helper thread's response\n");
+
+ do
+ {
+ ret = read (fd, buf, 1);
+ } while (ret == -1 && errno == EINTR);
+
+ close (fd);
+
+ DEBUG_AGENT ("agent: helper thread's response received\n");
+ }
+ else
+ return -1;
+
+ /* Need to read response with the inferior stopped. */
+ if (ptid != null_ptid)
+ {
+ /* Stop thread PTID. */
+ DEBUG_AGENT ("agent: stop helper thread\n");
+ target_stop_and_wait (ptid);
+ }
+
+ if (fd >= 0)
+ {
+ if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd,
+ IPA_CMD_BUF_SIZE))
+ {
+ warning (_("Error reading command response"));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/* Each bit of it stands for a capability of agent. */
+static uint32_t agent_capability = 0;
+
+/* Return true if agent has capability AGENT_CAP, otherwise return false. */
+
+int
+agent_capability_check (enum agent_capa agent_capa)
+{
+ if (agent_capability == 0)
+ {
+ if (target_read_uint32 (ipa_sym_addrs.addr_capability,
+ &agent_capability))
+ warning (_("Error reading capability of agent"));
+ }
+ return agent_capability & agent_capa;
+}
+
+/* Invalidate the cache of agent capability, so we'll read it from inferior
+ again. Call it when launches a new program or reconnect to remote stub. */
+
+void
+agent_capability_invalidate (void)
+{
+ agent_capability = 0;
+}
diff --git a/gdb/gdbsupport/agent.h b/gdb/gdbsupport/agent.h
new file mode 100644
index 00000000000..4f054987dd0
--- /dev/null
+++ b/gdb/gdbsupport/agent.h
@@ -0,0 +1,68 @@
+/* Shared utility routines for GDB to interact with agent.
+
+ Copyright (C) 2009-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_AGENT_H
+#define COMMON_AGENT_H
+
+#include "gdbsupport/preprocessor.h"
+
+int agent_run_command (int pid, const char *cmd, int len);
+
+int agent_look_up_symbols (void *);
+
+#define IPA_SYM_EXPORTED_NAME(SYM) gdb_agent_ ## SYM
+
+/* Define an entry in an IPA symbol list array. If IPA_SYM is used, the macro
+ IPA_SYM_STRUCT_NAME must be defined to the structure name holding the IPA
+ symbol addresses in that particular file, before including
+ gdbsupport/agent.h. */
+#define IPA_SYM(SYM) \
+ { \
+ STRINGIFY (IPA_SYM_EXPORTED_NAME (SYM)), \
+ offsetof (IPA_SYM_STRUCT_NAME, addr_ ## SYM) \
+ }
+
+/* The size in bytes of the buffer used to talk to the IPA helper
+ thread. */
+#define IPA_CMD_BUF_SIZE 1024
+
+int agent_loaded_p (void);
+
+extern int debug_agent;
+
+extern int use_agent;
+
+/* Capability of agent. Different agents may have different capabilities,
+ such as installing fast tracepoint or evaluating breakpoint conditions.
+ Capabilities are represented by bit-maps, and each capability occupies one
+ bit. */
+
+enum agent_capa
+{
+ /* Capability to install fast tracepoint. */
+ AGENT_CAPA_FAST_TRACE = 0x1,
+ /* Capability to install static tracepoint. */
+ AGENT_CAPA_STATIC_TRACE = (0x1 << 1),
+};
+
+int agent_capability_check (enum agent_capa);
+
+void agent_capability_invalidate (void);
+
+#endif /* COMMON_AGENT_H */
diff --git a/gdb/gdbsupport/array-view.h b/gdb/gdbsupport/array-view.h
new file mode 100644
index 00000000000..ad7933bc1fb
--- /dev/null
+++ b/gdb/gdbsupport/array-view.h
@@ -0,0 +1,259 @@
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_ARRAY_VIEW_H
+#define COMMON_ARRAY_VIEW_H
+
+#include "traits.h"
+#include <type_traits>
+
+/* An array_view is an abstraction that provides a non-owning view
+ over a sequence of contiguous objects.
+
+ A way to put it is that array_view is to std::vector (and
+ std::array and built-in arrays with rank==1) like std::string_view
+ is to std::string.
+
+ The main intent of array_view is to use it as function input
+ parameter type, making it possible to pass in any sequence of
+ contiguous objects, irrespective of whether the objects live on the
+ stack or heap and what actual container owns them. Implicit
+ construction from the element type is supported too, making it easy
+ to call functions that expect an array of elements when you only
+ have one element (usually on the stack). For example:
+
+ struct A { .... };
+ void function (gdb::array_view<A> as);
+
+ std::vector<A> std_vec = ...;
+ std::array<A, N> std_array = ...;
+ A array[] = {...};
+ A elem;
+
+ function (std_vec);
+ function (std_array);
+ function (array);
+ function (elem);
+
+ Views can be either mutable or const. A const view is simply
+ created by specifying a const T as array_view template parameter,
+ in which case operator[] of non-const array_view objects ends up
+ returning const references. Making the array_view itself const is
+ analogous to making a pointer itself be const. I.e., disables
+ re-seating the view/pointer.
+
+ Since array_view objects are small (pointer plus size), and
+ designed to be trivially copyable, they should generally be passed
+ around by value.
+
+ You can find unit tests covering the whole API in
+ unittests/array-view-selftests.c. */
+
+namespace gdb {
+
+template <typename T>
+class array_view
+{
+ /* True iff decayed T is the same as decayed U. E.g., we want to
+ say that 'T&' is the same as 'const T'. */
+ template <typename U>
+ using IsDecayedT = typename std::is_same<typename std::decay<T>::type,
+ typename std::decay<U>::type>;
+
+ /* True iff decayed T is the same as decayed U, and 'U *' is
+ implicitly convertible to 'T *'. This is a requirement for
+ several methods. */
+ template <typename U>
+ using DecayedConvertible = gdb::And<IsDecayedT<U>,
+ std::is_convertible<U *, T *>>;
+
+public:
+ using value_type = T;
+ using reference = T &;
+ using const_reference = const T &;
+ using size_type = size_t;
+
+ /* Default construction creates an empty view. */
+ constexpr array_view () noexcept
+ : m_array (nullptr), m_size (0)
+ {}
+
+ /* Create an array view over a single object of the type of an
+ array_view element. The created view as size==1. This is
+ templated on U to allow constructing a array_view<const T> over a
+ (non-const) T. The "convertible" requirement makes sure that you
+ can't create an array_view<T> over a const T. */
+ template<typename U,
+ typename = Requires<DecayedConvertible<U>>>
+ constexpr array_view (U &elem) noexcept
+ : m_array (&elem), m_size (1)
+ {}
+
+ /* Same as above, for rvalue references. */
+ template<typename U,
+ typename = Requires<DecayedConvertible<U>>>
+ constexpr array_view (U &&elem) noexcept
+ : m_array (&elem), m_size (1)
+ {}
+
+ /* Create an array view from a pointer to an array and an element
+ count. */
+ template<typename U,
+ typename = Requires<DecayedConvertible<U>>>
+ constexpr array_view (U *array, size_t size) noexcept
+ : m_array (array), m_size (size)
+ {}
+
+ /* Create an array view from a range. This is templated on both U
+ an V to allow passing in a mix of 'const T *' and 'T *'. */
+ template<typename U, typename V,
+ typename = Requires<DecayedConvertible<U>>,
+ typename = Requires<DecayedConvertible<V>>>
+ constexpr array_view (U *begin, V *end) noexcept
+ : m_array (begin), m_size (end - begin)
+ {}
+
+ /* Create an array view from an array. */
+ template<typename U, size_t Size,
+ typename = Requires<DecayedConvertible<U>>>
+ constexpr array_view (U (&array)[Size]) noexcept
+ : m_array (array), m_size (Size)
+ {}
+
+ /* Create an array view from a contiguous container. E.g.,
+ std::vector and std::array. */
+ template<typename Container,
+ typename = Requires<gdb::Not<IsDecayedT<Container>>>,
+ typename
+ = Requires<std::is_convertible
+ <decltype (std::declval<Container> ().data ()),
+ T *>>,
+ typename
+ = Requires<std::is_convertible
+ <decltype (std::declval<Container> ().size ()),
+ size_type>>>
+ constexpr array_view (Container &&c) noexcept
+ : m_array (c.data ()), m_size (c.size ())
+ {}
+
+ /* Observer methods. Some of these can't be constexpr until we
+ require C++14. */
+ /*constexpr14*/ T *data () noexcept { return m_array; }
+ constexpr const T *data () const noexcept { return m_array; }
+
+ /*constexpr14*/ T *begin () noexcept { return m_array; }
+ constexpr const T *begin () const noexcept { return m_array; }
+
+ /*constexpr14*/ T *end () noexcept { return m_array + m_size; }
+ constexpr const T *end () const noexcept { return m_array + m_size; }
+
+ /*constexpr14*/ reference operator[] (size_t index) noexcept
+ { return m_array[index]; }
+ constexpr const_reference operator[] (size_t index) const noexcept
+ { return m_array[index]; }
+
+ constexpr size_type size () const noexcept { return m_size; }
+ constexpr bool empty () const noexcept { return m_size == 0; }
+
+ /* Slice an array view. */
+
+ /* Return a new array view over SIZE elements starting at START. */
+ constexpr array_view<T> slice (size_type start, size_type size) const noexcept
+ { return {m_array + start, size}; }
+
+ /* Return a new array view over all the elements after START,
+ inclusive. */
+ constexpr array_view<T> slice (size_type start) const noexcept
+ { return {m_array + start, size () - start}; }
+
+private:
+ T *m_array;
+ size_type m_size;
+};
+
+/* Compare LHS and RHS for (deep) equality. That is, whether LHS and
+ RHS have the same sizes, and whether each pair of elements of LHS
+ and RHS at the same position compares equal. */
+
+template <typename T>
+bool
+operator== (const gdb::array_view<T> &lhs, const gdb::array_view<T> &rhs)
+{
+ if (lhs.size () != rhs.size ())
+ return false;
+
+ for (size_t i = 0; i < lhs.size (); i++)
+ if (!(lhs[i] == rhs[i]))
+ return false;
+
+ return true;
+}
+
+/* Compare two array_views for inequality. */
+
+template <typename T>
+bool
+operator!= (const gdb::array_view<T> &lhs, const gdb::array_view<T> &rhs)
+{
+ return !(lhs == rhs);
+}
+
+/* Create an array view from a pointer to an array and an element
+ count.
+
+ This is useful as alternative to constructing an array_view using
+ brace initialization when the size variable you have handy is of
+ signed type, since otherwise without an explicit cast the code
+ would be ill-formed.
+
+ For example, with:
+
+ extern void foo (int, int, gdb::array_view<value *>);
+
+ value *args[2];
+ int nargs;
+ foo (1, 2, {values, nargs});
+
+ You'd get:
+
+ source.c:10: error: narrowing conversion of ‘nargs’ from ‘int’ to
+ ‘size_t {aka long unsigned int}’ inside { } [-Werror=narrowing]
+
+ You could fix it by writing the somewhat distracting explicit cast:
+
+ foo (1, 2, {values, (size_t) nargs});
+
+ Or by instantiating an array_view explicitly:
+
+ foo (1, 2, gdb::array_view<value *>(values, nargs));
+
+ Or, better, using make_array_view, which has the advantage of
+ inferring the arrav_view element's type:
+
+ foo (1, 2, gdb::make_array_view (values, nargs));
+*/
+
+template<typename U>
+constexpr inline array_view<U>
+make_array_view (U *array, size_t size) noexcept
+{
+ return {array, size};
+}
+
+} /* namespace gdb */
+
+#endif
diff --git a/gdb/gdbsupport/ax.def b/gdb/gdbsupport/ax.def
new file mode 100644
index 00000000000..7b4c5ed7cca
--- /dev/null
+++ b/gdb/gdbsupport/ax.def
@@ -0,0 +1,97 @@
+/* Definition of agent opcode values. -*- c -*-
+ Copyright (C) 1998-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* The actual values of the various bytecode operations.
+
+ Other independent implementations of the agent bytecode engine will
+ rely on the exact values of these enums, and may not be recompiled
+ when we change this table. The numeric values should remain fixed
+ whenever possible. Thus, we assign them values explicitly here (to
+ allow gaps to form safely), and the disassembly table in
+ agentexpr.h behaves like an opcode map. If you want to see them
+ grouped logically, see doc/agentexpr.texi.
+
+ Each line is of the form:
+
+ DEFOP (name, size, data_size, consumed, produced, opcode)
+
+ NAME is the name of the operation.
+ SIZE is the number of argument bytes that the operation takes from
+ the bytecode stream.
+ DATA_SIZE is the size of data operated on, in bits, for operations
+ that care (ref and const). It is zero otherwise.
+ CONSUMED is the number of stack elements consumed.
+ PRODUCED is the number of stack elements produced.
+ OPCODE is the operation's encoding. */
+
+DEFOP (float, 0, 0, 0, 0, 0x01)
+DEFOP (add, 0, 0, 2, 1, 0x02)
+DEFOP (sub, 0, 0, 2, 1, 0x03)
+DEFOP (mul, 0, 0, 2, 1, 0x04)
+DEFOP (div_signed, 0, 0, 2, 1, 0x05)
+DEFOP (div_unsigned, 0, 0, 2, 1, 0x06)
+DEFOP (rem_signed, 0, 0, 2, 1, 0x07)
+DEFOP (rem_unsigned, 0, 0, 2, 1, 0x08)
+DEFOP (lsh, 0, 0, 2, 1, 0x09)
+DEFOP (rsh_signed, 0, 0, 2, 1, 0x0a)
+DEFOP (rsh_unsigned, 0, 0, 2, 1, 0x0b)
+DEFOP (trace, 0, 0, 2, 0, 0x0c)
+DEFOP (trace_quick, 1, 0, 1, 1, 0x0d)
+DEFOP (log_not, 0, 0, 1, 1, 0x0e)
+DEFOP (bit_and, 0, 0, 2, 1, 0x0f)
+DEFOP (bit_or, 0, 0, 2, 1, 0x10)
+DEFOP (bit_xor, 0, 0, 2, 1, 0x11)
+DEFOP (bit_not, 0, 0, 1, 1, 0x12)
+DEFOP (equal, 0, 0, 2, 1, 0x13)
+DEFOP (less_signed, 0, 0, 2, 1, 0x14)
+DEFOP (less_unsigned, 0, 0, 2, 1, 0x15)
+DEFOP (ext, 1, 0, 1, 1, 0x16)
+DEFOP (ref8, 0, 8, 1, 1, 0x17)
+DEFOP (ref16, 0, 16, 1, 1, 0x18)
+DEFOP (ref32, 0, 32, 1, 1, 0x19)
+DEFOP (ref64, 0, 64, 1, 1, 0x1a)
+DEFOP (ref_float, 0, 0, 1, 1, 0x1b)
+DEFOP (ref_double, 0, 0, 1, 1, 0x1c)
+DEFOP (ref_long_double, 0, 0, 1, 1, 0x1d)
+DEFOP (l_to_d, 0, 0, 1, 1, 0x1e)
+DEFOP (d_to_l, 0, 0, 1, 1, 0x1f)
+DEFOP (if_goto, 2, 0, 1, 0, 0x20)
+DEFOP (goto, 2, 0, 0, 0, 0x21)
+DEFOP (const8, 1, 8, 0, 1, 0x22)
+DEFOP (const16, 2, 16, 0, 1, 0x23)
+DEFOP (const32, 4, 32, 0, 1, 0x24)
+DEFOP (const64, 8, 64, 0, 1, 0x25)
+DEFOP (reg, 2, 0, 0, 1, 0x26)
+DEFOP (end, 0, 0, 0, 0, 0x27)
+DEFOP (dup, 0, 0, 1, 2, 0x28)
+DEFOP (pop, 0, 0, 1, 0, 0x29)
+DEFOP (zero_ext, 1, 0, 1, 1, 0x2a)
+DEFOP (swap, 0, 0, 2, 2, 0x2b)
+DEFOP (getv, 2, 0, 0, 1, 0x2c)
+DEFOP (setv, 2, 0, 1, 1, 0x2d)
+DEFOP (tracev, 2, 0, 0, 1, 0x2e)
+DEFOP (tracenz, 0, 0, 2, 0, 0x2f)
+DEFOP (trace16, 2, 0, 1, 1, 0x30)
+/* We need something here just to make the tables come out ok. */
+DEFOP (invalid2, 0, 0, 0, 0, 0x31)
+/* The "consumed" number for pick is wrong, but there's no way to
+ express the right thing. */
+DEFOP (pick, 1, 0, 0, 1, 0x32)
+DEFOP (rot, 0, 0, 3, 3, 0x33)
+/* Both the argument and consumed numbers are dynamic for this one. */
+DEFOP (printf, 0, 0, 0, 0, 0x34)
diff --git a/gdb/gdbsupport/break-common.h b/gdb/gdbsupport/break-common.h
new file mode 100644
index 00000000000..d85cadf442a
--- /dev/null
+++ b/gdb/gdbsupport/break-common.h
@@ -0,0 +1,31 @@
+/* Data structures associated with breakpoints shared in both GDB and
+ GDBserver.
+ Copyright (C) 1992-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_BREAK_COMMON_H
+#define COMMON_BREAK_COMMON_H
+
+enum target_hw_bp_type
+ {
+ hw_write = 0, /* Common HW watchpoint */
+ hw_read = 1, /* Read HW watchpoint */
+ hw_access = 2, /* Access HW watchpoint */
+ hw_execute = 3 /* Execute HW breakpoint */
+ };
+
+#endif /* COMMON_BREAK_COMMON_H */
diff --git a/gdb/gdbsupport/btrace-common.c b/gdb/gdbsupport/btrace-common.c
new file mode 100644
index 00000000000..13f1f1a0fdd
--- /dev/null
+++ b/gdb/gdbsupport/btrace-common.c
@@ -0,0 +1,192 @@
+/* Copyright (C) 2014-2019 Free Software Foundation, Inc.
+
+ Contributed by Intel Corp. <markus.t.metzger@intel.com>
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "btrace-common.h"
+
+
+/* See btrace-common.h. */
+
+const char *
+btrace_format_string (enum btrace_format format)
+{
+ switch (format)
+ {
+ case BTRACE_FORMAT_NONE:
+ return _("No or unknown format");
+
+ case BTRACE_FORMAT_BTS:
+ return _("Branch Trace Store");
+
+ case BTRACE_FORMAT_PT:
+ return _("Intel Processor Trace");
+ }
+
+ internal_error (__FILE__, __LINE__, _("Unknown branch trace format"));
+}
+
+/* See btrace-common.h. */
+
+const char *
+btrace_format_short_string (enum btrace_format format)
+{
+ switch (format)
+ {
+ case BTRACE_FORMAT_NONE:
+ return "unknown";
+
+ case BTRACE_FORMAT_BTS:
+ return "bts";
+
+ case BTRACE_FORMAT_PT:
+ return "pt";
+ }
+
+ internal_error (__FILE__, __LINE__, _("Unknown branch trace format"));
+}
+
+/* See btrace-common.h. */
+
+void
+btrace_data::fini ()
+{
+ switch (format)
+ {
+ case BTRACE_FORMAT_NONE:
+ /* Nothing to do. */
+ return;
+
+ case BTRACE_FORMAT_BTS:
+ VEC_free (btrace_block_s, variant.bts.blocks);
+ return;
+
+ case BTRACE_FORMAT_PT:
+ xfree (variant.pt.data);
+ return;
+ }
+
+ internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
+}
+
+/* See btrace-common.h. */
+
+bool
+btrace_data::empty () const
+{
+ switch (format)
+ {
+ case BTRACE_FORMAT_NONE:
+ return true;
+
+ case BTRACE_FORMAT_BTS:
+ return VEC_empty (btrace_block_s, variant.bts.blocks);
+
+ case BTRACE_FORMAT_PT:
+ return (variant.pt.size == 0);
+ }
+
+ internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
+}
+
+/* See btrace-common.h. */
+
+void
+btrace_data::clear ()
+{
+ fini ();
+ format = BTRACE_FORMAT_NONE;
+}
+
+/* See btrace-common.h. */
+
+int
+btrace_data_append (struct btrace_data *dst,
+ const struct btrace_data *src)
+{
+ switch (src->format)
+ {
+ case BTRACE_FORMAT_NONE:
+ return 0;
+
+ case BTRACE_FORMAT_BTS:
+ switch (dst->format)
+ {
+ default:
+ return -1;
+
+ case BTRACE_FORMAT_NONE:
+ dst->format = BTRACE_FORMAT_BTS;
+ dst->variant.bts.blocks = NULL;
+
+ /* Fall-through. */
+ case BTRACE_FORMAT_BTS:
+ {
+ unsigned int blk;
+
+ /* We copy blocks in reverse order to have the oldest block at
+ index zero. */
+ blk = VEC_length (btrace_block_s, src->variant.bts.blocks);
+ while (blk != 0)
+ {
+ btrace_block_s *block;
+
+ block = VEC_index (btrace_block_s, src->variant.bts.blocks,
+ --blk);
+
+ VEC_safe_push (btrace_block_s, dst->variant.bts.blocks, block);
+ }
+ }
+ }
+ return 0;
+
+ case BTRACE_FORMAT_PT:
+ switch (dst->format)
+ {
+ default:
+ return -1;
+
+ case BTRACE_FORMAT_NONE:
+ dst->format = BTRACE_FORMAT_PT;
+ dst->variant.pt.data = NULL;
+ dst->variant.pt.size = 0;
+
+ /* fall-through. */
+ case BTRACE_FORMAT_PT:
+ {
+ gdb_byte *data;
+ size_t size;
+
+ size = src->variant.pt.size + dst->variant.pt.size;
+ data = (gdb_byte *) xmalloc (size);
+
+ memcpy (data, dst->variant.pt.data, dst->variant.pt.size);
+ memcpy (data + dst->variant.pt.size, src->variant.pt.data,
+ src->variant.pt.size);
+
+ xfree (dst->variant.pt.data);
+
+ dst->variant.pt.data = data;
+ dst->variant.pt.size = size;
+ }
+ }
+ return 0;
+ }
+
+ internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
+}
diff --git a/gdb/gdbsupport/btrace-common.h b/gdb/gdbsupport/btrace-common.h
new file mode 100644
index 00000000000..0b18924882c
--- /dev/null
+++ b/gdb/gdbsupport/btrace-common.h
@@ -0,0 +1,257 @@
+/* Branch trace support for GDB, the GNU debugger.
+
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
+
+ Contributed by Intel Corp. <markus.t.metzger@intel.com>.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_BTRACE_COMMON_H
+#define COMMON_BTRACE_COMMON_H
+
+/* Branch tracing (btrace) is a per-thread control-flow execution trace of the
+ inferior. For presentation purposes, the branch trace is represented as a
+ list of sequential control-flow blocks, one such list per thread. */
+
+#include "vec.h"
+
+/* A branch trace block.
+
+ This represents a block of sequential control-flow. Adjacent blocks will be
+ connected via calls, returns, or jumps. The latter can be direct or
+ indirect, conditional or unconditional. Branches can further be
+ asynchronous, e.g. interrupts. */
+struct btrace_block
+{
+ /* The address of the first byte of the first instruction in the block.
+ The address may be zero if we do not know the beginning of this block,
+ such as for the first block in a delta trace. */
+ CORE_ADDR begin;
+
+ /* The address of the first byte of the last instruction in the block. */
+ CORE_ADDR end;
+};
+
+/* Define functions operating on a vector of branch trace blocks. */
+typedef struct btrace_block btrace_block_s;
+DEF_VEC_O (btrace_block_s);
+
+/* Enumeration of btrace formats. */
+
+enum btrace_format
+{
+ /* No branch trace format. */
+ BTRACE_FORMAT_NONE,
+
+ /* Branch trace is in Branch Trace Store (BTS) format.
+ Actually, the format is a sequence of blocks derived from BTS. */
+ BTRACE_FORMAT_BTS,
+
+ /* Branch trace is in Intel Processor Trace format. */
+ BTRACE_FORMAT_PT
+};
+
+/* An enumeration of cpu vendors. */
+
+enum btrace_cpu_vendor
+{
+ /* We do not know this vendor. */
+ CV_UNKNOWN,
+
+ /* Intel. */
+ CV_INTEL
+};
+
+/* A cpu identifier. */
+
+struct btrace_cpu
+{
+ /* The processor vendor. */
+ enum btrace_cpu_vendor vendor;
+
+ /* The cpu family. */
+ unsigned short family;
+
+ /* The cpu model. */
+ unsigned char model;
+
+ /* The cpu stepping. */
+ unsigned char stepping;
+};
+
+/* A BTS configuration. */
+
+struct btrace_config_bts
+{
+ /* The size of the branch trace buffer in bytes.
+
+ This is unsigned int and not size_t since it is registered as
+ control variable for "set record btrace bts buffer-size". */
+ unsigned int size;
+};
+
+/* An Intel Processor Trace configuration. */
+
+struct btrace_config_pt
+{
+ /* The size of the branch trace buffer in bytes.
+
+ This is unsigned int and not size_t since it is registered as
+ control variable for "set record btrace pt buffer-size". */
+ unsigned int size;
+};
+
+/* A branch tracing configuration.
+
+ This describes the requested configuration as well as the actually
+ obtained configuration.
+ We describe the configuration for all different formats so we can
+ easily switch between formats. */
+
+struct btrace_config
+{
+ /* The branch tracing format. */
+ enum btrace_format format;
+
+ /* The BTS format configuration. */
+ struct btrace_config_bts bts;
+
+ /* The Intel Processor Trace format configuration. */
+ struct btrace_config_pt pt;
+};
+
+/* Branch trace in BTS format. */
+struct btrace_data_bts
+{
+ /* Branch trace is represented as a vector of branch trace blocks starting
+ with the most recent block. */
+ VEC (btrace_block_s) *blocks;
+};
+
+/* Configuration information to go with the trace data. */
+struct btrace_data_pt_config
+{
+ /* The processor on which the trace has been collected. */
+ struct btrace_cpu cpu;
+};
+
+/* Branch trace in Intel Processor Trace format. */
+struct btrace_data_pt
+{
+ /* Some configuration information to go with the data. */
+ struct btrace_data_pt_config config;
+
+ /* The trace data. */
+ gdb_byte *data;
+
+ /* The size of DATA in bytes. */
+ size_t size;
+};
+
+/* The branch trace data. */
+struct btrace_data
+{
+ btrace_data () = default;
+
+ ~btrace_data ()
+ {
+ fini ();
+ }
+
+ btrace_data &operator= (btrace_data &&other)
+ {
+ if (this != &other)
+ {
+ fini ();
+ format = other.format;
+ variant = other.variant;
+ other.format = BTRACE_FORMAT_NONE;
+ }
+ return *this;
+ }
+
+ /* Return true if this is empty; false otherwise. */
+ bool empty () const;
+
+ /* Clear this object. */
+ void clear ();
+
+ enum btrace_format format = BTRACE_FORMAT_NONE;
+
+ union
+ {
+ /* Format == BTRACE_FORMAT_BTS. */
+ struct btrace_data_bts bts;
+
+ /* Format == BTRACE_FORMAT_PT. */
+ struct btrace_data_pt pt;
+ } variant;
+
+private:
+
+ DISABLE_COPY_AND_ASSIGN (btrace_data);
+
+ void fini ();
+};
+
+/* Target specific branch trace information. */
+struct btrace_target_info;
+
+/* Enumeration of btrace read types. */
+
+enum btrace_read_type
+{
+ /* Send all available trace. */
+ BTRACE_READ_ALL,
+
+ /* Send all available trace, if it changed. */
+ BTRACE_READ_NEW,
+
+ /* Send the trace since the last request. This will fail if the trace
+ buffer overflowed. */
+ BTRACE_READ_DELTA
+};
+
+/* Enumeration of btrace errors. */
+
+enum btrace_error
+{
+ /* No error. Everything is OK. */
+ BTRACE_ERR_NONE,
+
+ /* An unknown error. */
+ BTRACE_ERR_UNKNOWN,
+
+ /* Branch tracing is not supported on this system. */
+ BTRACE_ERR_NOT_SUPPORTED,
+
+ /* The branch trace buffer overflowed; no delta read possible. */
+ BTRACE_ERR_OVERFLOW
+};
+
+/* Return a string representation of FORMAT. */
+extern const char *btrace_format_string (enum btrace_format format);
+
+/* Return an abbreviation string representation of FORMAT. */
+extern const char *btrace_format_short_string (enum btrace_format format);
+
+/* Append the branch trace data from SRC to the end of DST.
+ Both SRC and DST must use the same format.
+ Returns zero on success; a negative number otherwise. */
+extern int btrace_data_append (struct btrace_data *dst,
+ const struct btrace_data *src);
+
+#endif /* COMMON_BTRACE_COMMON_H */
diff --git a/gdb/gdbsupport/buffer.c b/gdb/gdbsupport/buffer.c
new file mode 100644
index 00000000000..3c919e70979
--- /dev/null
+++ b/gdb/gdbsupport/buffer.c
@@ -0,0 +1,178 @@
+/* A simple growing buffer for GDB.
+
+ Copyright (C) 2009-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "xml-utils.h"
+#include "buffer.h"
+#include "inttypes.h"
+void
+buffer_grow (struct buffer *buffer, const char *data, size_t size)
+{
+ char *new_buffer;
+ size_t new_buffer_size;
+
+ if (size == 0)
+ return;
+
+ new_buffer_size = buffer->buffer_size;
+
+ if (new_buffer_size == 0)
+ new_buffer_size = 1;
+
+ while (buffer->used_size + size > new_buffer_size)
+ new_buffer_size *= 2;
+ new_buffer = (char *) xrealloc (buffer->buffer, new_buffer_size);
+ memcpy (new_buffer + buffer->used_size, data, size);
+ buffer->buffer = new_buffer;
+ buffer->buffer_size = new_buffer_size;
+ buffer->used_size += size;
+}
+
+void
+buffer_free (struct buffer *buffer)
+{
+ if (!buffer)
+ return;
+
+ xfree (buffer->buffer);
+ buffer->buffer = NULL;
+ buffer->buffer_size = 0;
+ buffer->used_size = 0;
+}
+
+void
+buffer_init (struct buffer *buffer)
+{
+ memset (buffer, 0, sizeof (*buffer));
+}
+
+char*
+buffer_finish (struct buffer *buffer)
+{
+ char *ret = buffer->buffer;
+ buffer->buffer = NULL;
+ buffer->buffer_size = 0;
+ buffer->used_size = 0;
+ return ret;
+}
+
+void
+buffer_xml_printf (struct buffer *buffer, const char *format, ...)
+{
+ va_list ap;
+ const char *f;
+ const char *prev;
+ int percent = 0;
+
+ va_start (ap, format);
+
+ prev = format;
+ for (f = format; *f; f++)
+ {
+ if (percent)
+ {
+ char buf[32];
+ char *str = buf;
+ const char *f_old = f;
+
+ switch (*f)
+ {
+ case 's':
+ str = va_arg (ap, char *);
+ break;
+ case 'd':
+ sprintf (str, "%d", va_arg (ap, int));
+ break;
+ case 'u':
+ sprintf (str, "%u", va_arg (ap, unsigned int));
+ break;
+ case 'x':
+ sprintf (str, "%x", va_arg (ap, unsigned int));
+ break;
+ case 'o':
+ sprintf (str, "%o", va_arg (ap, unsigned int));
+ break;
+ case 'l':
+ f++;
+ switch (*f)
+ {
+ case 'd':
+ sprintf (str, "%ld", va_arg (ap, long));
+ break;
+ case 'u':
+ sprintf (str, "%lu", va_arg (ap, unsigned long));
+ break;
+ case 'x':
+ sprintf (str, "%lx", va_arg (ap, unsigned long));
+ break;
+ case 'o':
+ sprintf (str, "%lo", va_arg (ap, unsigned long));
+ break;
+ case 'l':
+ f++;
+ switch (*f)
+ {
+ case 'd':
+ sprintf (str, "%" PRId64,
+ (int64_t) va_arg (ap, long long));
+ break;
+ case 'u':
+ sprintf (str, "%" PRIu64,
+ (uint64_t) va_arg (ap, unsigned long long));
+ break;
+ case 'x':
+ sprintf (str, "%" PRIx64,
+ (uint64_t) va_arg (ap, unsigned long long));
+ break;
+ case 'o':
+ sprintf (str, "%" PRIo64,
+ (uint64_t) va_arg (ap, unsigned long long));
+ break;
+ default:
+ str = 0;
+ break;
+ }
+ break;
+ default:
+ str = 0;
+ break;
+ }
+ break;
+ default:
+ str = 0;
+ break;
+ }
+
+ if (str)
+ {
+ buffer_grow (buffer, prev, f_old - prev - 1);
+ std::string p = xml_escape_text (str);
+ buffer_grow_str (buffer, p.c_str ());
+ prev = f + 1;
+ }
+ percent = 0;
+ }
+ else if (*f == '%')
+ percent = 1;
+ }
+
+ buffer_grow_str (buffer, prev);
+ va_end (ap);
+}
+
diff --git a/gdb/gdbsupport/buffer.h b/gdb/gdbsupport/buffer.h
new file mode 100644
index 00000000000..8b24b54d0eb
--- /dev/null
+++ b/gdb/gdbsupport/buffer.h
@@ -0,0 +1,68 @@
+/* A simple growing buffer for GDB.
+
+ Copyright (C) 2009-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_BUFFER_H
+#define COMMON_BUFFER_H
+
+struct buffer
+{
+ char *buffer;
+ size_t buffer_size; /* allocated size */
+ size_t used_size; /* actually used size */
+};
+
+/* Append DATA of size SIZE to the end of BUFFER. Grows the buffer to
+ accommodate the new data. */
+void buffer_grow (struct buffer *buffer, const char *data, size_t size);
+
+/* Append C to the end of BUFFER. Grows the buffer to accommodate the
+ new data. */
+
+static inline void
+buffer_grow_char (struct buffer *buffer, char c)
+{
+ buffer_grow (buffer, &c, 1);
+}
+
+/* Release any memory held by BUFFER. */
+void buffer_free (struct buffer *buffer);
+
+/* Initialize BUFFER. BUFFER holds no memory afterwards. */
+void buffer_init (struct buffer *buffer);
+
+/* Return a pointer into BUFFER data, effectively transferring
+ ownership of the buffer memory to the caller. Calling buffer_free
+ afterwards has no effect on the returned data. */
+char* buffer_finish (struct buffer *buffer);
+
+/* Simple printf to buffer function. Current implemented formatters:
+ %s - grow an xml escaped text in BUFFER.
+ %d - grow an signed integer in BUFFER.
+ %u - grow an unsigned integer in BUFFER.
+ %x - grow an unsigned integer formatted in hexadecimal in BUFFER.
+ %o - grow an unsigned integer formatted in octal in BUFFER. */
+void buffer_xml_printf (struct buffer *buffer, const char *format, ...)
+ ATTRIBUTE_PRINTF (2, 3);
+
+#define buffer_grow_str(BUFFER,STRING) \
+ buffer_grow (BUFFER, STRING, strlen (STRING))
+#define buffer_grow_str0(BUFFER,STRING) \
+ buffer_grow (BUFFER, STRING, strlen (STRING) + 1)
+
+#endif /* COMMON_BUFFER_H */
diff --git a/gdb/gdbsupport/byte-vector.h b/gdb/gdbsupport/byte-vector.h
new file mode 100644
index 00000000000..5dec3017c20
--- /dev/null
+++ b/gdb/gdbsupport/byte-vector.h
@@ -0,0 +1,63 @@
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_BYTE_VECTOR_H
+#define COMMON_BYTE_VECTOR_H
+
+#include "gdbsupport/def-vector.h"
+
+namespace gdb {
+
+/* byte_vector is a gdb_byte std::vector with a custom allocator that
+ unlike std::vector<gdb_byte> does not zero-initialize new elements
+ by default when the vector is created/resized. This is what you
+ usually want when working with byte buffers, since if you're
+ creating or growing a buffer you'll most surely want to fill it in
+ with data, in which case zero-initialization would be a
+ pessimization. For example:
+
+ gdb::byte_vector buf (some_large_size);
+ fill_with_data (buf.data (), buf.size ());
+
+ On the odd case you do need zero initialization, then you can still
+ call the overloads that specify an explicit value, like:
+
+ gdb::byte_vector buf (some_initial_size, 0);
+ buf.resize (a_bigger_size, 0);
+
+ (Or use std::vector<gdb_byte> instead.)
+
+ Note that unlike std::vector<gdb_byte>, function local
+ gdb::byte_vector objects constructed with an initial size like:
+
+ gdb::byte_vector buf (some_size);
+ fill_with_data (buf.data (), buf.size ());
+
+ usually compile down to the exact same as:
+
+ std::unique_ptr<byte[]> buf (new gdb_byte[some_size]);
+ fill_with_data (buf.get (), some_size);
+
+ with the former having the advantage of being a bit more readable,
+ and providing the whole std::vector API, if you end up needing it.
+*/
+using byte_vector = gdb::def_vector<gdb_byte>;
+using char_vector = gdb::def_vector<char>;
+
+} /* namespace gdb */
+
+#endif /* COMMON_DEF_VECTOR_H */
diff --git a/gdb/gdbsupport/cleanups.c b/gdb/gdbsupport/cleanups.c
new file mode 100644
index 00000000000..121720d3c0f
--- /dev/null
+++ b/gdb/gdbsupport/cleanups.c
@@ -0,0 +1,144 @@
+/* Cleanup routines for GDB, the GNU debugger.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "cleanups.h"
+
+/* The cleanup list records things that have to be undone
+ if an error happens (descriptors to be closed, memory to be freed, etc.)
+ Each link in the chain records a function to call and an
+ argument to give it.
+
+ Use make_cleanup to add an element to the cleanup chain.
+ Use do_cleanups to do all cleanup actions back to a given
+ point in the chain. Use discard_cleanups to remove cleanups
+ from the chain back to a given point, not doing them.
+
+ If the argument is pointer to allocated memory, then you need
+ to additionally set the 'free_arg' member to a function that will
+ free that memory. This function will be called both when the cleanup
+ is executed and when it's discarded. */
+
+struct cleanup
+{
+ struct cleanup *next;
+ void (*function) (void *);
+ void (*free_arg) (void *);
+ void *arg;
+};
+
+/* Used to mark the end of a cleanup chain.
+ The value is chosen so that it:
+ - is non-NULL so that make_cleanup never returns NULL,
+ - causes a segv if dereferenced
+ [though this won't catch errors that a value of, say,
+ ((struct cleanup *) -1) will]
+ - displays as something useful when printed in gdb.
+ This is const for a bit of extra robustness.
+ It is initialized to coax gcc into putting it into .rodata.
+ All fields are initialized to survive -Wextra. */
+static const struct cleanup sentinel_cleanup = { 0, 0, 0, 0 };
+
+/* Handy macro to use when referring to sentinel_cleanup. */
+#define SENTINEL_CLEANUP ((struct cleanup *) &sentinel_cleanup)
+
+/* Chain of cleanup actions established with make_final_cleanup,
+ to be executed when gdb exits. */
+static struct cleanup *final_cleanup_chain = SENTINEL_CLEANUP;
+
+/* Main worker routine to create a cleanup.
+ PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
+ FUNCTION is the function to call to perform the cleanup.
+ ARG is passed to FUNCTION when called.
+ FREE_ARG, if non-NULL, is called after the cleanup is performed.
+
+ The result is a pointer to the previous chain pointer
+ to be passed later to do_cleanups or discard_cleanups. */
+
+static struct cleanup *
+make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
+ void *arg, void (*free_arg) (void *))
+{
+ struct cleanup *newobj = XNEW (struct cleanup);
+ struct cleanup *old_chain = *pmy_chain;
+
+ newobj->next = *pmy_chain;
+ newobj->function = function;
+ newobj->free_arg = free_arg;
+ newobj->arg = arg;
+ *pmy_chain = newobj;
+
+ gdb_assert (old_chain != NULL);
+ return old_chain;
+}
+
+/* Worker routine to create a cleanup without a destructor.
+ PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
+ FUNCTION is the function to call to perform the cleanup.
+ ARG is passed to FUNCTION when called.
+
+ The result is a pointer to the previous chain pointer
+ to be passed later to do_cleanups or discard_cleanups. */
+
+static struct cleanup *
+make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
+ void *arg)
+{
+ return make_my_cleanup2 (pmy_chain, function, arg, NULL);
+}
+
+/* Add a new cleanup to the final cleanup_chain,
+ and return the previous chain pointer
+ to be passed later to do_cleanups or discard_cleanups.
+ Args are FUNCTION to clean up with, and ARG to pass to it. */
+
+struct cleanup *
+make_final_cleanup (make_cleanup_ftype *function, void *arg)
+{
+ return make_my_cleanup (&final_cleanup_chain, function, arg);
+}
+
+/* Worker routine to perform cleanups.
+ PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
+ OLD_CHAIN is the result of a "make" cleanup routine.
+ Cleanups are performed until we get back to the old end of the chain. */
+
+static void
+do_my_cleanups (struct cleanup **pmy_chain,
+ struct cleanup *old_chain)
+{
+ struct cleanup *ptr;
+
+ while ((ptr = *pmy_chain) != old_chain)
+ {
+ *pmy_chain = ptr->next; /* Do this first in case of recursion. */
+ (*ptr->function) (ptr->arg);
+ if (ptr->free_arg)
+ (*ptr->free_arg) (ptr->arg);
+ xfree (ptr);
+ }
+}
+
+/* Discard final cleanups and do the actions they describe. */
+
+void
+do_final_cleanups ()
+{
+ do_my_cleanups (&final_cleanup_chain, SENTINEL_CLEANUP);
+}
diff --git a/gdb/gdbsupport/cleanups.h b/gdb/gdbsupport/cleanups.h
new file mode 100644
index 00000000000..e676076a16d
--- /dev/null
+++ b/gdb/gdbsupport/cleanups.h
@@ -0,0 +1,39 @@
+/* Cleanups.
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_CLEANUPS_H
+#define COMMON_CLEANUPS_H
+
+/* Outside of cleanups.c, this is an opaque type. */
+struct cleanup;
+
+/* NOTE: cagney/2000-03-04: This typedef is strictly for the
+ make_cleanup function declarations below. Do not use this typedef
+ as a cast when passing functions into the make_cleanup() code.
+ Instead either use a bounce function or add a wrapper function.
+ Calling a f(char*) function with f(void*) is non-portable. */
+typedef void (make_cleanup_ftype) (void *);
+
+/* Function type for the dtor in make_cleanup_dtor. */
+typedef void (make_cleanup_dtor_ftype) (void *);
+
+extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *);
+
+extern void do_final_cleanups ();
+
+#endif /* COMMON_CLEANUPS_H */
diff --git a/gdb/gdbsupport/common-debug.c b/gdb/gdbsupport/common-debug.c
new file mode 100644
index 00000000000..97c90032ebd
--- /dev/null
+++ b/gdb/gdbsupport/common-debug.c
@@ -0,0 +1,37 @@
+/* Debug printing functions.
+
+ Copyright (C) 2014-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "common-debug.h"
+
+/* See gdbsupport/common-debug.h. */
+
+int show_debug_regs;
+
+/* See gdbsupport/common-debug.h. */
+
+void
+debug_printf (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ debug_vprintf (fmt, ap);
+ va_end (ap);
+}
diff --git a/gdb/gdbsupport/common-debug.h b/gdb/gdbsupport/common-debug.h
new file mode 100644
index 00000000000..d5bfc9eb3ae
--- /dev/null
+++ b/gdb/gdbsupport/common-debug.h
@@ -0,0 +1,41 @@
+/* Declarations for debug printing functions.
+
+ Copyright (C) 2014-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_COMMON_DEBUG_H
+#define COMMON_COMMON_DEBUG_H
+
+/* Set to nonzero to enable debugging of hardware breakpoint/
+ watchpoint support code. */
+
+extern int show_debug_regs;
+
+/* Print a formatted message to the appropriate channel for
+ debugging output for the client. */
+
+extern void debug_printf (const char *format, ...)
+ ATTRIBUTE_PRINTF (1, 2);
+
+/* Print a formatted message to the appropriate channel for
+ debugging output for the client. This function must be
+ provided by the client. */
+
+extern void debug_vprintf (const char *format, va_list ap)
+ ATTRIBUTE_PRINTF (1, 0);
+
+#endif /* COMMON_COMMON_DEBUG_H */
diff --git a/gdb/gdbsupport/common-defs.h b/gdb/gdbsupport/common-defs.h
new file mode 100644
index 00000000000..203bd8972da
--- /dev/null
+++ b/gdb/gdbsupport/common-defs.h
@@ -0,0 +1,150 @@
+/* Common definitions.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_COMMON_DEFS_H
+#define COMMON_COMMON_DEFS_H
+
+#include "config.h"
+
+#undef PACKAGE_NAME
+#undef PACKAGE_VERSION
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+
+#ifdef GDBSERVER
+#include "build-gnulib-gdbserver/config.h"
+#else
+#include "../../gnulib/config.h"
+#endif
+
+#undef PACKAGE_NAME
+#undef PACKAGE_VERSION
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+
+/* From:
+ https://www.gnu.org/software/gnulib/manual/html_node/stdint_002eh.html
+
+ "On some hosts that predate C++11, when using C++ one must define
+ __STDC_CONSTANT_MACROS to make visible the definitions of constant
+ macros such as INTMAX_C, and one must define __STDC_LIMIT_MACROS to
+ make visible the definitions of limit macros such as INTMAX_MAX.".
+
+ And:
+ https://www.gnu.org/software/gnulib/manual/html_node/inttypes_002eh.html
+
+ "On some hosts that predate C++11, when using C++ one must define
+ __STDC_FORMAT_MACROS to make visible the declarations of format
+ macros such as PRIdMAX."
+
+ Must do this before including any system header, since other system
+ headers may include stdint.h/inttypes.h. */
+#define __STDC_CONSTANT_MACROS 1
+#define __STDC_LIMIT_MACROS 1
+#define __STDC_FORMAT_MACROS 1
+
+/* Some distros enable _FORTIFY_SOURCE by default, which on occasion
+ has caused build failures with -Wunused-result when a patch is
+ developed on a distro that does not enable _FORTIFY_SOURCE. We
+ enable it here in order to try to catch these problems earlier;
+ plus this seems like a reasonable safety measure. The check for
+ optimization is required because _FORTIFY_SOURCE only works when
+ optimization is enabled. If _FORTIFY_SOURCE is already defined,
+ then we don't do anything. */
+
+#if !defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__ > 0
+#define _FORTIFY_SOURCE 2
+#endif
+
+/* We don't support Windows versions before XP, so we define
+ _WIN32_WINNT correspondingly to ensure the Windows API headers
+ expose the required symbols. */
+#if defined (__MINGW32__) || defined (__CYGWIN__)
+# ifdef _WIN32_WINNT
+# if _WIN32_WINNT < 0x0501
+# undef _WIN32_WINNT
+# define _WIN32_WINNT 0x0501
+# endif
+# else
+# define _WIN32_WINNT 0x0501
+# endif
+#endif /* __MINGW32__ || __CYGWIN__ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h> /* for strcasecmp and strncasecmp */
+#endif
+#include <errno.h>
+#include <alloca.h>
+
+#include "ansidecl.h"
+/* This is defined by ansidecl.h, but we prefer gnulib's version. On
+ MinGW, gnulib might enable __USE_MINGW_ANSI_STDIO, which may or not
+ require use of attribute gnu_printf instead of printf. gnulib
+ checks that at configure time. Since _GL_ATTRIBUTE_FORMAT_PRINTF
+ is compatible with ATTRIBUTE_PRINTF, simply use it. */
+#undef ATTRIBUTE_PRINTF
+#define ATTRIBUTE_PRINTF _GL_ATTRIBUTE_FORMAT_PRINTF
+
+#if GCC_VERSION >= 3004
+#define ATTRIBUTE_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
+#else
+#define ATTRIBUTE_UNUSED_RESULT
+#endif
+
+#include "libiberty.h"
+#include "pathmax.h"
+#include "gdb/signals.h"
+#include "gdb_locale.h"
+#include "ptid.h"
+#include "common-types.h"
+#include "common-utils.h"
+#include "gdb_assert.h"
+#include "errors.h"
+#include "print-utils.h"
+#include "common-debug.h"
+#include "cleanups.h"
+#include "common-exceptions.h"
+#include "gdbsupport/poison.h"
+
+#define EXTERN_C extern "C"
+#define EXTERN_C_PUSH extern "C" {
+#define EXTERN_C_POP }
+
+/* Pull in gdb::unique_xmalloc_ptr. */
+#include "gdbsupport/gdb_unique_ptr.h"
+
+/* String containing the current directory (what getwd would return). */
+extern char *current_directory;
+
+/* sbrk on macOS is not useful for our purposes, since sbrk(0) always
+ returns the same value. brk/sbrk on macOS is just an emulation
+ that always returns a pointer to a 4MB section reserved for
+ that. */
+
+#if defined (HAVE_SBRK) && !__APPLE__
+#define HAVE_USEFUL_SBRK 1
+#endif
+
+#endif /* COMMON_COMMON_DEFS_H */
diff --git a/gdb/gdbsupport/common-exceptions.c b/gdb/gdbsupport/common-exceptions.c
new file mode 100644
index 00000000000..9f210250a6f
--- /dev/null
+++ b/gdb/gdbsupport/common-exceptions.c
@@ -0,0 +1,235 @@
+/* Exception (throw catch) mechanism, for GDB, the GNU debugger.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "common-exceptions.h"
+#include <forward_list>
+
+/* Possible catcher states. */
+enum catcher_state {
+ /* Initial state, a new catcher has just been created. */
+ CATCHER_CREATED,
+ /* The catch code is running. */
+ CATCHER_RUNNING,
+ CATCHER_RUNNING_1,
+ /* The catch code threw an exception. */
+ CATCHER_ABORTING
+};
+
+/* Possible catcher actions. */
+enum catcher_action {
+ CATCH_ITER,
+ CATCH_ITER_1,
+ CATCH_THROWING
+};
+
+struct catcher
+{
+ enum catcher_state state = CATCHER_CREATED;
+ /* Jump buffer pointing back at the exception handler. */
+ jmp_buf buf;
+ /* Status buffer belonging to the exception handler. */
+ struct gdb_exception exception;
+};
+
+/* Where to go for throw_exception(). */
+static std::forward_list<struct catcher> catchers;
+
+jmp_buf *
+exceptions_state_mc_init ()
+{
+ catchers.emplace_front ();
+ return &catchers.front ().buf;
+}
+
+/* Catcher state machine. Returns non-zero if the m/c should be run
+ again, zero if it should abort. */
+
+static int
+exceptions_state_mc (enum catcher_action action)
+{
+ switch (catchers.front ().state)
+ {
+ case CATCHER_CREATED:
+ switch (action)
+ {
+ case CATCH_ITER:
+ /* Allow the code to run the catcher. */
+ catchers.front ().state = CATCHER_RUNNING;
+ return 1;
+ default:
+ internal_error (__FILE__, __LINE__, _("bad state"));
+ }
+ case CATCHER_RUNNING:
+ switch (action)
+ {
+ case CATCH_ITER:
+ /* No error/quit has occured. */
+ return 0;
+ case CATCH_ITER_1:
+ catchers.front ().state = CATCHER_RUNNING_1;
+ return 1;
+ case CATCH_THROWING:
+ catchers.front ().state = CATCHER_ABORTING;
+ /* See also throw_exception. */
+ return 1;
+ default:
+ internal_error (__FILE__, __LINE__, _("bad switch"));
+ }
+ case CATCHER_RUNNING_1:
+ switch (action)
+ {
+ case CATCH_ITER:
+ /* The did a "break" from the inner while loop. */
+ return 0;
+ case CATCH_ITER_1:
+ catchers.front ().state = CATCHER_RUNNING;
+ return 0;
+ case CATCH_THROWING:
+ catchers.front ().state = CATCHER_ABORTING;
+ /* See also throw_exception. */
+ return 1;
+ default:
+ internal_error (__FILE__, __LINE__, _("bad switch"));
+ }
+ case CATCHER_ABORTING:
+ switch (action)
+ {
+ case CATCH_ITER:
+ {
+ /* Exit normally if this catcher can handle this
+ exception. The caller analyses the func return
+ values. */
+ return 0;
+ }
+ default:
+ internal_error (__FILE__, __LINE__, _("bad state"));
+ }
+ default:
+ internal_error (__FILE__, __LINE__, _("bad switch"));
+ }
+}
+
+int
+exceptions_state_mc_catch (struct gdb_exception *exception,
+ int mask)
+{
+ *exception = std::move (catchers.front ().exception);
+ catchers.pop_front ();
+
+ if (exception->reason < 0)
+ {
+ if (mask & RETURN_MASK (exception->reason))
+ {
+ /* Exit normally and let the caller handle the
+ exception. */
+ return 1;
+ }
+
+ /* The caller didn't request that the event be caught, relay the
+ event to the next exception_catch/CATCH_SJLJ. */
+ throw_exception_sjlj (*exception);
+ }
+
+ /* No exception was thrown. */
+ return 0;
+}
+
+int
+exceptions_state_mc_action_iter (void)
+{
+ return exceptions_state_mc (CATCH_ITER);
+}
+
+int
+exceptions_state_mc_action_iter_1 (void)
+{
+ return exceptions_state_mc (CATCH_ITER_1);
+}
+
+/* Return EXCEPTION to the nearest containing CATCH_SJLJ block. */
+
+void
+throw_exception_sjlj (const struct gdb_exception &exception)
+{
+ /* Jump to the nearest CATCH_SJLJ block, communicating REASON to
+ that call via setjmp's return value. Note that REASON can't be
+ zero, by definition in common-exceptions.h. */
+ exceptions_state_mc (CATCH_THROWING);
+ enum return_reason reason = exception.reason;
+ catchers.front ().exception = exception;
+ longjmp (catchers.front ().buf, reason);
+}
+
+/* Implementation of throw_exception that uses C++ try/catch. */
+
+void
+throw_exception (gdb_exception &&exception)
+{
+ if (exception.reason == RETURN_QUIT)
+ throw gdb_exception_quit (std::move (exception));
+ else if (exception.reason == RETURN_ERROR)
+ throw gdb_exception_error (std::move (exception));
+ else
+ gdb_assert_not_reached ("invalid return reason");
+}
+
+static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0)
+throw_it (enum return_reason reason, enum errors error, const char *fmt,
+ va_list ap)
+{
+ if (reason == RETURN_QUIT)
+ throw gdb_exception_quit (fmt, ap);
+ else if (reason == RETURN_ERROR)
+ throw gdb_exception_error (error, fmt, ap);
+ else
+ gdb_assert_not_reached ("invalid return reason");
+}
+
+void
+throw_verror (enum errors error, const char *fmt, va_list ap)
+{
+ throw_it (RETURN_ERROR, error, fmt, ap);
+}
+
+void
+throw_vquit (const char *fmt, va_list ap)
+{
+ throw_it (RETURN_QUIT, GDB_NO_ERROR, fmt, ap);
+}
+
+void
+throw_error (enum errors error, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ throw_verror (error, fmt, args);
+ va_end (args);
+}
+
+void
+throw_quit (const char *fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ throw_vquit (fmt, args);
+ va_end (args);
+}
diff --git a/gdb/gdbsupport/common-exceptions.h b/gdb/gdbsupport/common-exceptions.h
new file mode 100644
index 00000000000..ebcaf031354
--- /dev/null
+++ b/gdb/gdbsupport/common-exceptions.h
@@ -0,0 +1,304 @@
+/* Exception (throw catch) mechanism, for GDB, the GNU debugger.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_COMMON_EXCEPTIONS_H
+#define COMMON_COMMON_EXCEPTIONS_H
+
+#include <setjmp.h>
+#include <new>
+#include <memory>
+#include <string>
+
+/* Reasons for calling throw_exceptions(). NOTE: all reason values
+ must be different from zero. enum value 0 is reserved for internal
+ use as the return value from an initial setjmp(). */
+
+enum return_reason
+ {
+ /* User interrupt. */
+ RETURN_QUIT = -2,
+ /* Any other error. */
+ RETURN_ERROR
+ };
+
+#define RETURN_MASK(reason) (1 << (int)(-reason))
+
+typedef enum
+{
+ RETURN_MASK_QUIT = RETURN_MASK (RETURN_QUIT),
+ RETURN_MASK_ERROR = RETURN_MASK (RETURN_ERROR),
+ RETURN_MASK_ALL = (RETURN_MASK_QUIT | RETURN_MASK_ERROR)
+} return_mask;
+
+/* Describe all exceptions. */
+
+enum errors {
+ GDB_NO_ERROR,
+
+ /* Any generic error, the corresponding text is in
+ exception.message. */
+ GENERIC_ERROR,
+
+ /* Something requested was not found. */
+ NOT_FOUND_ERROR,
+
+ /* Thread library lacks support necessary for finding thread local
+ storage. */
+ TLS_NO_LIBRARY_SUPPORT_ERROR,
+
+ /* Load module not found while attempting to find thread local storage. */
+ TLS_LOAD_MODULE_NOT_FOUND_ERROR,
+
+ /* Thread local storage has not been allocated yet. */
+ TLS_NOT_ALLOCATED_YET_ERROR,
+
+ /* Something else went wrong while attempting to find thread local
+ storage. The ``struct gdb_exception'' message field provides
+ more detail. */
+ TLS_GENERIC_ERROR,
+
+ /* Problem parsing an XML document. */
+ XML_PARSE_ERROR,
+
+ /* Error accessing memory. */
+ MEMORY_ERROR,
+
+ /* Value not available. E.g., a register was not collected in a
+ traceframe. */
+ NOT_AVAILABLE_ERROR,
+
+ /* Value was optimized out. Note: if the value was a register, this
+ means the register was not saved in the frame. */
+ OPTIMIZED_OUT_ERROR,
+
+ /* DW_OP_entry_value resolving failed. */
+ NO_ENTRY_VALUE_ERROR,
+
+ /* Target throwing an error has been closed. Current command should be
+ aborted as the inferior state is no longer valid. */
+ TARGET_CLOSE_ERROR,
+
+ /* An undefined command was executed. */
+ UNDEFINED_COMMAND_ERROR,
+
+ /* Requested feature, method, mechanism, etc. is not supported. */
+ NOT_SUPPORTED_ERROR,
+
+ /* The number of candidates generated during line completion has
+ reached the user's specified limit. This isn't an error, this exception
+ is used to halt searching for more completions, but for consistency
+ "_ERROR" is appended to the name. */
+ MAX_COMPLETIONS_REACHED_ERROR,
+
+ /* Add more errors here. */
+ NR_ERRORS
+};
+
+struct gdb_exception
+{
+ gdb_exception ()
+ : reason ((enum return_reason) 0),
+ error (GDB_NO_ERROR)
+ {
+ }
+
+ gdb_exception (enum return_reason r, enum errors e)
+ : reason (r),
+ error (e)
+ {
+ }
+
+ gdb_exception (enum return_reason r, enum errors e,
+ const char *fmt, va_list ap)
+ ATTRIBUTE_PRINTF (4, 0)
+ : reason (r),
+ error (e),
+ message (std::make_shared<std::string> (string_vprintf (fmt, ap)))
+ {
+ }
+
+ /* The move constructor exists so that we can mark it "noexcept",
+ which is a good practice for any sort of exception object. */
+ explicit gdb_exception (gdb_exception &&other) noexcept = default;
+
+ /* The copy constructor exists so that we can mark it "noexcept",
+ which is a good practice for any sort of exception object. */
+ gdb_exception (const gdb_exception &other) noexcept
+ : reason (other.reason),
+ error (other.error),
+ message (other.message)
+ {
+ }
+
+ /* The assignment operator exists so that we can mark it "noexcept",
+ which is a good practice for any sort of exception object. */
+ gdb_exception &operator= (const gdb_exception &other) noexcept
+ {
+ reason = other.reason;
+ error = other.error;
+ message = other.message;
+ return *this;
+ }
+
+ gdb_exception &operator= (gdb_exception &&other) noexcept = default;
+
+ /* Return the contents of the exception message, as a C string. The
+ string remains owned by the exception object. */
+ const char *what () const noexcept
+ {
+ return message->c_str ();
+ }
+
+ enum return_reason reason;
+ enum errors error;
+ std::shared_ptr<std::string> message;
+};
+
+/* Functions to drive the sjlj-based exceptions state machine. Though
+ declared here by necessity, these functions should be considered
+ internal to the exceptions subsystem and not used other than via
+ the TRY/CATCH (or TRY_SJLJ/CATCH_SJLJ) macros defined below. */
+
+extern jmp_buf *exceptions_state_mc_init (void);
+extern int exceptions_state_mc_action_iter (void);
+extern int exceptions_state_mc_action_iter_1 (void);
+extern int exceptions_state_mc_catch (struct gdb_exception *, int);
+
+/* Macro to wrap up standard try/catch behavior.
+
+ The double loop lets us correctly handle code "break"ing out of the
+ try catch block. (It works as the "break" only exits the inner
+ "while" loop, the outer for loop detects this handling it
+ correctly.) Of course "return" and "goto" are not so lucky.
+
+ For instance:
+
+ *INDENT-OFF*
+
+ TRY_SJLJ
+ {
+ }
+ CATCH_SJLJ (e, RETURN_MASK_ERROR)
+ {
+ switch (e.reason)
+ {
+ case RETURN_ERROR: ...
+ }
+ }
+ END_CATCH_SJLJ
+
+ The SJLJ variants are needed in some cases where gdb exceptions
+ need to cross third-party library code compiled without exceptions
+ support (e.g., readline). */
+
+#define TRY_SJLJ \
+ { \
+ jmp_buf *buf = \
+ exceptions_state_mc_init (); \
+ setjmp (*buf); \
+ } \
+ while (exceptions_state_mc_action_iter ()) \
+ while (exceptions_state_mc_action_iter_1 ())
+
+#define CATCH_SJLJ(EXCEPTION, MASK) \
+ { \
+ struct gdb_exception EXCEPTION; \
+ if (exceptions_state_mc_catch (&(EXCEPTION), MASK))
+
+#define END_CATCH_SJLJ \
+ }
+
+/* The exception types client code may catch. They're just shims
+ around gdb_exception that add nothing but type info. Which is used
+ is selected depending on the MASK argument passed to CATCH. */
+
+struct gdb_exception_error : public gdb_exception
+{
+ gdb_exception_error (enum errors e, const char *fmt, va_list ap)
+ ATTRIBUTE_PRINTF (3, 0)
+ : gdb_exception (RETURN_ERROR, e, fmt, ap)
+ {
+ }
+
+ explicit gdb_exception_error (gdb_exception &&ex) noexcept
+ : gdb_exception (std::move (ex))
+ {
+ gdb_assert (ex.reason == RETURN_ERROR);
+ }
+};
+
+struct gdb_exception_quit : public gdb_exception
+{
+ gdb_exception_quit (const char *fmt, va_list ap)
+ ATTRIBUTE_PRINTF (2, 0)
+ : gdb_exception (RETURN_QUIT, GDB_NO_ERROR, fmt, ap)
+ {
+ }
+
+ explicit gdb_exception_quit (gdb_exception &&ex) noexcept
+ : gdb_exception (std::move (ex))
+ {
+ gdb_assert (ex.reason == RETURN_QUIT);
+ }
+};
+
+/* An exception type that inherits from both std::bad_alloc and a gdb
+ exception. This is necessary because operator new can only throw
+ std::bad_alloc, and OTOH, we want exceptions thrown due to memory
+ allocation error to be caught by all the CATCH/RETURN_MASK_ALL
+ spread around the codebase. */
+
+struct gdb_quit_bad_alloc
+ : public gdb_exception_quit,
+ public std::bad_alloc
+{
+ explicit gdb_quit_bad_alloc (gdb_exception &&ex) noexcept
+ : gdb_exception_quit (std::move (ex)),
+ std::bad_alloc ()
+ {
+ }
+};
+
+/* *INDENT-ON* */
+
+/* Throw an exception (as described by "struct gdb_exception"),
+ landing in the inner most containing exception handler established
+ using TRY/CATCH. */
+extern void throw_exception (gdb_exception &&exception)
+ ATTRIBUTE_NORETURN;
+
+/* Throw an exception by executing a LONG JUMP to the inner most
+ containing exception handler established using TRY_SJLJ. Necessary
+ in some cases where we need to throw GDB exceptions across
+ third-party library code (e.g., readline). */
+extern void throw_exception_sjlj (const struct gdb_exception &exception)
+ ATTRIBUTE_NORETURN;
+
+/* Convenience wrappers around throw_exception that throw GDB
+ errors. */
+extern void throw_verror (enum errors, const char *fmt, va_list ap)
+ ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0);
+extern void throw_vquit (const char *fmt, va_list ap)
+ ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0);
+extern void throw_error (enum errors error, const char *fmt, ...)
+ ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3);
+extern void throw_quit (const char *fmt, ...)
+ ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2);
+
+#endif /* COMMON_COMMON_EXCEPTIONS_H */
diff --git a/gdb/gdbsupport/common-gdbthread.h b/gdb/gdbsupport/common-gdbthread.h
new file mode 100644
index 00000000000..d692be209cd
--- /dev/null
+++ b/gdb/gdbsupport/common-gdbthread.h
@@ -0,0 +1,25 @@
+/* Common multi-process/thread control defs for GDB and gdbserver.
+ Copyright (C) 1987-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_COMMON_GDBTHREAD_H
+#define COMMON_COMMON_GDBTHREAD_H
+
+/* Switch from one thread to another. */
+extern void switch_to_thread (ptid_t ptid);
+
+#endif /* COMMON_COMMON_GDBTHREAD_H */
diff --git a/gdb/gdbsupport/common-inferior.h b/gdb/gdbsupport/common-inferior.h
new file mode 100644
index 00000000000..72e4bd9eac3
--- /dev/null
+++ b/gdb/gdbsupport/common-inferior.h
@@ -0,0 +1,41 @@
+/* Functions to deal with the inferior being executed on GDB or
+ GDBserver.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_COMMON_INFERIOR_H
+#define COMMON_COMMON_INFERIOR_H
+
+/* Return the exec wrapper to be used when starting the inferior, or NULL
+ otherwise. */
+extern const char *get_exec_wrapper ();
+
+/* Return the name of the executable file as a string.
+ ERR nonzero means get error if there is none specified;
+ otherwise return 0 in that case. */
+extern char *get_exec_file (int err);
+
+/* Return the inferior's current working directory. If nothing has
+ been set, then return NULL. */
+extern const char *get_inferior_cwd ();
+
+/* Set the inferior current working directory. If CWD is NULL, unset
+ the directory. */
+extern void set_inferior_cwd (const char *cwd);
+
+#endif /* COMMON_COMMON_INFERIOR_H */
diff --git a/gdb/gdbsupport/common-regcache.c b/gdb/gdbsupport/common-regcache.c
new file mode 100644
index 00000000000..4bdadffb824
--- /dev/null
+++ b/gdb/gdbsupport/common-regcache.c
@@ -0,0 +1,36 @@
+/* Cache and manage the values of registers for GDB, the GNU debugger.
+
+ Copyright (C) 2015-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "common-regcache.h"
+
+/* Return the register's value or throw if it's not available. */
+
+ULONGEST
+regcache_raw_get_unsigned (struct regcache *regcache, int regnum)
+{
+ ULONGEST value;
+ enum register_status status;
+
+ status = regcache_raw_read_unsigned (regcache, regnum, &value);
+ if (status == REG_UNAVAILABLE)
+ throw_error (NOT_AVAILABLE_ERROR,
+ _("Register %d is not available"), regnum);
+ return value;
+}
diff --git a/gdb/gdbsupport/common-regcache.h b/gdb/gdbsupport/common-regcache.h
new file mode 100644
index 00000000000..95ce64a91f9
--- /dev/null
+++ b/gdb/gdbsupport/common-regcache.h
@@ -0,0 +1,85 @@
+/* Cache and manage the values of registers
+
+ Copyright (C) 2014-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_COMMON_REGCACHE_H
+#define COMMON_COMMON_REGCACHE_H
+
+/* This header is a stopgap until we have an independent regcache. */
+
+enum register_status : signed char
+ {
+ /* The register value is not in the cache, and we don't know yet
+ whether it's available in the target (or traceframe). */
+ REG_UNKNOWN = 0,
+
+ /* The register value is valid and cached. */
+ REG_VALID = 1,
+
+ /* The register value is unavailable. E.g., we're inspecting a
+ traceframe, and this register wasn't collected. Note that this
+ is different a different "unavailable" from saying the register
+ does not exist in the target's architecture --- in that case,
+ the target should have given us a target description that does
+ not include the register in the first place. */
+ REG_UNAVAILABLE = -1
+ };
+
+/* Return a pointer to the register cache associated with the
+ thread specified by PTID. This function must be provided by
+ the client. */
+
+extern struct regcache *get_thread_regcache_for_ptid (ptid_t ptid);
+
+/* Return the size of register numbered N in REGCACHE. This function
+ must be provided by the client. */
+
+extern int regcache_register_size (const struct regcache *regcache, int n);
+
+/* Read the PC register. This function must be provided by the
+ client. */
+
+extern CORE_ADDR regcache_read_pc (struct regcache *regcache);
+
+/* Read a raw register into a unsigned integer. */
+extern enum register_status regcache_raw_read_unsigned
+ (struct regcache *regcache, int regnum, ULONGEST *val);
+
+ULONGEST regcache_raw_get_unsigned (struct regcache *regcache, int regnum);
+
+struct reg_buffer_common
+{
+ virtual ~reg_buffer_common () = default;
+
+ /* Get the availability status of the value of register REGNUM in this
+ buffer. */
+ virtual register_status get_register_status (int regnum) const = 0;
+
+ /* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE. */
+ virtual void raw_supply (int regnum, const void *buf) = 0;
+
+ /* Collect register REGNUM from REGCACHE and store its contents in BUF. */
+ virtual void raw_collect (int regnum, void *buf) const = 0;
+
+ /* Compare the contents of the register stored in the regcache (ignoring the
+ first OFFSET bytes) to the contents of BUF (without any offset). Returns
+ true if the same. */
+ virtual bool raw_compare (int regnum, const void *buf, int offset) const = 0;
+};
+
+#endif /* COMMON_COMMON_REGCACHE_H */
diff --git a/gdb/gdbsupport/common-types.h b/gdb/gdbsupport/common-types.h
new file mode 100644
index 00000000000..ed73f6f990a
--- /dev/null
+++ b/gdb/gdbsupport/common-types.h
@@ -0,0 +1,66 @@
+/* Declarations for common types.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_COMMON_TYPES_H
+#define COMMON_COMMON_TYPES_H
+
+#ifdef GDBSERVER
+
+/* * A byte from the program being debugged. */
+typedef unsigned char gdb_byte;
+
+typedef unsigned long long CORE_ADDR;
+
+typedef long long LONGEST;
+typedef unsigned long long ULONGEST;
+
+#else /* GDBSERVER */
+
+#include "bfd.h"
+
+/* * A byte from the program being debugged. */
+typedef bfd_byte gdb_byte;
+
+/* * An address in the program being debugged. Host byte order. */
+typedef bfd_vma CORE_ADDR;
+
+/* This is to make sure that LONGEST is at least as big as CORE_ADDR. */
+
+#ifdef BFD64
+
+typedef BFD_HOST_64_BIT LONGEST;
+typedef BFD_HOST_U_64_BIT ULONGEST;
+
+#else /* No BFD64 */
+
+typedef long long LONGEST;
+typedef unsigned long long ULONGEST;
+
+#endif /* No BFD64 */
+#endif /* GDBSERVER */
+
+/* * The largest CORE_ADDR value. */
+#define CORE_ADDR_MAX (~(CORE_ADDR) 0)
+
+/* * The largest ULONGEST value. */
+#define ULONGEST_MAX (~(ULONGEST) 0)
+
+enum tribool { TRIBOOL_UNKNOWN = -1, TRIBOOL_FALSE = 0, TRIBOOL_TRUE = 1 };
+
+#endif /* COMMON_COMMON_TYPES_H */
diff --git a/gdb/gdbsupport/common-utils.c b/gdb/gdbsupport/common-utils.c
new file mode 100644
index 00000000000..384029db70a
--- /dev/null
+++ b/gdb/gdbsupport/common-utils.c
@@ -0,0 +1,358 @@
+/* Shared general utility routines for GDB, the GNU debugger.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "common-utils.h"
+#include "host-defs.h"
+#include <ctype.h>
+
+void *
+xzalloc (size_t size)
+{
+ return xcalloc (1, size);
+}
+
+/* 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;
+}
+
+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;
+}
+
+/* See documentation in common-utils.h. */
+
+std::string
+string_printf (const char* fmt, ...)
+{
+ va_list vp;
+ int size;
+
+ va_start (vp, fmt);
+ size = vsnprintf (NULL, 0, fmt, vp);
+ va_end (vp);
+
+ std::string str (size, '\0');
+
+ /* C++11 and later guarantee std::string uses contiguous memory and
+ always includes the terminating '\0'. */
+ va_start (vp, fmt);
+ vsprintf (&str[0], fmt, vp);
+ va_end (vp);
+
+ return str;
+}
+
+/* See documentation in common-utils.h. */
+
+std::string
+string_vprintf (const char* fmt, va_list args)
+{
+ va_list vp;
+ size_t size;
+
+ va_copy (vp, args);
+ size = vsnprintf (NULL, 0, fmt, vp);
+ va_end (vp);
+
+ std::string str (size, '\0');
+
+ /* C++11 and later guarantee std::string uses contiguous memory and
+ always includes the terminating '\0'. */
+ vsprintf (&str[0], fmt, args);
+
+ return str;
+}
+
+
+/* See documentation in common-utils.h. */
+
+void
+string_appendf (std::string &str, const char *fmt, ...)
+{
+ va_list vp;
+
+ va_start (vp, fmt);
+ string_vappendf (str, fmt, vp);
+ va_end (vp);
+}
+
+
+/* See documentation in common-utils.h. */
+
+void
+string_vappendf (std::string &str, const char *fmt, va_list args)
+{
+ va_list vp;
+ int grow_size;
+
+ va_copy (vp, args);
+ grow_size = vsnprintf (NULL, 0, fmt, vp);
+ va_end (vp);
+
+ size_t curr_size = str.size ();
+ str.resize (curr_size + grow_size);
+
+ /* C++11 and later guarantee std::string uses contiguous memory and
+ always includes the terminating '\0'. */
+ vsprintf (&str[curr_size], fmt, args);
+}
+
+char *
+savestring (const char *ptr, size_t len)
+{
+ char *p = (char *) xmalloc (len + 1);
+
+ memcpy (p, ptr, len);
+ p[len] = 0;
+ return p;
+}
+
+/* The bit offset of the highest byte in a ULONGEST, for overflow
+ checking. */
+
+#define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT)
+
+/* True (non-zero) iff DIGIT is a valid digit in radix BASE,
+ where 2 <= BASE <= 36. */
+
+static int
+is_digit_in_base (unsigned char digit, int base)
+{
+ if (!isalnum (digit))
+ return 0;
+ if (base <= 10)
+ return (isdigit (digit) && digit < base + '0');
+ else
+ return (isdigit (digit) || tolower (digit) < base - 10 + 'a');
+}
+
+static int
+digit_to_int (unsigned char c)
+{
+ if (isdigit (c))
+ return c - '0';
+ else
+ return tolower (c) - 'a' + 10;
+}
+
+/* As for strtoul, but for ULONGEST results. */
+
+ULONGEST
+strtoulst (const char *num, const char **trailer, int base)
+{
+ unsigned int high_part;
+ ULONGEST result;
+ int minus = 0;
+ int i = 0;
+
+ /* Skip leading whitespace. */
+ while (isspace (num[i]))
+ i++;
+
+ /* Handle prefixes. */
+ if (num[i] == '+')
+ i++;
+ else if (num[i] == '-')
+ {
+ minus = 1;
+ i++;
+ }
+
+ if (base == 0 || base == 16)
+ {
+ if (num[i] == '0' && (num[i + 1] == 'x' || num[i + 1] == 'X'))
+ {
+ i += 2;
+ if (base == 0)
+ base = 16;
+ }
+ }
+
+ if (base == 0 && num[i] == '0')
+ base = 8;
+
+ if (base == 0)
+ base = 10;
+
+ if (base < 2 || base > 36)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ result = high_part = 0;
+ for (; is_digit_in_base (num[i], base); i += 1)
+ {
+ result = result * base + digit_to_int (num[i]);
+ high_part = high_part * base + (unsigned int) (result >> HIGH_BYTE_POSN);
+ result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1;
+ if (high_part > 0xff)
+ {
+ errno = ERANGE;
+ result = ~ (ULONGEST) 0;
+ high_part = 0;
+ minus = 0;
+ break;
+ }
+ }
+
+ if (trailer != NULL)
+ *trailer = &num[i];
+
+ result = result + ((ULONGEST) high_part << HIGH_BYTE_POSN);
+ if (minus)
+ return -result;
+ else
+ return result;
+}
+
+/* See documentation in common-utils.h. */
+
+char *
+skip_spaces (char *chp)
+{
+ if (chp == NULL)
+ return NULL;
+ while (*chp && isspace (*chp))
+ chp++;
+ return chp;
+}
+
+/* A const-correct version of the above. */
+
+const char *
+skip_spaces (const char *chp)
+{
+ if (chp == NULL)
+ return NULL;
+ while (*chp && isspace (*chp))
+ chp++;
+ return chp;
+}
+
+/* See documentation in common-utils.h. */
+
+const char *
+skip_to_space (const char *chp)
+{
+ if (chp == NULL)
+ return NULL;
+ while (*chp && !isspace (*chp))
+ chp++;
+ return chp;
+}
+
+/* See documentation in common-utils.h. */
+
+char *
+skip_to_space (char *chp)
+{
+ return (char *) skip_to_space ((const char *) chp);
+}
+
+/* See gdbsupport/common-utils.h. */
+
+void
+free_vector_argv (std::vector<char *> &v)
+{
+ for (char *el : v)
+ xfree (el);
+
+ v.clear ();
+}
+
+/* See gdbsupport/common-utils.h. */
+
+std::string
+stringify_argv (const std::vector<char *> &args)
+{
+ std::string ret;
+
+ if (!args.empty () && args[0] != NULL)
+ {
+ for (auto s : args)
+ if (s != NULL)
+ {
+ ret += s;
+ ret += ' ';
+ }
+
+ /* Erase the last whitespace. */
+ ret.erase (ret.end () - 1);
+ }
+
+ return ret;
+}
+
+/* See gdbsupport/common-utils.h. */
+
+ULONGEST
+align_up (ULONGEST v, int n)
+{
+ /* Check that N is really a power of two. */
+ gdb_assert (n && (n & (n-1)) == 0);
+ return (v + n - 1) & -n;
+}
+
+/* See gdbsupport/common-utils.h. */
+
+ULONGEST
+align_down (ULONGEST v, int n)
+{
+ /* Check that N is really a power of two. */
+ gdb_assert (n && (n & (n-1)) == 0);
+ return (v & -n);
+}
diff --git a/gdb/gdbsupport/common-utils.h b/gdb/gdbsupport/common-utils.h
new file mode 100644
index 00000000000..52bf3437b1c
--- /dev/null
+++ b/gdb/gdbsupport/common-utils.h
@@ -0,0 +1,181 @@
+/* Shared general utility routines for GDB, the GNU debugger.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_COMMON_UTILS_H
+#define COMMON_COMMON_UTILS_H
+
+#include <string>
+#include <vector>
+
+#include "poison.h"
+
+/* If possible, define FUNCTION_NAME, a macro containing the name of
+ the function being defined. Since this macro may not always be
+ defined, all uses must be protected by appropriate macro definition
+ checks (Eg: "#ifdef FUNCTION_NAME").
+
+ Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
+ which contains the name of the function currently being defined.
+ This is broken in G++ before version 2.6.
+ C9x has a similar variable called __func__, but prefer the GCC one since
+ it demangles C++ function names. */
+#if (GCC_VERSION >= 2004)
+#define FUNCTION_NAME __PRETTY_FUNCTION__
+#else
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#define FUNCTION_NAME __func__ /* ARI: func */
+#endif
+#endif
+
+/* xmalloc(), xrealloc() and xcalloc() have already been declared in
+ "libiberty.h". */
+
+/* Like xmalloc, but zero the memory. */
+void *xzalloc (size_t);
+
+template <typename T>
+static void
+xfree (T *ptr)
+{
+ static_assert (IsFreeable<T>::value, "Trying to use xfree with a non-POD \
+data type. Use operator delete instead.");
+
+ if (ptr != NULL)
+ free (ptr); /* ARI: free */
+}
+
+
+/* Like asprintf and vasprintf, but return the string, throw an error
+ if no memory. */
+char *xstrprintf (const char *format, ...) ATTRIBUTE_PRINTF (1, 2);
+char *xstrvprintf (const char *format, va_list ap)
+ ATTRIBUTE_PRINTF (1, 0);
+
+/* Like snprintf, but throw an error if the output buffer is too small. */
+int xsnprintf (char *str, size_t size, const char *format, ...)
+ ATTRIBUTE_PRINTF (3, 4);
+
+/* Returns a std::string built from a printf-style format string. */
+std::string string_printf (const char* fmt, ...)
+ ATTRIBUTE_PRINTF (1, 2);
+
+/* Like string_printf, but takes a va_list. */
+std::string string_vprintf (const char* fmt, va_list args)
+ ATTRIBUTE_PRINTF (1, 0);
+
+/* Like string_printf, but appends to DEST instead of returning a new
+ std::string. */
+void string_appendf (std::string &dest, const char* fmt, ...)
+ ATTRIBUTE_PRINTF (2, 3);
+
+/* Like string_appendf, but takes a va_list. */
+void string_vappendf (std::string &dest, const char* fmt, va_list args)
+ ATTRIBUTE_PRINTF (2, 0);
+
+/* Make a copy of the string at PTR with LEN characters
+ (and add a null character at the end in the copy).
+ Uses malloc to get the space. Returns the address of the copy. */
+
+char *savestring (const char *ptr, size_t len);
+
+/* The strerror() function can return NULL for errno values that are
+ out of range. Provide a "safe" version that always returns a
+ printable string. */
+
+extern char *safe_strerror (int);
+
+/* Return non-zero if the start of STRING matches PATTERN, zero
+ otherwise. */
+
+static inline int
+startswith (const char *string, const char *pattern)
+{
+ return strncmp (string, pattern, strlen (pattern)) == 0;
+}
+
+ULONGEST strtoulst (const char *num, const char **trailer, int base);
+
+/* Skip leading whitespace characters in INP, returning an updated
+ pointer. If INP is NULL, return NULL. */
+
+extern char *skip_spaces (char *inp);
+
+/* A const-correct version of the above. */
+
+extern const char *skip_spaces (const char *inp);
+
+/* Skip leading non-whitespace characters in INP, returning an updated
+ pointer. If INP is NULL, return NULL. */
+
+extern char *skip_to_space (char *inp);
+
+/* A const-correct version of the above. */
+
+extern const char *skip_to_space (const char *inp);
+
+/* Assumes that V is an argv for a program, and iterates through
+ freeing all the elements. */
+extern void free_vector_argv (std::vector<char *> &v);
+
+/* Given a vector of arguments ARGV, return a string equivalent to
+ joining all the arguments with a whitespace separating them. */
+extern std::string stringify_argv (const std::vector<char *> &argv);
+
+/* Return true if VALUE is in [LOW, HIGH]. */
+
+template <typename T>
+static bool
+in_inclusive_range (T value, T low, T high)
+{
+ return value >= low && value <= high;
+}
+
+/* Ensure that V is aligned to an N byte boundary (B's assumed to be a
+ power of 2). Round up/down when necessary. Examples of correct
+ use include:
+
+ addr = align_up (addr, 8); -- VALUE needs 8 byte alignment
+ write_memory (addr, value, len);
+ addr += len;
+
+ and:
+
+ sp = align_down (sp - len, 16); -- Keep SP 16 byte aligned
+ write_memory (sp, value, len);
+
+ Note that uses such as:
+
+ write_memory (addr, value, len);
+ addr += align_up (len, 8);
+
+ and:
+
+ sp -= align_up (len, 8);
+ write_memory (sp, value, len);
+
+ are typically not correct as they don't ensure that the address (SP
+ or ADDR) is correctly aligned (relying on previous alignment to
+ keep things right). This is also why the methods are called
+ "align_..." instead of "round_..." as the latter reads better with
+ this incorrect coding style. */
+
+extern ULONGEST align_up (ULONGEST v, int n);
+extern ULONGEST align_down (ULONGEST v, int n);
+
+#endif /* COMMON_COMMON_UTILS_H */
diff --git a/gdb/gdbsupport/common.host b/gdb/gdbsupport/common.host
new file mode 100644
index 00000000000..4839059e610
--- /dev/null
+++ b/gdb/gdbsupport/common.host
@@ -0,0 +1,36 @@
+# Common object files to include for each host.
+#
+# Copyright (C) 2015-2019 Free Software Foundation, Inc.
+#
+# This file is part of GDB.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Map host triplet into the common object files to be included by
+# GDB/gdbserver. This is invoked from the autoconf generated
+# configure script.
+
+# This file sets the following shell variables:
+# common_host_obs host-specific .o files to include when building
+# GDB/gdbserver
+
+case "${host}" in
+
+*-mingw*) common_host_obs=gdbsupport/mingw-strerror.o
+ ;;
+*)
+ common_host_obs=gdbsupport/posix-strerror.o
+ ;;
+
+esac
diff --git a/gdb/gdbsupport/common.m4 b/gdb/gdbsupport/common.m4
new file mode 100644
index 00000000000..5701dd98293
--- /dev/null
+++ b/gdb/gdbsupport/common.m4
@@ -0,0 +1,48 @@
+dnl Autoconf configure snippets for common.
+dnl Copyright (C) 1995-2019 Free Software Foundation, Inc.
+dnl
+dnl This file is part of GDB.
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+dnl Invoke configury needed by the files in 'common'.
+AC_DEFUN([GDB_AC_COMMON], [
+ AC_HEADER_STDC
+ AC_FUNC_ALLOCA
+
+ dnl Note that this requires codeset.m4, which is included
+ dnl by the users of common.m4.
+ AM_LANGINFO_CODESET
+
+ AC_CHECK_HEADERS(linux/perf_event.h locale.h memory.h signal.h dnl
+ sys/resource.h sys/socket.h dnl
+ sys/un.h sys/wait.h dnl
+ thread_db.h wait.h dnl
+ termios.h)
+
+ AC_CHECK_FUNCS([fdwalk getrlimit pipe pipe2 socketpair sigaction])
+
+ AC_CHECK_DECLS([strerror, strstr])
+
+ dnl Check if sigsetjmp is available. Using AC_CHECK_FUNCS won't
+ dnl do since sigsetjmp might only be defined as a macro.
+AC_CACHE_CHECK([for sigsetjmp], gdb_cv_func_sigsetjmp,
+[AC_TRY_COMPILE([
+#include <setjmp.h>
+], [sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1);],
+gdb_cv_func_sigsetjmp=yes, gdb_cv_func_sigsetjmp=no)])
+if test $gdb_cv_func_sigsetjmp = yes; then
+ AC_DEFINE(HAVE_SIGSETJMP, 1, [Define if sigsetjmp is available. ])
+fi
+])
diff --git a/gdb/gdbsupport/create-version.sh b/gdb/gdbsupport/create-version.sh
new file mode 100755
index 00000000000..30525babb5a
--- /dev/null
+++ b/gdb/gdbsupport/create-version.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# Copyright (C) 1989-2019 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Create version.c from version.in.
+# Usage:
+# create-version.sh PATH-TO-GDB-SRCDIR HOST_ALIAS \
+# TARGET_ALIAS OUTPUT-FILE-NAME
+
+srcdir="$1"
+host_alias="$2"
+target_alias="$3"
+output="$4"
+
+rm -f version.c-tmp $output version.tmp
+date=`sed -n -e 's/^.* BFD_VERSION_DATE \(.*\)$/\1/p' $srcdir/../bfd/version.h`
+sed -e "s/DATE/$date/" < $srcdir/version.in > version.tmp
+echo '#include "gdbsupport/version.h"' >> version.c-tmp
+echo 'const char version[] = "'"`sed q version.tmp`"'";' >> version.c-tmp
+echo 'const char host_name[] = "'"$host_alias"'";' >> version.c-tmp
+echo 'const char target_name[] = "'"$target_alias"'";' >> version.c-tmp
+mv version.c-tmp $output
+rm -f version.tmp
diff --git a/gdb/gdbsupport/def-vector.h b/gdb/gdbsupport/def-vector.h
new file mode 100644
index 00000000000..fb933b8308d
--- /dev/null
+++ b/gdb/gdbsupport/def-vector.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_DEF_VECTOR_H
+#define COMMON_DEF_VECTOR_H
+
+#include <vector>
+#include "gdbsupport/default-init-alloc.h"
+
+namespace gdb {
+
+/* A vector that uses an allocator that default constructs using
+ default-initialization rather than value-initialization. The idea
+ is to use this when you don't want zero-initialization of elements
+ of vectors of trivial types. E.g., byte buffers. */
+
+template<typename T> using def_vector
+ = std::vector<T, gdb::default_init_allocator<T>>;
+
+} /* namespace gdb */
+
+#endif /* COMMON_DEF_VECTOR_H */
diff --git a/gdb/gdbsupport/default-init-alloc.h b/gdb/gdbsupport/default-init-alloc.h
new file mode 100644
index 00000000000..2d739c9a635
--- /dev/null
+++ b/gdb/gdbsupport/default-init-alloc.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_DEFAULT_INIT_ALLOC_H
+#define COMMON_DEFAULT_INIT_ALLOC_H
+
+namespace gdb {
+
+/* An allocator that default constructs using default-initialization
+ rather than value-initialization. The idea is to use this when you
+ don't want to default construct elements of containers of trivial
+ types using zero-initialization. */
+
+/* Mostly as implementation convenience, this is implemented as an
+ adapter that given an allocator A, overrides 'A::construct()'. 'A'
+ defaults to std::allocator<T>. */
+
+template<typename T, typename A = std::allocator<T>>
+class default_init_allocator : public A
+{
+public:
+ /* Pull in A's ctors. */
+ using A::A;
+
+ /* Override rebind. */
+ template<typename U>
+ struct rebind
+ {
+ /* A couple helpers just to make it a bit more readable. */
+ typedef std::allocator_traits<A> traits_;
+ typedef typename traits_::template rebind_alloc<U> alloc_;
+
+ /* This is what we're after. */
+ typedef default_init_allocator<U, alloc_> other;
+ };
+
+ /* Make the base allocator's construct method(s) visible. */
+ using A::construct;
+
+ /* .. and provide an override/overload for the case of default
+ construction (i.e., no arguments). This is where we construct
+ with default-init. */
+ template <typename U>
+ void construct (U *ptr)
+ noexcept (std::is_nothrow_default_constructible<U>::value)
+ {
+ ::new ((void *) ptr) U; /* default-init */
+ }
+};
+
+} /* namespace gdb */
+
+#endif /* COMMON_DEFAULT_INIT_ALLOC_H */
diff --git a/gdb/gdbsupport/enum-flags.h b/gdb/gdbsupport/enum-flags.h
new file mode 100644
index 00000000000..88ba5910f9d
--- /dev/null
+++ b/gdb/gdbsupport/enum-flags.h
@@ -0,0 +1,221 @@
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_ENUM_FLAGS_H
+#define COMMON_ENUM_FLAGS_H
+
+/* Type-safe wrapper for enum flags. enum flags are enums where the
+ values are bits that are meant to be ORed together.
+
+ This allows writing code like the below, while with raw enums this
+ would fail to compile without casts to enum type at the assignments
+ to 'f':
+
+ enum some_flag
+ {
+ flag_val1 = 1 << 1,
+ flag_val2 = 1 << 2,
+ flag_val3 = 1 << 3,
+ flag_val4 = 1 << 4,
+ };
+ DEF_ENUM_FLAGS_TYPE(enum some_flag, some_flags);
+
+ some_flags f = flag_val1 | flag_val2;
+ f |= flag_val3;
+
+ It's also possible to assign literal zero to an enum flags variable
+ (meaning, no flags), dispensing adding an awkward explicit "no
+ value" value to the enumeration. For example:
+
+ some_flags f = 0;
+ f |= flag_val3 | flag_val4;
+
+ Note that literal integers other than zero fail to compile:
+
+ some_flags f = 1; // error
+*/
+
+#ifdef __cplusplus
+
+/* Traits type used to prevent the global operator overloads from
+ instantiating for non-flag enums. */
+template<typename T> struct enum_flags_type {};
+
+/* Use this to mark an enum as flags enum. It defines FLAGS as
+ enum_flags wrapper class for ENUM, and enables the global operator
+ overloads for ENUM. */
+#define DEF_ENUM_FLAGS_TYPE(enum_type, flags_type) \
+ typedef enum_flags<enum_type> flags_type; \
+ template<> \
+ struct enum_flags_type<enum_type> \
+ { \
+ typedef enum_flags<enum_type> type; \
+ }
+
+/* Until we can rely on std::underlying type being universally
+ available (C++11), roll our own for enums. */
+template<int size, bool sign> class integer_for_size { typedef void type; };
+template<> struct integer_for_size<1, 0> { typedef uint8_t type; };
+template<> struct integer_for_size<2, 0> { typedef uint16_t type; };
+template<> struct integer_for_size<4, 0> { typedef uint32_t type; };
+template<> struct integer_for_size<8, 0> { typedef uint64_t type; };
+template<> struct integer_for_size<1, 1> { typedef int8_t type; };
+template<> struct integer_for_size<2, 1> { typedef int16_t type; };
+template<> struct integer_for_size<4, 1> { typedef int32_t type; };
+template<> struct integer_for_size<8, 1> { typedef int64_t type; };
+
+template<typename T>
+struct enum_underlying_type
+{
+ typedef typename
+ integer_for_size<sizeof (T), static_cast<bool>(T (-1) < T (0))>::type
+ type;
+};
+
+template <typename E>
+class enum_flags
+{
+public:
+ typedef E enum_type;
+ typedef typename enum_underlying_type<enum_type>::type underlying_type;
+
+private:
+ /* Private type used to support initializing flag types with zero:
+
+ foo_flags f = 0;
+
+ but not other integers:
+
+ foo_flags f = 1;
+
+ The way this works is that we define an implicit constructor that
+ takes a pointer to this private type. Since nothing can
+ instantiate an object of this type, the only possible pointer to
+ pass to the constructor is the NULL pointer, or, zero. */
+ struct zero_type;
+
+ underlying_type
+ underlying_value () const
+ {
+ return m_enum_value;
+ }
+
+public:
+ /* Allow default construction. */
+ enum_flags ()
+ : m_enum_value ((enum_type) 0)
+ {}
+
+ /* If you get an error saying these two overloads are ambiguous,
+ then you tried to mix values of different enum types. */
+ enum_flags (enum_type e)
+ : m_enum_value (e)
+ {}
+ enum_flags (struct enum_flags::zero_type *zero)
+ : m_enum_value ((enum_type) 0)
+ {}
+
+ enum_flags &operator&= (enum_type e)
+ {
+ m_enum_value = (enum_type) (underlying_value () & e);
+ return *this;
+ }
+ enum_flags &operator|= (enum_type e)
+ {
+ m_enum_value = (enum_type) (underlying_value () | e);
+ return *this;
+ }
+ enum_flags &operator^= (enum_type e)
+ {
+ m_enum_value = (enum_type) (underlying_value () ^ e);
+ return *this;
+ }
+
+ operator enum_type () const
+ {
+ return m_enum_value;
+ }
+
+ enum_flags operator& (enum_type e) const
+ {
+ return (enum_type) (underlying_value () & e);
+ }
+ enum_flags operator| (enum_type e) const
+ {
+ return (enum_type) (underlying_value () | e);
+ }
+ enum_flags operator^ (enum_type e) const
+ {
+ return (enum_type) (underlying_value () ^ e);
+ }
+ enum_flags operator~ () const
+ {
+ // We only the underlying type to be unsigned when actually using
+ // operator~ -- if it were not unsigned, undefined behavior could
+ // result. However, asserting this in the class itself would
+ // require too many unnecessary changes to otherwise ok enum
+ // types.
+ gdb_static_assert (std::is_unsigned<underlying_type>::value);
+ return (enum_type) ~underlying_value ();
+ }
+
+private:
+ /* Stored as enum_type because GDB knows to print the bit flags
+ neatly if the enum values look like bit flags. */
+ enum_type m_enum_value;
+};
+
+/* Global operator overloads. */
+
+template <typename enum_type>
+typename enum_flags_type<enum_type>::type
+operator& (enum_type e1, enum_type e2)
+{
+ return enum_flags<enum_type> (e1) & e2;
+}
+
+template <typename enum_type>
+typename enum_flags_type<enum_type>::type
+operator| (enum_type e1, enum_type e2)
+{
+ return enum_flags<enum_type> (e1) | e2;
+}
+
+template <typename enum_type>
+typename enum_flags_type<enum_type>::type
+operator^ (enum_type e1, enum_type e2)
+{
+ return enum_flags<enum_type> (e1) ^ e2;
+}
+
+template <typename enum_type>
+typename enum_flags_type<enum_type>::type
+operator~ (enum_type e)
+{
+ return ~enum_flags<enum_type> (e);
+}
+
+#else /* __cplusplus */
+
+/* In C, the flags type is just a typedef for the enum type. */
+
+#define DEF_ENUM_FLAGS_TYPE(enum_type, flags_type) \
+ typedef enum_type flags_type
+
+#endif /* __cplusplus */
+
+#endif /* COMMON_ENUM_FLAGS_H */
diff --git a/gdb/gdbsupport/environ.c b/gdb/gdbsupport/environ.c
new file mode 100644
index 00000000000..006d80afdce
--- /dev/null
+++ b/gdb/gdbsupport/environ.c
@@ -0,0 +1,183 @@
+/* environ.c -- library for manipulating environments for GNU.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "environ.h"
+#include <algorithm>
+#include <utility>
+
+/* See gdbsupport/environ.h. */
+
+gdb_environ &
+gdb_environ::operator= (gdb_environ &&e)
+{
+ /* Are we self-moving? */
+ if (&e == this)
+ return *this;
+
+ m_environ_vector = std::move (e.m_environ_vector);
+ m_user_set_env = std::move (e.m_user_set_env);
+ m_user_unset_env = std::move (e.m_user_unset_env);
+ e.m_environ_vector.clear ();
+ e.m_environ_vector.push_back (NULL);
+ e.m_user_set_env.clear ();
+ e.m_user_unset_env.clear ();
+ return *this;
+}
+
+/* See gdbsupport/environ.h. */
+
+gdb_environ gdb_environ::from_host_environ ()
+{
+ extern char **environ;
+ gdb_environ e;
+
+ if (environ == NULL)
+ return e;
+
+ for (int i = 0; environ[i] != NULL; ++i)
+ {
+ /* Make sure we add the element before the last (NULL). */
+ e.m_environ_vector.insert (e.m_environ_vector.end () - 1,
+ xstrdup (environ[i]));
+ }
+
+ return e;
+}
+
+/* See gdbsupport/environ.h. */
+
+void
+gdb_environ::clear ()
+{
+ for (char *v : m_environ_vector)
+ xfree (v);
+ m_environ_vector.clear ();
+ /* Always add the NULL element. */
+ m_environ_vector.push_back (NULL);
+ m_user_set_env.clear ();
+ m_user_unset_env.clear ();
+}
+
+/* Helper function to check if STRING contains an environment variable
+ assignment of VAR, i.e., if STRING starts with 'VAR='. Return true
+ if it contains, false otherwise. */
+
+static bool
+match_var_in_string (const char *string, const char *var, size_t var_len)
+{
+ if (strncmp (string, var, var_len) == 0 && string[var_len] == '=')
+ return true;
+
+ return false;
+}
+
+/* See gdbsupport/environ.h. */
+
+const char *
+gdb_environ::get (const char *var) const
+{
+ size_t len = strlen (var);
+
+ for (char *el : m_environ_vector)
+ if (el != NULL && match_var_in_string (el, var, len))
+ return &el[len + 1];
+
+ return NULL;
+}
+
+/* See gdbsupport/environ.h. */
+
+void
+gdb_environ::set (const char *var, const char *value)
+{
+ char *fullvar = concat (var, "=", value, NULL);
+
+ /* We have to unset the variable in the vector if it exists. */
+ unset (var, false);
+
+ /* Insert the element before the last one, which is always NULL. */
+ m_environ_vector.insert (m_environ_vector.end () - 1, fullvar);
+
+ /* Mark this environment variable as having been set by the user.
+ This will be useful when we deal with setting environment
+ variables on the remote target. */
+ m_user_set_env.insert (std::string (fullvar));
+
+ /* If this environment variable is marked as unset by the user, then
+ remove it from the list, because now the user wants to set
+ it. */
+ m_user_unset_env.erase (std::string (var));
+}
+
+/* See gdbsupport/environ.h. */
+
+void
+gdb_environ::unset (const char *var, bool update_unset_list)
+{
+ size_t len = strlen (var);
+ std::vector<char *>::iterator it_env;
+
+ /* We iterate until '.end () - 1' because the last element is
+ always NULL. */
+ for (it_env = m_environ_vector.begin ();
+ it_env != m_environ_vector.end () - 1;
+ ++it_env)
+ if (match_var_in_string (*it_env, var, len))
+ break;
+
+ if (it_env != m_environ_vector.end () - 1)
+ {
+ m_user_set_env.erase (std::string (*it_env));
+ xfree (*it_env);
+
+ m_environ_vector.erase (it_env);
+ }
+
+ if (update_unset_list)
+ m_user_unset_env.insert (std::string (var));
+}
+
+/* See gdbsupport/environ.h. */
+
+void
+gdb_environ::unset (const char *var)
+{
+ unset (var, true);
+}
+
+/* See gdbsupport/environ.h. */
+
+char **
+gdb_environ::envp () const
+{
+ return const_cast<char **> (&m_environ_vector[0]);
+}
+
+/* See gdbsupport/environ.h. */
+
+const std::set<std::string> &
+gdb_environ::user_set_env () const
+{
+ return m_user_set_env;
+}
+
+const std::set<std::string> &
+gdb_environ::user_unset_env () const
+{
+ return m_user_unset_env;
+}
diff --git a/gdb/gdbsupport/environ.h b/gdb/gdbsupport/environ.h
new file mode 100644
index 00000000000..8a6b907c9b4
--- /dev/null
+++ b/gdb/gdbsupport/environ.h
@@ -0,0 +1,103 @@
+/* Header for environment manipulation library.
+ Copyright (C) 1989-2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_ENVIRON_H
+#define COMMON_ENVIRON_H
+
+#include <vector>
+#include <set>
+
+/* Class that represents the environment variables as seen by the
+ inferior. */
+
+class gdb_environ
+{
+public:
+ /* Regular constructor and destructor. */
+ gdb_environ ()
+ {
+ /* Make sure that the vector contains at least a NULL element.
+ If/when we add more variables to it, NULL will always be the
+ last element. */
+ m_environ_vector.push_back (NULL);
+ }
+
+ ~gdb_environ ()
+ {
+ clear ();
+ }
+
+ /* Move constructor. */
+ gdb_environ (gdb_environ &&e)
+ : m_environ_vector (std::move (e.m_environ_vector)),
+ m_user_set_env (std::move (e.m_user_set_env)),
+ m_user_unset_env (std::move (e.m_user_unset_env))
+ {
+ /* Make sure that the moved-from vector is left at a valid
+ state (only one NULL element). */
+ e.m_environ_vector.clear ();
+ e.m_environ_vector.push_back (NULL);
+ e.m_user_set_env.clear ();
+ e.m_user_unset_env.clear ();
+ }
+
+ /* Move assignment. */
+ gdb_environ &operator= (gdb_environ &&e);
+
+ /* Create a gdb_environ object using the host's environment
+ variables. */
+ static gdb_environ from_host_environ ();
+
+ /* Clear the environment variables stored in the object. */
+ void clear ();
+
+ /* Return the value in the environment for the variable VAR. The
+ returned pointer is only valid as long as the gdb_environ object
+ is not modified. */
+ const char *get (const char *var) const;
+
+ /* Store VAR=VALUE in the environment. */
+ void set (const char *var, const char *value);
+
+ /* Unset VAR in environment. */
+ void unset (const char *var);
+
+ /* Return the environment vector represented as a 'char **'. */
+ char **envp () const;
+
+ /* Return the user-set environment vector. */
+ const std::set<std::string> &user_set_env () const;
+
+ /* Return the user-unset environment vector. */
+ const std::set<std::string> &user_unset_env () const;
+
+private:
+ /* Unset VAR in environment. If UPDATE_UNSET_LIST is true, then
+ also update M_USER_UNSET_ENV to reflect the unsetting of the
+ environment variable. */
+ void unset (const char *var, bool update_unset_list);
+
+ /* A vector containing the environment variables. */
+ std::vector<char *> m_environ_vector;
+
+ /* The environment variables explicitly set by the user. */
+ std::set<std::string> m_user_set_env;
+
+ /* The environment variables explicitly unset by the user. */
+ std::set<std::string> m_user_unset_env;
+};
+
+#endif /* COMMON_ENVIRON_H */
diff --git a/gdb/gdbsupport/errors.c b/gdb/gdbsupport/errors.c
new file mode 100644
index 00000000000..96be0381850
--- /dev/null
+++ b/gdb/gdbsupport/errors.c
@@ -0,0 +1,69 @@
+/* Error reporting facilities.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "errors.h"
+
+/* See gdbsupport/errors.h. */
+
+void
+warning (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ vwarning (fmt, ap);
+ va_end (ap);
+}
+
+/* See gdbsupport/errors.h. */
+
+void
+error (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ verror (fmt, ap);
+ va_end (ap);
+}
+
+/* See gdbsupport/errors.h. */
+
+void
+internal_error (const char *file, int line, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ internal_verror (file, line, fmt, ap);
+ va_end (ap);
+}
+
+/* See gdbsupport/errors.h. */
+
+void
+internal_warning (const char *file, int line, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ internal_vwarning (file, line, fmt, ap);
+ va_end (ap);
+}
diff --git a/gdb/gdbsupport/errors.h b/gdb/gdbsupport/errors.h
new file mode 100644
index 00000000000..8dbc6cff5f6
--- /dev/null
+++ b/gdb/gdbsupport/errors.h
@@ -0,0 +1,90 @@
+/* Declarations for error-reporting facilities.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_ERRORS_H
+#define COMMON_ERRORS_H
+
+/* A problem was detected, but the requested operation can still
+ proceed. A warning message is constructed using a printf- or
+ vprintf-style argument list. The function "vwarning" must be
+ provided by the client. */
+
+extern void warning (const char *fmt, ...)
+ ATTRIBUTE_PRINTF (1, 2);
+
+extern void vwarning (const char *fmt, va_list args)
+ ATTRIBUTE_PRINTF (1, 0);
+
+/* A non-predictable, non-fatal error was detected. The requested
+ operation cannot proceed. An error message is constructed using
+ a printf- or vprintf-style argument list. These functions do not
+ return. The function "verror" must be provided by the client. */
+
+extern void error (const char *fmt, ...)
+ ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2);
+
+extern void verror (const char *fmt, va_list args)
+ ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0);
+
+/* An internal error was detected. Internal errors indicate
+ programming errors such as assertion failures, as opposed to
+ more general errors beyond the application's control. These
+ functions do not return. An error message is constructed using
+ a printf- or vprintf-style argument list. FILE and LINE
+ indicate the file and line number where the programming error
+ was detected. The function "internal_verror" must be provided
+ by the client. */
+
+extern void internal_error (const char *file, int line,
+ const char *fmt, ...)
+ ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 4);
+
+extern void internal_verror (const char *file, int line,
+ const char *fmt, va_list args)
+ ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0);
+
+/* An internal problem was detected, but the requested operation can
+ still proceed. Internal warnings indicate programming errors as
+ opposed to more general issues beyond the application's control.
+ A warning message is constructed using a printf- or vprintf-style
+ argument list. The function "internal_vwarning" must be provided
+ by the client. */
+
+extern void internal_warning (const char *file, int line,
+ const char *fmt, ...)
+ ATTRIBUTE_PRINTF (3, 4);
+
+extern void internal_vwarning (const char *file, int line,
+ const char *fmt, va_list args)
+ ATTRIBUTE_PRINTF (3, 0);
+
+
+/* Like "error", but the error message is constructed by combining
+ STRING with the system error message for errno. This function does
+ not return. This function must be provided by the client. */
+
+extern void perror_with_name (const char *string) ATTRIBUTE_NORETURN;
+
+/* Call this function to handle memory allocation failures. This
+ function does not return. This function must be provided by the
+ client. */
+
+extern void malloc_failure (long size) ATTRIBUTE_NORETURN;
+
+#endif /* COMMON_ERRORS_H */
diff --git a/gdb/gdbsupport/fileio.c b/gdb/gdbsupport/fileio.c
new file mode 100644
index 00000000000..28d97fc2f26
--- /dev/null
+++ b/gdb/gdbsupport/fileio.c
@@ -0,0 +1,255 @@
+/* File-I/O functions for GDB, the GNU debugger.
+
+ Copyright (C) 2003-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "fileio.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* See fileio.h. */
+
+int
+host_to_fileio_error (int error)
+{
+ switch (error)
+ {
+ case EPERM:
+ return FILEIO_EPERM;
+ case ENOENT:
+ return FILEIO_ENOENT;
+ case EINTR:
+ return FILEIO_EINTR;
+ case EIO:
+ return FILEIO_EIO;
+ case EBADF:
+ return FILEIO_EBADF;
+ case EACCES:
+ return FILEIO_EACCES;
+ case EFAULT:
+ return FILEIO_EFAULT;
+ case EBUSY:
+ return FILEIO_EBUSY;
+ case EEXIST:
+ return FILEIO_EEXIST;
+ case ENODEV:
+ return FILEIO_ENODEV;
+ case ENOTDIR:
+ return FILEIO_ENOTDIR;
+ case EISDIR:
+ return FILEIO_EISDIR;
+ case EINVAL:
+ return FILEIO_EINVAL;
+ case ENFILE:
+ return FILEIO_ENFILE;
+ case EMFILE:
+ return FILEIO_EMFILE;
+ case EFBIG:
+ return FILEIO_EFBIG;
+ case ENOSPC:
+ return FILEIO_ENOSPC;
+ case ESPIPE:
+ return FILEIO_ESPIPE;
+ case EROFS:
+ return FILEIO_EROFS;
+ case ENOSYS:
+ return FILEIO_ENOSYS;
+ case ENAMETOOLONG:
+ return FILEIO_ENAMETOOLONG;
+ }
+ return FILEIO_EUNKNOWN;
+}
+
+/* See fileio.h. */
+
+int
+fileio_to_host_openflags (int fileio_open_flags, int *open_flags_p)
+{
+ int open_flags = 0;
+
+ if (fileio_open_flags & ~FILEIO_O_SUPPORTED)
+ return -1;
+
+ if (fileio_open_flags & FILEIO_O_CREAT)
+ open_flags |= O_CREAT;
+ if (fileio_open_flags & FILEIO_O_EXCL)
+ open_flags |= O_EXCL;
+ if (fileio_open_flags & FILEIO_O_TRUNC)
+ open_flags |= O_TRUNC;
+ if (fileio_open_flags & FILEIO_O_APPEND)
+ open_flags |= O_APPEND;
+ if (fileio_open_flags & FILEIO_O_RDONLY)
+ open_flags |= O_RDONLY;
+ if (fileio_open_flags & FILEIO_O_WRONLY)
+ open_flags |= O_WRONLY;
+ if (fileio_open_flags & FILEIO_O_RDWR)
+ open_flags |= O_RDWR;
+ /* On systems supporting binary and text mode, always open files
+ in binary mode. */
+#ifdef O_BINARY
+ open_flags |= O_BINARY;
+#endif
+
+ *open_flags_p = open_flags;
+ return 0;
+}
+
+/* See fileio.h. */
+
+int
+fileio_to_host_mode (int fileio_mode, mode_t *mode_p)
+{
+ mode_t mode = 0;
+
+ if (fileio_mode & ~FILEIO_S_SUPPORTED)
+ return -1;
+
+ if (fileio_mode & FILEIO_S_IFREG)
+ mode |= S_IFREG;
+ if (fileio_mode & FILEIO_S_IFDIR)
+ mode |= S_IFDIR;
+ if (fileio_mode & FILEIO_S_IFCHR)
+ mode |= S_IFCHR;
+ if (fileio_mode & FILEIO_S_IRUSR)
+ mode |= S_IRUSR;
+ if (fileio_mode & FILEIO_S_IWUSR)
+ mode |= S_IWUSR;
+ if (fileio_mode & FILEIO_S_IXUSR)
+ mode |= S_IXUSR;
+#ifdef S_IRGRP
+ if (fileio_mode & FILEIO_S_IRGRP)
+ mode |= S_IRGRP;
+#endif
+#ifdef S_IWGRP
+ if (fileio_mode & FILEIO_S_IWGRP)
+ mode |= S_IWGRP;
+#endif
+#ifdef S_IXGRP
+ if (fileio_mode & FILEIO_S_IXGRP)
+ mode |= S_IXGRP;
+#endif
+ if (fileio_mode & FILEIO_S_IROTH)
+ mode |= S_IROTH;
+#ifdef S_IWOTH
+ if (fileio_mode & FILEIO_S_IWOTH)
+ mode |= S_IWOTH;
+#endif
+#ifdef S_IXOTH
+ if (fileio_mode & FILEIO_S_IXOTH)
+ mode |= S_IXOTH;
+#endif
+
+ *mode_p = mode;
+ return 0;
+}
+
+/* Convert a host-format mode_t into a bitmask of File-I/O flags. */
+
+static LONGEST
+fileio_mode_pack (mode_t mode)
+{
+ mode_t tmode = 0;
+
+ if (S_ISREG (mode))
+ tmode |= FILEIO_S_IFREG;
+ if (S_ISDIR (mode))
+ tmode |= FILEIO_S_IFDIR;
+ if (S_ISCHR (mode))
+ tmode |= FILEIO_S_IFCHR;
+ if (mode & S_IRUSR)
+ tmode |= FILEIO_S_IRUSR;
+ if (mode & S_IWUSR)
+ tmode |= FILEIO_S_IWUSR;
+ if (mode & S_IXUSR)
+ tmode |= FILEIO_S_IXUSR;
+#ifdef S_IRGRP
+ if (mode & S_IRGRP)
+ tmode |= FILEIO_S_IRGRP;
+#endif
+#ifdef S_IWGRP
+ if (mode & S_IWGRP)
+ tmode |= FILEIO_S_IWGRP;
+#endif
+#ifdef S_IXGRP
+ if (mode & S_IXGRP)
+ tmode |= FILEIO_S_IXGRP;
+#endif
+ if (mode & S_IROTH)
+ tmode |= FILEIO_S_IROTH;
+#ifdef S_IWOTH
+ if (mode & S_IWOTH)
+ tmode |= FILEIO_S_IWOTH;
+#endif
+#ifdef S_IXOTH
+ if (mode & S_IXOTH)
+ tmode |= FILEIO_S_IXOTH;
+#endif
+ return tmode;
+}
+
+/* Pack a host-format mode_t into an fio_mode_t. */
+
+static void
+host_to_fileio_mode (mode_t num, fio_mode_t fnum)
+{
+ host_to_bigendian (fileio_mode_pack (num), (char *) fnum, 4);
+}
+
+/* Pack a host-format integer into an fio_ulong_t. */
+
+static void
+host_to_fileio_ulong (LONGEST num, fio_ulong_t fnum)
+{
+ host_to_bigendian (num, (char *) fnum, 8);
+}
+
+/* See fileio.h. */
+
+void
+host_to_fileio_stat (struct stat *st, struct fio_stat *fst)
+{
+ LONGEST blksize;
+
+ host_to_fileio_uint ((long) st->st_dev, fst->fst_dev);
+ host_to_fileio_uint ((long) st->st_ino, fst->fst_ino);
+ host_to_fileio_mode (st->st_mode, fst->fst_mode);
+ host_to_fileio_uint ((long) st->st_nlink, fst->fst_nlink);
+ host_to_fileio_uint ((long) st->st_uid, fst->fst_uid);
+ host_to_fileio_uint ((long) st->st_gid, fst->fst_gid);
+ host_to_fileio_uint ((long) st->st_rdev, fst->fst_rdev);
+ host_to_fileio_ulong ((LONGEST) st->st_size, fst->fst_size);
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ blksize = st->st_blksize;
+#else
+ blksize = 512;
+#endif
+ host_to_fileio_ulong (blksize, fst->fst_blksize);
+#if HAVE_STRUCT_STAT_ST_BLOCKS
+ host_to_fileio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks);
+#else
+ /* FIXME: This is correct for DJGPP, but other systems that don't
+ have st_blocks, if any, might prefer 512 instead of st_blksize.
+ (eliz, 30-12-2003) */
+ host_to_fileio_ulong (((LONGEST) st->st_size + blksize - 1)
+ / blksize,
+ fst->fst_blocks);
+#endif
+ host_to_fileio_time (st->st_atime, fst->fst_atime);
+ host_to_fileio_time (st->st_mtime, fst->fst_mtime);
+ host_to_fileio_time (st->st_ctime, fst->fst_ctime);
+}
diff --git a/gdb/gdbsupport/fileio.h b/gdb/gdbsupport/fileio.h
new file mode 100644
index 00000000000..7a2e7c2817e
--- /dev/null
+++ b/gdb/gdbsupport/fileio.h
@@ -0,0 +1,73 @@
+/* File-I/O functions for GDB, the GNU debugger.
+
+ Copyright (C) 2003-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_FILEIO_H
+#define COMMON_FILEIO_H
+
+#include "gdb/fileio.h"
+#include <sys/stat.h>
+
+/* Convert a host-format errno value to a File-I/O error number. */
+
+extern int host_to_fileio_error (int error);
+
+/* Convert File-I/O open flags FFLAGS to host format, storing
+ the result in *FLAGS. Return 0 on success, -1 on error. */
+
+extern int fileio_to_host_openflags (int fflags, int *flags);
+
+/* Convert File-I/O mode FMODE to host format, storing
+ the result in *MODE. Return 0 on success, -1 on error. */
+
+extern int fileio_to_host_mode (int fmode, mode_t *mode);
+
+/* Pack a host-format integer into a byte buffer in big-endian
+ format. BYTES specifies the size of the integer to pack in
+ bytes. */
+
+static inline void
+host_to_bigendian (LONGEST num, char *buf, int bytes)
+{
+ int i;
+
+ for (i = 0; i < bytes; ++i)
+ buf[i] = (num >> (8 * (bytes - i - 1))) & 0xff;
+}
+
+/* Pack a host-format integer into an fio_uint_t. */
+
+static inline void
+host_to_fileio_uint (long num, fio_uint_t fnum)
+{
+ host_to_bigendian ((LONGEST) num, (char *) fnum, 4);
+}
+
+/* Pack a host-format time_t into an fio_time_t. */
+
+static inline void
+host_to_fileio_time (time_t num, fio_time_t fnum)
+{
+ host_to_bigendian ((LONGEST) num, (char *) fnum, 4);
+}
+
+/* Pack a host-format struct stat into a struct fio_stat. */
+
+extern void host_to_fileio_stat (struct stat *st, struct fio_stat *fst);
+
+#endif /* COMMON_FILEIO_H */
diff --git a/gdb/gdbsupport/filestuff.c b/gdb/gdbsupport/filestuff.c
new file mode 100644
index 00000000000..b8fca1552a4
--- /dev/null
+++ b/gdb/gdbsupport/filestuff.c
@@ -0,0 +1,503 @@
+/* Low-level file-handling.
+ Copyright (C) 2012-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "filestuff.h"
+#include "gdb_vecs.h"
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <algorithm>
+
+#ifdef USE_WIN32API
+#include <winsock2.h>
+#include <windows.h>
+#define HAVE_SOCKETS 1
+#elif defined HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+/* Define HAVE_F_GETFD if we plan to use F_GETFD. */
+#define HAVE_F_GETFD F_GETFD
+#define HAVE_SOCKETS 1
+#endif
+
+#ifdef HAVE_KINFO_GETFILE
+#include <sys/user.h>
+#include <libutil.h>
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
+
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+
+#ifndef O_NOINHERIT
+#define O_NOINHERIT 0
+#endif
+
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC 0
+#endif
+
+
+
+#ifndef HAVE_FDWALK
+
+#include <dirent.h>
+
+/* Replacement for fdwalk, if the system doesn't define it. Walks all
+ open file descriptors (though this implementation may walk closed
+ ones as well, depending on the host platform's capabilities) and
+ call FUNC with ARG. If FUNC returns non-zero, stops immediately
+ and returns the same value. Otherwise, returns zero when
+ finished. */
+
+static int
+fdwalk (int (*func) (void *, int), void *arg)
+{
+ /* Checking __linux__ isn't great but it isn't clear what would be
+ better. There doesn't seem to be a good way to check for this in
+ configure. */
+#ifdef __linux__
+ DIR *dir;
+
+ dir = opendir ("/proc/self/fd");
+ if (dir != NULL)
+ {
+ struct dirent *entry;
+ int result = 0;
+
+ for (entry = readdir (dir); entry != NULL; entry = readdir (dir))
+ {
+ long fd;
+ char *tail;
+
+ errno = 0;
+ fd = strtol (entry->d_name, &tail, 10);
+ if (*tail != '\0' || errno != 0)
+ continue;
+ if ((int) fd != fd)
+ {
+ /* What can we do here really? */
+ continue;
+ }
+
+ if (fd == dirfd (dir))
+ continue;
+
+ result = func (arg, fd);
+ if (result != 0)
+ break;
+ }
+
+ closedir (dir);
+ return result;
+ }
+ /* We may fall through to the next case. */
+#endif
+#ifdef HAVE_KINFO_GETFILE
+ int nfd;
+ gdb::unique_xmalloc_ptr<struct kinfo_file[]> fdtbl
+ (kinfo_getfile (getpid (), &nfd));
+ if (fdtbl != NULL)
+ {
+ for (int i = 0; i < nfd; i++)
+ {
+ if (fdtbl[i].kf_fd >= 0)
+ {
+ int result = func (arg, fdtbl[i].kf_fd);
+ if (result != 0)
+ return result;
+ }
+ }
+ return 0;
+ }
+ /* We may fall through to the next case. */
+#endif
+
+ {
+ int max, fd;
+
+#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
+ struct rlimit rlim;
+
+ if (getrlimit (RLIMIT_NOFILE, &rlim) == 0 && rlim.rlim_max != RLIM_INFINITY)
+ max = rlim.rlim_max;
+ else
+#endif
+ {
+#ifdef _SC_OPEN_MAX
+ max = sysconf (_SC_OPEN_MAX);
+#else
+ /* Whoops. */
+ return 0;
+#endif /* _SC_OPEN_MAX */
+ }
+
+ for (fd = 0; fd < max; ++fd)
+ {
+ struct stat sb;
+ int result;
+
+ /* Only call FUNC for open fds. */
+ if (fstat (fd, &sb) == -1)
+ continue;
+
+ result = func (arg, fd);
+ if (result != 0)
+ return result;
+ }
+
+ return 0;
+ }
+}
+
+#endif /* HAVE_FDWALK */
+
+
+
+/* A vector holding all the fds open when notice_open_fds was called. We
+ don't use a hashtab because we don't expect there to be many open fds. */
+
+static std::vector<int> open_fds;
+
+/* An fdwalk callback function used by notice_open_fds. It puts the
+ given file descriptor into the vec. */
+
+static int
+do_mark_open_fd (void *ignore, int fd)
+{
+ open_fds.push_back (fd);
+ return 0;
+}
+
+/* See filestuff.h. */
+
+void
+notice_open_fds (void)
+{
+ fdwalk (do_mark_open_fd, NULL);
+}
+
+/* See filestuff.h. */
+
+void
+mark_fd_no_cloexec (int fd)
+{
+ do_mark_open_fd (NULL, fd);
+}
+
+/* See filestuff.h. */
+
+void
+unmark_fd_no_cloexec (int fd)
+{
+ auto it = std::remove (open_fds.begin (), open_fds.end (), fd);
+
+ if (it != open_fds.end ())
+ open_fds.erase (it);
+ else
+ gdb_assert_not_reached (_("fd not found in open_fds"));
+}
+
+/* Helper function for close_most_fds that closes the file descriptor
+ if appropriate. */
+
+static int
+do_close (void *ignore, int fd)
+{
+ for (int val : open_fds)
+ {
+ if (fd == val)
+ {
+ /* Keep this one open. */
+ return 0;
+ }
+ }
+
+ close (fd);
+ return 0;
+}
+
+/* See filestuff.h. */
+
+void
+close_most_fds (void)
+{
+ fdwalk (do_close, NULL);
+}
+
+
+
+/* This is a tri-state flag. When zero it means we haven't yet tried
+ O_CLOEXEC. When positive it means that O_CLOEXEC works on this
+ host. When negative, it means that O_CLOEXEC doesn't work. We
+ track this state because, while gdb might have been compiled
+ against a libc that supplies O_CLOEXEC, there is no guarantee that
+ the kernel supports it. */
+
+static int trust_o_cloexec;
+
+/* Mark FD as close-on-exec, ignoring errors. Update
+ TRUST_O_CLOEXEC. */
+
+static void
+mark_cloexec (int fd)
+{
+#ifdef HAVE_F_GETFD
+ int old = fcntl (fd, F_GETFD, 0);
+
+ if (old != -1)
+ {
+ fcntl (fd, F_SETFD, old | FD_CLOEXEC);
+
+ if (trust_o_cloexec == 0)
+ {
+ if ((old & FD_CLOEXEC) != 0)
+ trust_o_cloexec = 1;
+ else
+ trust_o_cloexec = -1;
+ }
+ }
+#endif /* HAVE_F_GETFD */
+}
+
+/* Depending on TRUST_O_CLOEXEC, mark FD as close-on-exec. */
+
+static void
+maybe_mark_cloexec (int fd)
+{
+ if (trust_o_cloexec <= 0)
+ mark_cloexec (fd);
+}
+
+#ifdef HAVE_SOCKETS
+
+/* Like maybe_mark_cloexec, but for callers that use SOCK_CLOEXEC. */
+
+static void
+socket_mark_cloexec (int fd)
+{
+ if (SOCK_CLOEXEC == 0 || trust_o_cloexec <= 0)
+ mark_cloexec (fd);
+}
+
+#endif
+
+
+
+/* See filestuff.h. */
+
+int
+gdb_open_cloexec (const char *filename, int flags, unsigned long mode)
+{
+ int fd = open (filename, flags | O_CLOEXEC, mode);
+
+ if (fd >= 0)
+ maybe_mark_cloexec (fd);
+
+ return fd;
+}
+
+/* See filestuff.h. */
+
+gdb_file_up
+gdb_fopen_cloexec (const char *filename, const char *opentype)
+{
+ FILE *result;
+ /* Probe for "e" support once. But, if we can tell the operating
+ system doesn't know about close on exec mode "e" without probing,
+ skip it. E.g., the Windows runtime issues an "Invalid parameter
+ passed to C runtime function" OutputDebugString warning for
+ unknown modes. Assume that if O_CLOEXEC is zero, then "e" isn't
+ supported. On MinGW, O_CLOEXEC is an alias of O_NOINHERIT, and
+ "e" isn't supported. */
+ static int fopen_e_ever_failed_einval =
+ O_CLOEXEC == 0 || O_CLOEXEC == O_NOINHERIT;
+
+ if (!fopen_e_ever_failed_einval)
+ {
+ char *copy;
+
+ copy = (char *) alloca (strlen (opentype) + 2);
+ strcpy (copy, opentype);
+ /* This is a glibc extension but we try it unconditionally on
+ this path. */
+ strcat (copy, "e");
+ result = fopen (filename, copy);
+
+ if (result == NULL && errno == EINVAL)
+ {
+ result = fopen (filename, opentype);
+ if (result != NULL)
+ fopen_e_ever_failed_einval = 1;
+ }
+ }
+ else
+ result = fopen (filename, opentype);
+
+ if (result != NULL)
+ maybe_mark_cloexec (fileno (result));
+
+ return gdb_file_up (result);
+}
+
+#ifdef HAVE_SOCKETS
+/* See filestuff.h. */
+
+int
+gdb_socketpair_cloexec (int domain, int style, int protocol,
+ int filedes[2])
+{
+#ifdef HAVE_SOCKETPAIR
+ int result = socketpair (domain, style | SOCK_CLOEXEC, protocol, filedes);
+
+ if (result != -1)
+ {
+ socket_mark_cloexec (filedes[0]);
+ socket_mark_cloexec (filedes[1]);
+ }
+
+ return result;
+#else
+ gdb_assert_not_reached (_("socketpair not available on this host"));
+#endif
+}
+
+/* See filestuff.h. */
+
+int
+gdb_socket_cloexec (int domain, int style, int protocol)
+{
+ int result = socket (domain, style | SOCK_CLOEXEC, protocol);
+
+ if (result != -1)
+ socket_mark_cloexec (result);
+
+ return result;
+}
+#endif
+
+/* See filestuff.h. */
+
+int
+gdb_pipe_cloexec (int filedes[2])
+{
+ int result;
+
+#ifdef HAVE_PIPE2
+ result = pipe2 (filedes, O_CLOEXEC);
+ if (result != -1)
+ {
+ maybe_mark_cloexec (filedes[0]);
+ maybe_mark_cloexec (filedes[1]);
+ }
+#else
+#ifdef HAVE_PIPE
+ result = pipe (filedes);
+ if (result != -1)
+ {
+ mark_cloexec (filedes[0]);
+ mark_cloexec (filedes[1]);
+ }
+#else /* HAVE_PIPE */
+ gdb_assert_not_reached (_("pipe not available on this host"));
+#endif /* HAVE_PIPE */
+#endif /* HAVE_PIPE2 */
+
+ return result;
+}
+
+/* See gdbsupport/filestuff.h. */
+
+bool
+is_regular_file (const char *name, int *errno_ptr)
+{
+ struct stat st;
+ const int status = stat (name, &st);
+
+ /* Stat should never fail except when the file does not exist.
+ If stat fails, analyze the source of error and return true
+ unless the file does not exist, to avoid returning false results
+ on obscure systems where stat does not work as expected. */
+
+ if (status != 0)
+ {
+ if (errno != ENOENT)
+ return true;
+ *errno_ptr = ENOENT;
+ return false;
+ }
+
+ if (S_ISREG (st.st_mode))
+ return true;
+
+ if (S_ISDIR (st.st_mode))
+ *errno_ptr = EISDIR;
+ else
+ *errno_ptr = EINVAL;
+ return false;
+}
+
+/* See gdbsupport/filestuff.h. */
+
+bool
+mkdir_recursive (const char *dir)
+{
+ auto holder = make_unique_xstrdup (dir);
+ char * const start = holder.get ();
+ char *component_start = start;
+ char *component_end = start;
+
+ while (1)
+ {
+ /* Find the beginning of the next component. */
+ while (*component_start == '/')
+ component_start++;
+
+ /* Are we done? */
+ if (*component_start == '\0')
+ return true;
+
+ /* Find the slash or null-terminator after this component. */
+ component_end = component_start;
+ while (*component_end != '/' && *component_end != '\0')
+ component_end++;
+
+ /* Temporarily replace the slash with a null terminator, so we can create
+ the directory up to this component. */
+ char saved_char = *component_end;
+ *component_end = '\0';
+
+ /* If we get EEXIST and the existing path is a directory, then we're
+ happy. If it exists, but it's a regular file and this is not the last
+ component, we'll fail at the next component. If this is the last
+ component, the caller will fail with ENOTDIR when trying to
+ open/create a file under that path. */
+ if (mkdir (start, 0700) != 0)
+ if (errno != EEXIST)
+ return false;
+
+ /* Restore the overwritten char. */
+ *component_end = saved_char;
+ component_start = component_end;
+ }
+}
diff --git a/gdb/gdbsupport/filestuff.h b/gdb/gdbsupport/filestuff.h
new file mode 100644
index 00000000000..c50781da01c
--- /dev/null
+++ b/gdb/gdbsupport/filestuff.h
@@ -0,0 +1,142 @@
+/* Low-level file-handling.
+ Copyright (C) 2012-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_FILESTUFF_H
+#define COMMON_FILESTUFF_H
+
+#include <dirent.h>
+#include <fcntl.h>
+
+/* Note all the file descriptors which are open when this is called.
+ These file descriptors will not be closed by close_most_fds. */
+
+extern void notice_open_fds (void);
+
+/* Mark a file descriptor as inheritable across an exec. */
+
+extern void mark_fd_no_cloexec (int fd);
+
+/* Mark a file descriptor as no longer being inheritable across an
+ exec. This is only meaningful when FD was previously passed to
+ mark_fd_no_cloexec. */
+
+extern void unmark_fd_no_cloexec (int fd);
+
+/* Close all open file descriptors other than those marked by
+ 'notice_open_fds', and stdin, stdout, and stderr. Errors that
+ occur while closing are ignored. */
+
+extern void close_most_fds (void);
+
+/* Like 'open', but ensures that the returned file descriptor has the
+ close-on-exec flag set. */
+
+extern int gdb_open_cloexec (const char *filename, int flags,
+ /* mode_t */ unsigned long mode);
+
+/* Like mkstemp, but ensures that the file descriptor is
+ close-on-exec. */
+
+static inline int
+gdb_mkostemp_cloexec (char *name_template, int flags = 0)
+{
+ /* gnulib provides a mkostemp replacement if needed. */
+ return mkostemp (name_template, flags | O_CLOEXEC);
+}
+
+/* Convenience wrapper for the above, which takes the filename as an
+ std::string. */
+
+static inline int
+gdb_open_cloexec (const std::string &filename, int flags,
+ /* mode_t */ unsigned long mode)
+{
+ return gdb_open_cloexec (filename.c_str (), flags, mode);
+}
+
+struct gdb_file_deleter
+{
+ void operator() (FILE *file) const
+ {
+ fclose (file);
+ }
+};
+
+/* A unique pointer to a FILE. */
+
+typedef std::unique_ptr<FILE, gdb_file_deleter> gdb_file_up;
+
+/* Like 'fopen', but ensures that the returned file descriptor has the
+ close-on-exec flag set. */
+
+extern gdb_file_up gdb_fopen_cloexec (const char *filename,
+ const char *opentype);
+
+/* Convenience wrapper for the above, which takes the filename as an
+ std::string. */
+
+static inline gdb_file_up
+gdb_fopen_cloexec (const std::string &filename, const char *opentype)
+{
+ return gdb_fopen_cloexec (filename.c_str (), opentype);
+}
+
+/* Like 'socketpair', but ensures that the returned file descriptors
+ have the close-on-exec flag set. */
+
+extern int gdb_socketpair_cloexec (int domain, int style, int protocol,
+ int filedes[2]);
+
+/* Like 'socket', but ensures that the returned file descriptor has
+ the close-on-exec flag set. */
+
+extern int gdb_socket_cloexec (int domain, int style, int protocol);
+
+/* Like 'pipe', but ensures that the returned file descriptors have
+ the close-on-exec flag set. */
+
+extern int gdb_pipe_cloexec (int filedes[2]);
+
+struct gdb_dir_deleter
+{
+ void operator() (DIR *dir) const
+ {
+ closedir (dir);
+ }
+};
+
+/* A unique pointer to a DIR. */
+
+typedef std::unique_ptr<DIR, gdb_dir_deleter> gdb_dir_up;
+
+/* Return true if the file NAME exists and is a regular file.
+ If the result is false then *ERRNO_PTR is set to a useful value assuming
+ we're expecting a regular file. */
+extern bool is_regular_file (const char *name, int *errno_ptr);
+
+
+/* A cheap (as in low-quality) recursive mkdir. Try to create all the
+ parents directories up to DIR and DIR itself. Stop if we hit an
+ error along the way. There is no attempt to remove created
+ directories in case of failure.
+
+ Returns false on failure and sets errno. */
+
+extern bool mkdir_recursive (const char *dir);
+
+#endif /* COMMON_FILESTUFF_H */
diff --git a/gdb/gdbsupport/filtered-iterator.h b/gdb/gdbsupport/filtered-iterator.h
new file mode 100644
index 00000000000..e1b486d6f08
--- /dev/null
+++ b/gdb/gdbsupport/filtered-iterator.h
@@ -0,0 +1,87 @@
+/* A forward filtered iterator for GDB, the GNU debugger.
+ Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_FILTERED_ITERATOR_H
+#define COMMON_FILTERED_ITERATOR_H
+
+/* A filtered iterator. This wraps BaseIterator and automatically
+ skips elements that FilterFunc filters out. Requires that
+ default-constructing a BaseIterator creates a valid one-past-end
+ iterator. */
+
+template<typename BaseIterator, typename FilterFunc>
+class filtered_iterator
+{
+public:
+ typedef filtered_iterator self_type;
+ typedef typename BaseIterator::value_type value_type;
+ typedef typename BaseIterator::reference reference;
+ typedef typename BaseIterator::pointer pointer;
+ typedef typename BaseIterator::iterator_category iterator_category;
+ typedef typename BaseIterator::difference_type difference_type;
+
+ /* Construct by forwarding all arguments to the underlying
+ iterator. */
+ template<typename... Args>
+ explicit filtered_iterator (Args &&...args)
+ : m_it (std::forward<Args> (args)...)
+ { skip_filtered (); }
+
+ /* Create a one-past-end iterator. */
+ filtered_iterator () = default;
+
+ /* Need these as the variadic constructor would be a better match
+ otherwise. */
+ filtered_iterator (filtered_iterator &) = default;
+ filtered_iterator (const filtered_iterator &) = default;
+ filtered_iterator (filtered_iterator &&) = default;
+ filtered_iterator (const filtered_iterator &&other)
+ : filtered_iterator (static_cast<const filtered_iterator &> (other))
+ {}
+
+ value_type operator* () const { return *m_it; }
+
+ self_type &operator++ ()
+ {
+ ++m_it;
+ skip_filtered ();
+ return *this;
+ }
+
+ bool operator== (const self_type &other) const
+ { return *m_it == *other.m_it; }
+
+ bool operator!= (const self_type &other) const
+ { return *m_it != *other.m_it; }
+
+private:
+
+ void skip_filtered ()
+ {
+ for (; m_it != m_end; ++m_it)
+ if (m_filter (*m_it))
+ break;
+ }
+
+private:
+ FilterFunc m_filter {};
+ BaseIterator m_it {};
+ BaseIterator m_end {};
+};
+
+#endif /* COMMON_FILTERED_ITERATOR_H */
diff --git a/gdb/gdbsupport/format.c b/gdb/gdbsupport/format.c
new file mode 100644
index 00000000000..fb3421e62bf
--- /dev/null
+++ b/gdb/gdbsupport/format.c
@@ -0,0 +1,350 @@
+/* Parse a printf-style format string.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "format.h"
+
+format_pieces::format_pieces (const char **arg)
+{
+ const char *s;
+ char *f, *string;
+ const char *prev_start;
+ const char *percent_loc;
+ char *sub_start, *current_substring;
+ enum argclass this_argclass;
+
+ s = *arg;
+
+ /* Parse the format-control string and copy it into the string STRING,
+ processing some kinds of escape sequence. */
+
+ f = string = (char *) alloca (strlen (s) + 1);
+
+ while (*s != '"' && *s != '\0')
+ {
+ int c = *s++;
+ switch (c)
+ {
+ case '\0':
+ continue;
+
+ case '\\':
+ switch (c = *s++)
+ {
+ case '\\':
+ *f++ = '\\';
+ break;
+ case 'a':
+ *f++ = '\a';
+ break;
+ case 'b':
+ *f++ = '\b';
+ break;
+ case 'e':
+ *f++ = '\e';
+ break;
+ case 'f':
+ *f++ = '\f';
+ break;
+ case 'n':
+ *f++ = '\n';
+ break;
+ case 'r':
+ *f++ = '\r';
+ break;
+ case 't':
+ *f++ = '\t';
+ break;
+ case 'v':
+ *f++ = '\v';
+ break;
+ case '"':
+ *f++ = '"';
+ break;
+ default:
+ /* ??? TODO: handle other escape sequences. */
+ error (_("Unrecognized escape character \\%c in format string."),
+ c);
+ }
+ break;
+
+ default:
+ *f++ = c;
+ }
+ }
+
+ /* Terminate our escape-processed copy. */
+ *f++ = '\0';
+
+ /* Whether the format string ended with double-quote or zero, we're
+ done with it; it's up to callers to complain about syntax. */
+ *arg = s;
+
+ /* Need extra space for the '\0's. Doubling the size is sufficient. */
+
+ current_substring = (char *) xmalloc (strlen (string) * 2 + 1000);
+ m_storage.reset (current_substring);
+
+ /* Now scan the string for %-specs and see what kinds of args they want.
+ argclass classifies the %-specs so we can give printf-type functions
+ something of the right size. */
+
+ f = string;
+ prev_start = string;
+ while (*f)
+ if (*f++ == '%')
+ {
+ int seen_hash = 0, seen_zero = 0, lcount = 0, seen_prec = 0;
+ int seen_space = 0, seen_plus = 0;
+ int seen_big_l = 0, seen_h = 0, seen_big_h = 0;
+ int seen_big_d = 0, seen_double_big_d = 0;
+ int bad = 0;
+
+ /* Skip over "%%", it will become part of a literal piece. */
+ if (*f == '%')
+ {
+ f++;
+ continue;
+ }
+
+ sub_start = current_substring;
+
+ strncpy (current_substring, prev_start, f - 1 - prev_start);
+ current_substring += f - 1 - prev_start;
+ *current_substring++ = '\0';
+
+ m_pieces.emplace_back (sub_start, literal_piece);
+
+ percent_loc = f - 1;
+
+ /* Check the validity of the format specifier, and work
+ out what argument it expects. We only accept C89
+ format strings, with the exception of long long (which
+ we autoconf for). */
+
+ /* The first part of a format specifier is a set of flag
+ characters. */
+ while (*f != '\0' && strchr ("0-+ #", *f))
+ {
+ if (*f == '#')
+ seen_hash = 1;
+ else if (*f == '0')
+ seen_zero = 1;
+ else if (*f == ' ')
+ seen_space = 1;
+ else if (*f == '+')
+ seen_plus = 1;
+ f++;
+ }
+
+ /* The next part of a format specifier is a width. */
+ while (*f != '\0' && strchr ("0123456789", *f))
+ f++;
+
+ /* The next part of a format specifier is a precision. */
+ if (*f == '.')
+ {
+ seen_prec = 1;
+ f++;
+ while (*f != '\0' && strchr ("0123456789", *f))
+ f++;
+ }
+
+ /* The next part of a format specifier is a length modifier. */
+ if (*f == 'h')
+ {
+ seen_h = 1;
+ f++;
+ }
+ else if (*f == 'l')
+ {
+ f++;
+ lcount++;
+ if (*f == 'l')
+ {
+ f++;
+ lcount++;
+ }
+ }
+ else if (*f == 'L')
+ {
+ seen_big_l = 1;
+ f++;
+ }
+ /* Decimal32 modifier. */
+ else if (*f == 'H')
+ {
+ seen_big_h = 1;
+ f++;
+ }
+ /* Decimal64 and Decimal128 modifiers. */
+ else if (*f == 'D')
+ {
+ f++;
+
+ /* Check for a Decimal128. */
+ if (*f == 'D')
+ {
+ f++;
+ seen_double_big_d = 1;
+ }
+ else
+ seen_big_d = 1;
+ }
+
+ switch (*f)
+ {
+ case 'u':
+ if (seen_hash)
+ bad = 1;
+ /* FALLTHROUGH */
+
+ case 'o':
+ case 'x':
+ case 'X':
+ if (seen_space || seen_plus)
+ bad = 1;
+ /* FALLTHROUGH */
+
+ case 'd':
+ case 'i':
+ if (lcount == 0)
+ this_argclass = int_arg;
+ else if (lcount == 1)
+ this_argclass = long_arg;
+ else
+ this_argclass = long_long_arg;
+
+ if (seen_big_l)
+ bad = 1;
+ break;
+
+ case 'c':
+ this_argclass = lcount == 0 ? int_arg : wide_char_arg;
+ if (lcount > 1 || seen_h || seen_big_l)
+ bad = 1;
+ if (seen_prec || seen_zero || seen_space || seen_plus)
+ bad = 1;
+ break;
+
+ case 'p':
+ this_argclass = ptr_arg;
+ if (lcount || seen_h || seen_big_l)
+ bad = 1;
+ if (seen_prec)
+ bad = 1;
+ if (seen_hash || seen_zero || seen_space || seen_plus)
+ bad = 1;
+ break;
+
+ case 's':
+ this_argclass = lcount == 0 ? string_arg : wide_string_arg;
+ if (lcount > 1 || seen_h || seen_big_l)
+ bad = 1;
+ if (seen_zero || seen_space || seen_plus)
+ bad = 1;
+ break;
+
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'E':
+ case 'G':
+ if (seen_double_big_d)
+ this_argclass = dec128float_arg;
+ else if (seen_big_d)
+ this_argclass = dec64float_arg;
+ else if (seen_big_h)
+ this_argclass = dec32float_arg;
+ else if (seen_big_l)
+ this_argclass = long_double_arg;
+ else
+ this_argclass = double_arg;
+
+ if (lcount || seen_h)
+ bad = 1;
+ break;
+
+ case '*':
+ error (_("`*' not supported for precision or width in printf"));
+
+ case 'n':
+ error (_("Format specifier `n' not supported in printf"));
+
+ case '\0':
+ error (_("Incomplete format specifier at end of format string"));
+
+ default:
+ error (_("Unrecognized format specifier '%c' in printf"), *f);
+ }
+
+ if (bad)
+ error (_("Inappropriate modifiers to "
+ "format specifier '%c' in printf"),
+ *f);
+
+ f++;
+
+ sub_start = current_substring;
+
+ if (lcount > 1 && USE_PRINTF_I64)
+ {
+ /* Windows' printf does support long long, but not the usual way.
+ Convert %lld to %I64d. */
+ int length_before_ll = f - percent_loc - 1 - lcount;
+
+ strncpy (current_substring, percent_loc, length_before_ll);
+ strcpy (current_substring + length_before_ll, "I64");
+ current_substring[length_before_ll + 3] =
+ percent_loc[length_before_ll + lcount];
+ current_substring += length_before_ll + 4;
+ }
+ else if (this_argclass == wide_string_arg
+ || this_argclass == wide_char_arg)
+ {
+ /* Convert %ls or %lc to %s. */
+ int length_before_ls = f - percent_loc - 2;
+
+ strncpy (current_substring, percent_loc, length_before_ls);
+ strcpy (current_substring + length_before_ls, "s");
+ current_substring += length_before_ls + 2;
+ }
+ else
+ {
+ strncpy (current_substring, percent_loc, f - percent_loc);
+ current_substring += f - percent_loc;
+ }
+
+ *current_substring++ = '\0';
+
+ prev_start = f;
+
+ m_pieces.emplace_back (sub_start, this_argclass);
+ }
+
+ /* Record the remainder of the string. */
+
+ sub_start = current_substring;
+
+ strncpy (current_substring, prev_start, f - prev_start);
+ current_substring += f - prev_start;
+ *current_substring++ = '\0';
+
+ m_pieces.emplace_back (sub_start, literal_piece);
+}
diff --git a/gdb/gdbsupport/format.h b/gdb/gdbsupport/format.h
new file mode 100644
index 00000000000..08ef66a7602
--- /dev/null
+++ b/gdb/gdbsupport/format.h
@@ -0,0 +1,96 @@
+/* Parse a printf-style format string.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_FORMAT_H
+#define COMMON_FORMAT_H
+
+#include "gdbsupport/gdb_string_view.h"
+
+#if defined(__MINGW32__) && !defined(PRINTF_HAS_LONG_LONG)
+# define USE_PRINTF_I64 1
+# define PRINTF_HAS_LONG_LONG
+#else
+# define USE_PRINTF_I64 0
+#endif
+
+/* The argclass represents the general type of data that goes with a
+ format directive; int_arg for %d, long_arg for %l, and so forth.
+ Note that these primarily distinguish types by size and need for
+ special handling, so for instance %u and %x are (at present) also
+ classed as int_arg. */
+
+enum argclass
+ {
+ literal_piece,
+ int_arg, long_arg, long_long_arg, ptr_arg,
+ string_arg, wide_string_arg, wide_char_arg,
+ double_arg, long_double_arg,
+ dec32float_arg, dec64float_arg, dec128float_arg
+ };
+
+/* A format piece is a section of the format string that may include a
+ single print directive somewhere in it, and the associated class
+ for the argument. */
+
+struct format_piece
+{
+ format_piece (const char *str, enum argclass argc)
+ : string (str),
+ argclass (argc)
+ {
+ }
+
+ bool operator== (const format_piece &other) const
+ {
+ return (this->argclass == other.argclass
+ && gdb::string_view (this->string) == other.string);
+ }
+
+ const char *string;
+ enum argclass argclass;
+};
+
+class format_pieces
+{
+public:
+
+ format_pieces (const char **arg);
+ ~format_pieces () = default;
+
+ DISABLE_COPY_AND_ASSIGN (format_pieces);
+
+ typedef std::vector<format_piece>::iterator iterator;
+
+ iterator begin ()
+ {
+ return m_pieces.begin ();
+ }
+
+ iterator end ()
+ {
+ return m_pieces.end ();
+ }
+
+private:
+
+ std::vector<format_piece> m_pieces;
+ gdb::unique_xmalloc_ptr<char> m_storage;
+};
+
+#endif /* COMMON_FORMAT_H */
diff --git a/gdb/gdbsupport/forward-scope-exit.h b/gdb/gdbsupport/forward-scope-exit.h
new file mode 100644
index 00000000000..bba4027aa5a
--- /dev/null
+++ b/gdb/gdbsupport/forward-scope-exit.h
@@ -0,0 +1,123 @@
+/* Copyright (C) 2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_FORWARD_SCOPE_EXIT_H
+#define COMMON_FORWARD_SCOPE_EXIT_H
+
+#include "gdbsupport/scope-exit.h"
+#include <functional>
+
+/* A forward_scope_exit is like scope_exit, but instead of giving it a
+ callable, you instead specialize it for a given cleanup function,
+ and the generated class automatically has a constructor with the
+ same interface as the cleanup function. forward_scope_exit
+ captures the arguments passed to the ctor, and in turn passes those
+ as arguments to the wrapped cleanup function, when it is called at
+ scope exit time, from within the forward_scope_exit dtor. The
+ forward_scope_exit class can take any number of arguments, and is
+ cancelable if needed.
+
+ This allows usage like this:
+
+ void
+ delete_longjmp_breakpoint (int arg)
+ {
+ // Blah, blah, blah...
+ }
+
+ using longjmp_breakpoint_cleanup
+ = FORWARD_SCOPE_EXIT (delete_longjmp_breakpoint);
+
+ This above created a new cleanup class `longjmp_breakpoint_cleanup`
+ than can then be used like this:
+
+ longjmp_breakpoint_cleanup obj (thread);
+
+ // Blah, blah, blah...
+
+ obj.release (); // Optional cancel if needed.
+
+ forward_scope_exit is also handy when you would need to wrap a
+ scope_exit in a gdb::optional:
+
+ gdb::optional<longjmp_breakpoint_cleanup> cleanup;
+ if (some condition)
+ cleanup.emplace (thread);
+ ...
+ if (cleanup)
+ cleanup->release ();
+
+ since with scope exit, you would have to know the scope_exit's
+ callable template type when you create the gdb::optional:
+
+ gdb:optional<scope_exit<what goes here?>>
+
+ The "forward" naming fits both purposes shown above -- the class
+ "forwards" ctor arguments to the wrapped cleanup function at scope
+ exit time, and can also be used to "forward declare"
+ scope_exit-like objects. */
+
+namespace detail
+{
+
+/* Function and Signature are passed in the same type, in order to
+ extract Function's arguments' types in the specialization below.
+ Those are used to generate the constructor. */
+
+template<typename Function, Function *function, typename Signature>
+struct forward_scope_exit;
+
+template<typename Function, Function *function,
+ typename Res, typename... Args>
+class forward_scope_exit<Function, function, Res (Args...)>
+ : public scope_exit_base<forward_scope_exit<Function,
+ function,
+ Res (Args...)>>
+{
+ /* For access to on_exit(). */
+ friend scope_exit_base<forward_scope_exit<Function,
+ function,
+ Res (Args...)>>;
+
+public:
+ explicit forward_scope_exit (Args ...args)
+ : m_bind_function (function, args...)
+ {
+ /* Nothing. */
+ }
+
+private:
+ void on_exit ()
+ {
+ m_bind_function ();
+ }
+
+ /* The function and the arguments passed to the ctor, all packed in
+ a std::bind. */
+ decltype (std::bind (function, std::declval<Args> ()...))
+ m_bind_function;
+};
+
+} /* namespace detail */
+
+/* This is the "public" entry point. It's a macro to avoid having to
+ name FUNC more than once. */
+
+#define FORWARD_SCOPE_EXIT(FUNC) \
+ detail::forward_scope_exit<decltype (FUNC), FUNC, decltype (FUNC)>
+
+#endif /* COMMON_FORWARD_SCOPE_EXIT_H */
diff --git a/gdb/gdbsupport/function-view.h b/gdb/gdbsupport/function-view.h
new file mode 100644
index 00000000000..1a577ba0e91
--- /dev/null
+++ b/gdb/gdbsupport/function-view.h
@@ -0,0 +1,323 @@
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_FUNCTION_VIEW_H
+#define COMMON_FUNCTION_VIEW_H
+
+/* function_view is a polymorphic type-erasing wrapper class that
+ encapsulates a non-owning reference to arbitrary callable objects.
+
+ A way to put it is that function_view is to std::function like
+ std::string_view is to std::string. While std::function stores a
+ type-erased callable object internally, function_view holds a
+ type-erased reference to an external callable object.
+
+ This is meant to be used as callback type of a function that:
+
+ #1 - Takes a callback as parameter.
+
+ #2 - Wants to support arbitrary callable objects as callback type
+ (e.g., stateful function objects, lambda closures, free
+ functions).
+
+ #3 - Does not store the callback anywhere; instead the function
+ just calls the callback directly or forwards it to some
+ other function that calls it.
+
+ #4 - Can't be, or we don't want it to be, a template function
+ with the callable type as template parameter. For example,
+ when the callback is a parameter of a virtual member
+ function, or when putting the function template in a header
+ would expose too much implementation detail.
+
+ Note that the C-style "function pointer" + "void *data" callback
+ parameter idiom fails requirement #2 above. Please don't add new
+ uses of that idiom. I.e., something like this wouldn't work;
+
+ typedef bool (iterate_over_foos_cb) (foo *f, void *user_data),
+ void iterate_over_foos (iterate_over_foos_cb *callback, void *user_data);
+
+ foo *find_foo_by_type (int type)
+ {
+ foo *found = nullptr;
+
+ iterate_over_foos ([&] (foo *f, void *data)
+ {
+ if (foo->type == type)
+ {
+ found = foo;
+ return true; // stop iterating
+ }
+ return false; // continue iterating
+ }, NULL);
+
+ return found;
+ }
+
+ The above wouldn't compile, because lambdas with captures can't be
+ implicitly converted to a function pointer (because a capture means
+ some context data must be passed to the lambda somehow).
+
+ C++11 gave us std::function as type-erased wrapper around arbitrary
+ callables, however, std::function is not an ideal fit for transient
+ callbacks such as the use case above. For this use case, which is
+ quite pervasive, a function_view is a better choice, because while
+ function_view is light and does not require any heap allocation,
+ std::function is a heavy-weight object with value semantics that
+ generally requires a heap allocation on construction/assignment of
+ the target callable. In addition, while it is possible to use
+ std::function in such a way that avoids most of the overhead by
+ making sure to only construct it with callables of types that fit
+ std::function's small object optimization, such as function
+ pointers and std::reference_wrapper callables, that is quite
+ inconvenient in practice, because restricting to free-function
+ callables would imply no state/capture/closure, which we need in
+ most cases, and std::reference_wrapper implies remembering to use
+ std::ref/std::cref where the callable is constructed, with the
+ added inconvenience that std::ref/std::cref have deleted rvalue-ref
+ overloads, meaning you can't use unnamed/temporary lambdas with
+ them.
+
+ Note that because function_view is a non-owning view of a callable,
+ care must be taken to ensure that the callable outlives the
+ function_view that calls it. This is not really a problem for the
+ use case function_view is intended for, such as passing a temporary
+ function object / lambda to a function that accepts a callback,
+ because in those cases, the temporary is guaranteed to be live
+ until the called function returns.
+
+ Calling a function_view with no associated target is undefined,
+ unlike with std::function, which throws std::bad_function_call.
+ This is by design, to avoid the otherwise necessary NULL check in
+ function_view::operator().
+
+ Since function_view objects are small (a pair of pointers), they
+ should generally be passed around by value.
+
+ Usage:
+
+ Given this function that accepts a callback:
+
+ void
+ iterate_over_foos (gdb::function_view<void (foo *)> callback)
+ {
+ for (auto &foo : foos)
+ callback (&foo);
+ }
+
+ you can call it like this, passing a lambda as callback:
+
+ iterate_over_foos ([&] (foo *f)
+ {
+ process_one_foo (f);
+ });
+
+ or like this, passing a function object as callback:
+
+ struct function_object
+ {
+ void operator() (foo *f)
+ {
+ if (s->check ())
+ process_one_foo (f);
+ }
+
+ // some state
+ state *s;
+ };
+
+ state mystate;
+ function_object matcher {&mystate};
+ iterate_over_foos (matcher);
+
+ or like this, passing a function pointer as callback:
+
+ iterate_over_foos (process_one_foo);
+
+ You can find unit tests covering the whole API in
+ unittests/function-view-selftests.c. */
+
+namespace gdb {
+
+namespace fv_detail {
+/* Bits shared by all function_view instantiations that do not depend
+ on the template parameters. */
+
+/* Storage for the erased callable. This is a union in order to be
+ able to save both a function object (data) pointer or a function
+ pointer without triggering undefined behavior. */
+union erased_callable
+{
+ /* For function objects. */
+ void *data;
+
+ /* For function pointers. */
+ void (*fn) ();
+};
+
+} /* namespace fv_detail */
+
+/* Use partial specialization to get access to the callable's
+ signature. */
+template<class Signature>
+struct function_view;
+
+template<typename Res, typename... Args>
+class function_view<Res (Args...)>
+{
+ template<typename From, typename To>
+ using CompatibleReturnType
+ = Or<std::is_void<To>,
+ std::is_same<From, To>,
+ std::is_convertible<From, To>>;
+
+ /* True if Func can be called with Args, and either the result is
+ Res, convertible to Res or Res is void. */
+ template<typename Callable,
+ typename Res2 = typename std::result_of<Callable &(Args...)>::type>
+ struct IsCompatibleCallable : CompatibleReturnType<Res2, Res>
+ {};
+
+ /* True if Callable is a function_view. Used to avoid hijacking the
+ copy ctor. */
+ template <typename Callable>
+ struct IsFunctionView
+ : std::is_same<function_view, typename std::decay<Callable>::type>
+ {};
+
+ public:
+
+ /* NULL by default. */
+ constexpr function_view () noexcept
+ : m_erased_callable {},
+ m_invoker {}
+ {}
+
+ /* Default copy/assignment is fine. */
+ function_view (const function_view &) = default;
+ function_view &operator= (const function_view &) = default;
+
+ /* This is the main entry point. Use SFINAE to avoid hijacking the
+ copy constructor and to ensure that the target type is
+ compatible. */
+ template
+ <typename Callable,
+ typename = Requires<Not<IsFunctionView<Callable>>>,
+ typename = Requires<IsCompatibleCallable<Callable>>>
+ function_view (Callable &&callable) noexcept
+ {
+ bind (callable);
+ }
+
+ /* Construct a NULL function_view. */
+ constexpr function_view (std::nullptr_t) noexcept
+ : m_erased_callable {},
+ m_invoker {}
+ {}
+
+ /* Clear a function_view. */
+ function_view &operator= (std::nullptr_t) noexcept
+ {
+ m_invoker = nullptr;
+ return *this;
+ }
+
+ /* Return true if the wrapper has a target, false otherwise. Note
+ we check M_INVOKER instead of M_ERASED_CALLABLE because we don't
+ know which member of the union is active right now. */
+ constexpr explicit operator bool () const noexcept
+ { return m_invoker != nullptr; }
+
+ /* Call the callable. */
+ Res operator () (Args... args) const
+ { return m_invoker (m_erased_callable, std::forward<Args> (args)...); }
+
+ private:
+
+ /* Bind this function_view to a compatible function object
+ reference. */
+ template <typename Callable>
+ void bind (Callable &callable) noexcept
+ {
+ m_erased_callable.data = (void *) std::addressof (callable);
+ m_invoker = [] (fv_detail::erased_callable ecall, Args... args)
+ noexcept (noexcept (callable (std::forward<Args> (args)...))) -> Res
+ {
+ auto &restored_callable = *static_cast<Callable *> (ecall.data);
+ /* The explicit cast to Res avoids a compile error when Res is
+ void and the callable returns non-void. */
+ return (Res) restored_callable (std::forward<Args> (args)...);
+ };
+ }
+
+ /* Bind this function_view to a compatible function pointer.
+
+ Making this a separate function allows avoiding one indirection,
+ by storing the function pointer directly in the storage, instead
+ of a pointer to pointer. erased_callable is then a union in
+ order to avoid storing a function pointer as a data pointer here,
+ which would be undefined. */
+ template<class Res2, typename... Args2>
+ void bind (Res2 (*fn) (Args2...)) noexcept
+ {
+ m_erased_callable.fn = reinterpret_cast<void (*) ()> (fn);
+ m_invoker = [] (fv_detail::erased_callable ecall, Args... args)
+ noexcept (noexcept (fn (std::forward<Args> (args)...))) -> Res
+ {
+ auto restored_fn = reinterpret_cast<Res2 (*) (Args2...)> (ecall.fn);
+ /* The explicit cast to Res avoids a compile error when Res is
+ void and the callable returns non-void. */
+ return (Res) restored_fn (std::forward<Args> (args)...);
+ };
+ }
+
+ /* Storage for the erased callable. */
+ fv_detail::erased_callable m_erased_callable;
+
+ /* The invoker. This is set to a capture-less lambda by one of the
+ 'bind' overloads. The lambda restores the right type of the
+ callable (which is passed as first argument), and forwards the
+ args. */
+ Res (*m_invoker) (fv_detail::erased_callable, Args...);
+};
+
+/* Allow comparison with NULL. Defer the work to the in-class
+ operator bool implementation. */
+
+template<typename Res, typename... Args>
+constexpr inline bool
+operator== (const function_view<Res (Args...)> &f, std::nullptr_t) noexcept
+{ return !static_cast<bool> (f); }
+
+template<typename Res, typename... Args>
+constexpr inline bool
+operator== (std::nullptr_t, const function_view<Res (Args...)> &f) noexcept
+{ return !static_cast<bool> (f); }
+
+template<typename Res, typename... Args>
+constexpr inline bool
+operator!= (const function_view<Res (Args...)> &f, std::nullptr_t) noexcept
+{ return static_cast<bool> (f); }
+
+template<typename Res, typename... Args>
+constexpr inline bool
+operator!= (std::nullptr_t, const function_view<Res (Args...)> &f) noexcept
+{ return static_cast<bool> (f); }
+
+} /* namespace gdb */
+
+#endif
diff --git a/gdb/gdbsupport/gdb_assert.h b/gdb/gdbsupport/gdb_assert.h
new file mode 100644
index 00000000000..a719d878990
--- /dev/null
+++ b/gdb/gdbsupport/gdb_assert.h
@@ -0,0 +1,59 @@
+/* GDB-friendly replacement for <assert.h>.
+ Copyright (C) 2000-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_ASSERT_H
+#define COMMON_GDB_ASSERT_H
+
+/* A static assertion. This will cause a compile-time error if EXPR,
+ which must be a compile-time constant, is false. */
+
+#define gdb_static_assert(expr) static_assert (expr, "")
+
+/* PRAGMATICS: "gdb_assert.h":gdb_assert() is a lower case (rather
+ than upper case) macro since that provides the closest fit to the
+ existing lower case macro <assert.h>:assert() that it is
+ replacing. */
+
+#define gdb_assert(expr) \
+ ((void) ((expr) ? 0 : \
+ (gdb_assert_fail (#expr, __FILE__, __LINE__, FUNCTION_NAME), 0)))
+
+/* This prints an "Assertion failed" message, asking the user if they
+ want to continue, dump core, or just exit. */
+#if defined (FUNCTION_NAME)
+#define gdb_assert_fail(assertion, file, line, function) \
+ internal_error (file, line, _("%s: Assertion `%s' failed."), \
+ function, assertion)
+#else
+#define gdb_assert_fail(assertion, file, line, function) \
+ internal_error (file, line, _("Assertion `%s' failed."), \
+ assertion)
+#endif
+
+/* The canonical form of gdb_assert (0).
+ MESSAGE is a string to include in the error message. */
+
+#if defined (FUNCTION_NAME)
+#define gdb_assert_not_reached(message) \
+ internal_error (__FILE__, __LINE__, "%s: %s", FUNCTION_NAME, _(message))
+#else
+#define gdb_assert_not_reached(message) \
+ internal_error (__FILE__, __LINE__, _(message))
+#endif
+
+#endif /* COMMON_GDB_ASSERT_H */
diff --git a/gdb/gdbsupport/gdb_locale.h b/gdb/gdbsupport/gdb_locale.h
new file mode 100644
index 00000000000..4e59b4f16cb
--- /dev/null
+++ b/gdb/gdbsupport/gdb_locale.h
@@ -0,0 +1,43 @@
+/* GDB-friendly replacement for <locale.h>.
+ Copyright (C) 2002-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_LOCALE_H
+#define COMMON_GDB_LOCALE_H
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(String) gettext (String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+# else
+# define N_(String) (String)
+# endif
+#else
+# define _(String) (String)
+# define N_(String) (String)
+#endif
+
+#ifdef HAVE_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
+
+#endif /* COMMON_GDB_LOCALE_H */
diff --git a/gdb/gdbsupport/gdb_optional.h b/gdb/gdbsupport/gdb_optional.h
new file mode 100644
index 00000000000..94300e48d6a
--- /dev/null
+++ b/gdb/gdbsupport/gdb_optional.h
@@ -0,0 +1,219 @@
+/* An optional object.
+
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_OPTIONAL_H
+#define COMMON_GDB_OPTIONAL_H
+
+#include "gdbsupport/traits.h"
+
+namespace gdb
+{
+
+struct in_place_t
+{
+ explicit in_place_t () = default;
+};
+
+constexpr gdb::in_place_t in_place {};
+
+/* This class attempts to be a compatible subset of std::optional,
+ which is slated to be available in C++17. This class optionally
+ holds an object of some type -- by default it is constructed not
+ holding an object, but later the object can be "emplaced". This is
+ similar to using std::unique_ptr, but in-object allocation is
+ guaranteed.
+
+ Unlike std::optional, we currently only support copy/move
+ construction/assignment of an optional<T> from either exactly
+ optional<T> or T. I.e., we don't support copy/move
+ construction/assignment from optional<U> or U, when U is a type
+ convertible to T. Making that work depending on the definitions of
+ T and U is somewhat complicated, and currently the users of this
+ class don't need it. */
+
+template<typename T>
+class optional
+{
+public:
+
+ constexpr optional ()
+ : m_dummy ()
+ {}
+
+ template<typename... Args>
+ constexpr optional (in_place_t, Args &&... args)
+ : m_item (std::forward<Args> (args)...),
+ m_instantiated (true)
+ {}
+
+ ~optional ()
+ { this->reset (); }
+
+ /* Copy and move constructors. */
+
+ optional (const optional &other)
+ {
+ if (other.m_instantiated)
+ this->emplace (other.get ());
+ }
+
+ optional (optional &&other)
+ noexcept(std::is_nothrow_move_constructible<T> ())
+ {
+ if (other.m_instantiated)
+ this->emplace (std::move (other.get ()));
+ }
+
+ constexpr optional (const T &other)
+ : m_item (other),
+ m_instantiated (true)
+ {}
+
+ constexpr optional (T &&other)
+ noexcept (std::is_nothrow_move_constructible<T> ())
+ : m_item (std::move (other)),
+ m_instantiated (true)
+ {}
+
+ /* Assignment operators. */
+
+ optional &
+ operator= (const optional &other)
+ {
+ if (m_instantiated && other.m_instantiated)
+ this->get () = other.get ();
+ else
+ {
+ if (other.m_instantiated)
+ this->emplace (other.get ());
+ else
+ this->reset ();
+ }
+
+ return *this;
+ }
+
+ optional &
+ operator= (optional &&other)
+ noexcept (And<std::is_nothrow_move_constructible<T>,
+ std::is_nothrow_move_assignable<T>> ())
+ {
+ if (m_instantiated && other.m_instantiated)
+ this->get () = std::move (other.get ());
+ else
+ {
+ if (other.m_instantiated)
+ this->emplace (std::move (other.get ()));
+ else
+ this->reset ();
+ }
+ return *this;
+ }
+
+ optional &
+ operator= (const T &other)
+ {
+ if (m_instantiated)
+ this->get () = other;
+ else
+ this->emplace (other);
+ return *this;
+ }
+
+ optional &
+ operator= (T &&other)
+ noexcept (And<std::is_nothrow_move_constructible<T>,
+ std::is_nothrow_move_assignable<T>> ())
+ {
+ if (m_instantiated)
+ this->get () = std::move (other);
+ else
+ this->emplace (std::move (other));
+ return *this;
+ }
+
+ template<typename... Args>
+ T &emplace (Args &&... args)
+ {
+ this->reset ();
+ new (&m_item) T (std::forward<Args>(args)...);
+ m_instantiated = true;
+ return this->get ();
+ }
+
+ /* Observers. */
+ constexpr const T *operator-> () const
+ { return std::addressof (this->get ()); }
+
+ T *operator-> ()
+ { return std::addressof (this->get ()); }
+
+ constexpr const T &operator* () const &
+ { return this->get (); }
+
+ T &operator* () &
+ { return this->get (); }
+
+ T &&operator* () &&
+ { return std::move (this->get ()); }
+
+ constexpr const T &&operator* () const &&
+ { return std::move (this->get ()); }
+
+ constexpr explicit operator bool () const noexcept
+ { return m_instantiated; }
+
+ constexpr bool has_value () const noexcept
+ { return m_instantiated; }
+
+ /* 'reset' is a 'safe' operation with no precondition. */
+ void reset () noexcept
+ {
+ if (m_instantiated)
+ this->destroy ();
+ }
+
+private:
+
+ /* Destroy the object. */
+ void destroy ()
+ {
+ gdb_assert (m_instantiated);
+ m_instantiated = false;
+ m_item.~T ();
+ }
+
+ /* The get operations have m_instantiated as a precondition. */
+ T &get () noexcept { return m_item; }
+ constexpr const T &get () const noexcept { return m_item; }
+
+ /* The object. */
+ union
+ {
+ struct { } m_dummy;
+ T m_item;
+ };
+
+ /* True if the object was ever emplaced. */
+ bool m_instantiated = false;
+};
+
+}
+
+#endif /* COMMON_GDB_OPTIONAL_H */
diff --git a/gdb/gdbsupport/gdb_proc_service.h b/gdb/gdbsupport/gdb_proc_service.h
new file mode 100644
index 00000000000..8565da3286c
--- /dev/null
+++ b/gdb/gdbsupport/gdb_proc_service.h
@@ -0,0 +1,173 @@
+/* <proc_service.h> replacement for systems that don't have it.
+ Copyright (C) 2000-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_PROC_SERVICE_H
+#define COMMON_GDB_PROC_SERVICE_H
+
+#include <sys/types.h>
+
+#ifdef HAVE_PROC_SERVICE_H
+
+/* glibc's proc_service.h doesn't wrap itself with extern "C". Need
+ to do it ourselves. */
+EXTERN_C_PUSH
+
+#include <proc_service.h>
+
+EXTERN_C_POP
+
+#else /* HAVE_PROC_SERVICE_H */
+
+/* The following fallback definitions have been imported and adjusted
+ from glibc's proc_service.h */
+
+/* Callback interface for libthread_db, functions users must define.
+ Copyright (C) 1999,2002,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* The definitions in this file must correspond to those in the debugger. */
+
+#ifdef HAVE_SYS_PROCFS_H
+#include <sys/procfs.h>
+#endif
+
+/* Not all platforms bring in <linux/elf.h> via <sys/procfs.h>. If
+ <sys/procfs.h> wasn't enough to find elf_fpregset_t, try the kernel
+ headers also (but don't if we don't need to). */
+#ifndef HAVE_ELF_FPREGSET_T
+# ifdef HAVE_LINUX_ELF_H
+# include <linux/elf.h>
+# endif
+#endif
+
+EXTERN_C_PUSH
+
+/* Functions in this interface return one of these status codes. */
+typedef enum
+{
+ PS_OK, /* Generic "call succeeded". */
+ PS_ERR, /* Generic error. */
+ PS_BADPID, /* Bad process handle. */
+ PS_BADLID, /* Bad LWP identifier. */
+ PS_BADADDR, /* Bad address. */
+ PS_NOSYM, /* Could not find given symbol. */
+ PS_NOFREGS /* FPU register set not available for given LWP. */
+} ps_err_e;
+
+#ifndef HAVE_LWPID_T
+typedef unsigned int lwpid_t;
+#endif
+
+#ifndef HAVE_PSADDR_T
+typedef void *psaddr_t;
+#endif
+
+#ifndef HAVE_PRGREGSET_T
+typedef elf_gregset_t prgregset_t;
+#endif
+
+#ifndef HAVE_PRFPREGSET_T
+typedef elf_fpregset_t prfpregset_t;
+#endif
+
+/* This type is opaque in this interface. It's defined by the user of
+ libthread_db. GDB's version is defined below. */
+struct ps_prochandle;
+
+
+/* Read or write process memory at the given address. */
+extern ps_err_e ps_pdread (struct ps_prochandle *,
+ psaddr_t, void *, size_t);
+extern ps_err_e ps_pdwrite (struct ps_prochandle *,
+ psaddr_t, const void *, size_t);
+extern ps_err_e ps_ptread (struct ps_prochandle *,
+ psaddr_t, void *, size_t);
+extern ps_err_e ps_ptwrite (struct ps_prochandle *,
+ psaddr_t, const void *, size_t);
+
+
+/* Get and set the given LWP's general or FPU register set. */
+extern ps_err_e ps_lgetregs (struct ps_prochandle *,
+ lwpid_t, prgregset_t);
+extern ps_err_e ps_lsetregs (struct ps_prochandle *,
+ lwpid_t, const prgregset_t);
+extern ps_err_e ps_lgetfpregs (struct ps_prochandle *,
+ lwpid_t, prfpregset_t *);
+extern ps_err_e ps_lsetfpregs (struct ps_prochandle *,
+ lwpid_t, const prfpregset_t *);
+
+/* Return the PID of the process. */
+extern pid_t ps_getpid (struct ps_prochandle *);
+
+/* Fetch the special per-thread address associated with the given LWP.
+ This call is only used on a few platforms (most use a normal register).
+ The meaning of the `int' parameter is machine-dependent. */
+extern ps_err_e ps_get_thread_area (struct ps_prochandle *,
+ lwpid_t, int, psaddr_t *);
+
+
+/* Look up the named symbol in the named DSO in the symbol tables
+ associated with the process being debugged, filling in *SYM_ADDR
+ with the corresponding run-time address. */
+extern ps_err_e ps_pglobal_lookup (struct ps_prochandle *,
+ const char *object_name,
+ const char *sym_name,
+ psaddr_t *sym_addr);
+
+
+/* Stop or continue the entire process. */
+extern ps_err_e ps_pstop (struct ps_prochandle *);
+extern ps_err_e ps_pcontinue (struct ps_prochandle *);
+
+/* Stop or continue the given LWP alone. */
+extern ps_err_e ps_lstop (struct ps_prochandle *, lwpid_t);
+extern ps_err_e ps_lcontinue (struct ps_prochandle *, lwpid_t);
+
+/* The following are only defined in/called by Solaris. */
+
+/* Get size of extra register set. */
+extern ps_err_e ps_lgetxregsize (struct ps_prochandle *ph,
+ lwpid_t lwpid, int *xregsize);
+/* Get extra register set. */
+extern ps_err_e ps_lgetxregs (struct ps_prochandle *ph, lwpid_t lwpid,
+ caddr_t xregset);
+extern ps_err_e ps_lsetxregs (struct ps_prochandle *ph, lwpid_t lwpid,
+ caddr_t xregset);
+
+/* Log a message (sends to gdb_stderr). */
+extern void ps_plog (const char *fmt, ...);
+
+EXTERN_C_POP
+
+#endif /* HAVE_PROC_SERVICE_H */
+
+#endif /* COMMON_GDB_PROC_SERVICE_H */
diff --git a/gdb/gdbsupport/gdb_ref_ptr.h b/gdb/gdbsupport/gdb_ref_ptr.h
new file mode 100644
index 00000000000..c31c9a2e58b
--- /dev/null
+++ b/gdb/gdbsupport/gdb_ref_ptr.h
@@ -0,0 +1,228 @@
+/* Reference-counted smart pointer class
+
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_REF_PTR_H
+#define COMMON_GDB_REF_PTR_H
+
+#include <cstddef>
+
+namespace gdb
+{
+
+/* An instance of this class either holds a reference to a
+ reference-counted object or is "NULL". Reference counting is
+ handled externally by a policy class. If the object holds a
+ reference, then when the object is destroyed, the reference is
+ decref'd.
+
+ Normally an instance is constructed using a pointer. This sort of
+ initialization lets this class manage the lifetime of that
+ reference.
+
+ Assignment and copy construction will make a new reference as
+ appropriate. Assignment from a plain pointer is disallowed to
+ avoid confusion about whether this acquires a new reference;
+ instead use the "reset" method -- which, like the pointer
+ constructor, transfers ownership.
+
+ The policy class must provide two static methods:
+ void incref (T *);
+ void decref (T *);
+*/
+template<typename T, typename Policy>
+class ref_ptr
+{
+ public:
+
+ /* Create a new NULL instance. */
+ ref_ptr ()
+ : m_obj (NULL)
+ {
+ }
+
+ /* Create a new NULL instance. Note that this is not explicit. */
+ ref_ptr (const std::nullptr_t)
+ : m_obj (NULL)
+ {
+ }
+
+ /* Create a new instance. OBJ is a reference, management of which
+ is now transferred to this class. */
+ explicit ref_ptr (T *obj)
+ : m_obj (obj)
+ {
+ }
+
+ /* Copy another instance. */
+ ref_ptr (const ref_ptr &other)
+ : m_obj (other.m_obj)
+ {
+ if (m_obj != NULL)
+ Policy::incref (m_obj);
+ }
+
+ /* Transfer ownership from OTHER. */
+ ref_ptr (ref_ptr &&other)
+ : m_obj (other.m_obj)
+ {
+ other.m_obj = NULL;
+ }
+
+ /* Destroy this instance. */
+ ~ref_ptr ()
+ {
+ if (m_obj != NULL)
+ Policy::decref (m_obj);
+ }
+
+ /* Copy another instance. */
+ ref_ptr &operator= (const ref_ptr &other)
+ {
+ /* Do nothing on self-assignment. */
+ if (this != &other)
+ {
+ reset (other.m_obj);
+ if (m_obj != NULL)
+ Policy::incref (m_obj);
+ }
+ return *this;
+ }
+
+ /* Transfer ownership from OTHER. */
+ ref_ptr &operator= (ref_ptr &&other)
+ {
+ /* Do nothing on self-assignment. */
+ if (this != &other)
+ {
+ reset (other.m_obj);
+ other.m_obj = NULL;
+ }
+ return *this;
+ }
+
+ /* Change this instance's referent. OBJ is a reference, management
+ of which is now transferred to this class. */
+ void reset (T *obj)
+ {
+ if (m_obj != NULL)
+ Policy::decref (m_obj);
+ m_obj = obj;
+ }
+
+ /* Return this instance's referent without changing the state of
+ this class. */
+ T *get () const
+ {
+ return m_obj;
+ }
+
+ /* Return this instance's referent, and stop managing this
+ reference. The caller is now responsible for the ownership of
+ the reference. */
+ ATTRIBUTE_UNUSED_RESULT T *release ()
+ {
+ T *result = m_obj;
+
+ m_obj = NULL;
+ return result;
+ }
+
+ /* Let users refer to members of the underlying pointer. */
+ T *operator-> () const
+ {
+ return m_obj;
+ }
+
+ /* Acquire a new reference and return a ref_ptr that owns it. */
+ static ref_ptr<T, Policy> new_reference (T *obj)
+ {
+ Policy::incref (obj);
+ return ref_ptr<T, Policy> (obj);
+ }
+
+ private:
+
+ T *m_obj;
+};
+
+template<typename T, typename Policy>
+inline bool operator== (const ref_ptr<T, Policy> &lhs,
+ const ref_ptr<T, Policy> &rhs)
+{
+ return lhs.get () == rhs.get ();
+}
+
+template<typename T, typename Policy>
+inline bool operator== (const ref_ptr<T, Policy> &lhs, const T *rhs)
+{
+ return lhs.get () == rhs;
+}
+
+template<typename T, typename Policy>
+inline bool operator== (const ref_ptr<T, Policy> &lhs, const std::nullptr_t)
+{
+ return lhs.get () == nullptr;
+}
+
+template<typename T, typename Policy>
+inline bool operator== (const T *lhs, const ref_ptr<T, Policy> &rhs)
+{
+ return lhs == rhs.get ();
+}
+
+template<typename T, typename Policy>
+inline bool operator== (const std::nullptr_t, const ref_ptr<T, Policy> &rhs)
+{
+ return nullptr == rhs.get ();
+}
+
+template<typename T, typename Policy>
+inline bool operator!= (const ref_ptr<T, Policy> &lhs,
+ const ref_ptr<T, Policy> &rhs)
+{
+ return lhs.get () != rhs.get ();
+}
+
+template<typename T, typename Policy>
+inline bool operator!= (const ref_ptr<T, Policy> &lhs, const T *rhs)
+{
+ return lhs.get () != rhs;
+}
+
+template<typename T, typename Policy>
+inline bool operator!= (const ref_ptr<T, Policy> &lhs, const std::nullptr_t)
+{
+ return lhs.get () != nullptr;
+}
+
+template<typename T, typename Policy>
+inline bool operator!= (const T *lhs, const ref_ptr<T, Policy> &rhs)
+{
+ return lhs != rhs.get ();
+}
+
+template<typename T, typename Policy>
+inline bool operator!= (const std::nullptr_t, const ref_ptr<T, Policy> &rhs)
+{
+ return nullptr != rhs.get ();
+}
+
+}
+
+#endif /* COMMON_GDB_REF_PTR_H */
diff --git a/gdb/gdbsupport/gdb_setjmp.h b/gdb/gdbsupport/gdb_setjmp.h
new file mode 100644
index 00000000000..d4ebbfa8f2a
--- /dev/null
+++ b/gdb/gdbsupport/gdb_setjmp.h
@@ -0,0 +1,34 @@
+/* Portability wrappers for setjmp and longjmp.
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_SETJMP_H
+#define COMMON_GDB_SETJMP_H
+
+#include <setjmp.h>
+
+#ifdef HAVE_SIGSETJMP
+#define SIGJMP_BUF sigjmp_buf
+#define SIGSETJMP(buf) sigsetjmp((buf), 1)
+#define SIGLONGJMP(buf,val) siglongjmp((buf), (val))
+#else
+#define SIGJMP_BUF jmp_buf
+#define SIGSETJMP(buf) setjmp(buf)
+#define SIGLONGJMP(buf,val) longjmp((buf), (val))
+#endif
+
+#endif /* COMMON_GDB_SETJMP_H */
diff --git a/gdb/gdbsupport/gdb_signals.h b/gdb/gdbsupport/gdb_signals.h
new file mode 100644
index 00000000000..da99f57133c
--- /dev/null
+++ b/gdb/gdbsupport/gdb_signals.h
@@ -0,0 +1,58 @@
+/* Target signal translation functions for GDB.
+ Copyright (C) 1990-2019 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_SIGNALS_H
+#define COMMON_GDB_SIGNALS_H
+
+#include "gdb/signals.h"
+
+/* Predicate to gdb_signal_to_host(). Return non-zero if the enum
+ targ_signal SIGNO has an equivalent ``host'' representation. */
+/* FIXME: cagney/1999-11-22: The name below was chosen in preference
+ to the shorter gdb_signal_p() because it is far less ambigious.
+ In this context ``gdb_signal'' refers to GDB's internal
+ representation of the target's set of signals while ``host signal''
+ refers to the target operating system's signal. Confused? */
+extern int gdb_signal_to_host_p (enum gdb_signal signo);
+
+/* Convert between host signal numbers and enum gdb_signal's.
+ gdb_signal_to_host() returns 0 and prints a warning() on GDB's
+ console if SIGNO has no equivalent host representation. */
+/* FIXME: cagney/1999-11-22: Here ``host'' is used incorrectly, it is
+ refering to the target operating system's signal numbering.
+ Similarly, ``enum gdb_signal'' is named incorrectly, ``enum
+ gdb_signal'' would probably be better as it is refering to GDB's
+ internal representation of a target operating system's signal. */
+extern enum gdb_signal gdb_signal_from_host (int);
+extern int gdb_signal_to_host (enum gdb_signal);
+
+/* Return the enum symbol name of SIG as a string, to use in debug
+ output. */
+extern const char *gdb_signal_to_symbol_string (enum gdb_signal sig);
+
+/* Return the string for a signal. */
+extern const char *gdb_signal_to_string (enum gdb_signal);
+
+/* Return the name (SIGHUP, etc.) for a signal. */
+extern const char *gdb_signal_to_name (enum gdb_signal);
+
+/* Given a name (SIGHUP, etc.), return its signal. */
+enum gdb_signal gdb_signal_from_name (const char *);
+
+#endif /* COMMON_GDB_SIGNALS_H */
diff --git a/gdb/gdbsupport/gdb_splay_tree.h b/gdb/gdbsupport/gdb_splay_tree.h
new file mode 100644
index 00000000000..90b05cdce17
--- /dev/null
+++ b/gdb/gdbsupport/gdb_splay_tree.h
@@ -0,0 +1,42 @@
+/* GDB wrapper for splay trees.
+
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_SPLAY_TREE_H
+#define COMMON_GDB_SPLAY_TREE_H
+
+#include "splay-tree.h"
+
+namespace gdb {
+
+struct splay_tree_deleter
+{
+ void operator() (splay_tree tree) const
+ {
+ splay_tree_delete (tree);
+ }
+};
+
+} /* namespace gdb */
+
+/* A unique pointer to a splay tree. */
+
+typedef std::unique_ptr<splay_tree_s, gdb::splay_tree_deleter>
+ gdb_splay_tree_up;
+
+#endif /* COMMON_GDB_SPLAY_TREE_H */
diff --git a/gdb/gdbsupport/gdb_string_view.h b/gdb/gdbsupport/gdb_string_view.h
new file mode 100644
index 00000000000..68f7f7de36b
--- /dev/null
+++ b/gdb/gdbsupport/gdb_string_view.h
@@ -0,0 +1,562 @@
+// Components for manipulating non-owning sequences of characters -*- C++ -*-
+
+
+#ifndef COMMON_GDB_STRING_VIEW_H
+#define COMMON_GDB_STRING_VIEW_H
+
+// Note: This file has been stolen from the gcc repo
+// (libstdc++-v3/include/experimental/string_view) and has local modifications.
+
+// Copyright (C) 2013-2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+//
+// N3762 basic_string_view library
+//
+
+
+#if __cplusplus >= 201703L
+
+#include <string_view>
+
+namespace gdb {
+ using string_view = std::string_view;
+} /* namespace gdb */
+
+#else /* __cplusplus < 201703L */
+
+#include <string>
+#include <limits>
+
+namespace gdb {
+
+ /**
+ * @class basic_string_view <experimental/string_view>
+ * @brief A non-owning reference to a string.
+ *
+ * @ingroup strings
+ * @ingroup sequences
+ * @ingroup experimental
+ *
+ * @tparam _CharT Type of character
+ * @tparam _Traits Traits for character type, defaults to
+ * char_traits<_CharT>.
+ *
+ * A basic_string_view looks like this:
+ *
+ * @code
+ * _CharT* _M_str
+ * size_t _M_len
+ * @endcode
+ */
+ template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
+ class basic_string_view
+ {
+ public:
+
+ // types
+ using traits_type = _Traits;
+ using value_type = _CharT;
+ using pointer = const _CharT*;
+ using const_pointer = const _CharT*;
+ using reference = const _CharT&;
+ using const_reference = const _CharT&;
+ using const_iterator = const _CharT*;
+ using iterator = const_iterator;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+ using reverse_iterator = const_reverse_iterator;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ static constexpr size_type npos = size_type(-1);
+
+ // [string.view.cons], construct/copy
+
+ constexpr
+ basic_string_view() noexcept
+ : _M_len{0}, _M_str{nullptr}
+ { }
+
+ constexpr basic_string_view(const basic_string_view&) noexcept = default;
+
+ template<typename _Allocator>
+ basic_string_view(const std::basic_string<_CharT, _Traits,
+ _Allocator>& __str) noexcept
+ : _M_len{__str.length()}, _M_str{__str.data()}
+ { }
+
+ /*constexpr*/ basic_string_view(const _CharT* __str)
+ : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
+ _M_str{__str}
+ { }
+
+ constexpr basic_string_view(const _CharT* __str, size_type __len)
+ : _M_len{__len},
+ _M_str{__str}
+ { }
+
+ basic_string_view&
+ operator=(const basic_string_view&) noexcept = default;
+
+ // [string.view.iterators], iterators
+
+ constexpr const_iterator
+ begin() const noexcept
+ { return this->_M_str; }
+
+ constexpr const_iterator
+ end() const noexcept
+ { return this->_M_str + this->_M_len; }
+
+ constexpr const_iterator
+ cbegin() const noexcept
+ { return this->_M_str; }
+
+ constexpr const_iterator
+ cend() const noexcept
+ { return this->_M_str + this->_M_len; }
+
+ const_reverse_iterator
+ rbegin() const noexcept
+ { return const_reverse_iterator(this->end()); }
+
+ const_reverse_iterator
+ rend() const noexcept
+ { return const_reverse_iterator(this->begin()); }
+
+ const_reverse_iterator
+ crbegin() const noexcept
+ { return const_reverse_iterator(this->end()); }
+
+ const_reverse_iterator
+ crend() const noexcept
+ { return const_reverse_iterator(this->begin()); }
+
+ // [string.view.capacity], capacity
+
+ constexpr size_type
+ size() const noexcept
+ { return this->_M_len; }
+
+ constexpr size_type
+ length() const noexcept
+ { return _M_len; }
+
+ constexpr size_type
+ max_size() const noexcept
+ {
+ return (npos - sizeof(size_type) - sizeof(void*))
+ / sizeof(value_type) / 4;
+ }
+
+ constexpr bool
+ empty() const noexcept
+ { return this->_M_len == 0; }
+
+ // [string.view.access], element access
+
+ constexpr const _CharT&
+ operator[](size_type __pos) const
+ {
+ // TODO: Assert to restore in a way compatible with the constexpr.
+ // __glibcxx_assert(__pos < this->_M_len);
+ return *(this->_M_str + __pos);
+ }
+
+ constexpr const _CharT&
+ at(size_type __pos) const
+ {
+ return __pos < this->_M_len
+ ? *(this->_M_str + __pos)
+ : (error (_("basic_string_view::at: __pos "
+ "(which is %zu) >= this->size() "
+ "(which is %zu)"),
+ __pos, this->size()),
+ *this->_M_str);
+ }
+
+ constexpr const _CharT&
+ front() const
+ {
+ // TODO: Assert to restore in a way compatible with the constexpr.
+ // __glibcxx_assert(this->_M_len > 0);
+ return *this->_M_str;
+ }
+
+ constexpr const _CharT&
+ back() const
+ {
+ // TODO: Assert to restore in a way compatible with the constexpr.
+ // __glibcxx_assert(this->_M_len > 0);
+ return *(this->_M_str + this->_M_len - 1);
+ }
+
+ constexpr const _CharT*
+ data() const noexcept
+ { return this->_M_str; }
+
+ // [string.view.modifiers], modifiers:
+
+ /*constexpr*/ void
+ remove_prefix(size_type __n)
+ {
+ gdb_assert (this->_M_len >= __n);
+ this->_M_str += __n;
+ this->_M_len -= __n;
+ }
+
+ /*constexpr*/ void
+ remove_suffix(size_type __n)
+ { this->_M_len -= __n; }
+
+ /*constexpr*/ void
+ swap(basic_string_view& __sv) noexcept
+ {
+ auto __tmp = *this;
+ *this = __sv;
+ __sv = __tmp;
+ }
+
+
+ // [string.view.ops], string operations:
+
+ template<typename _Allocator>
+ explicit operator std::basic_string<_CharT, _Traits, _Allocator>() const
+ {
+ return { this->_M_str, this->_M_len };
+ }
+
+ template<typename _Allocator = std::allocator<_CharT>>
+ std::basic_string<_CharT, _Traits, _Allocator>
+ to_string(const _Allocator& __alloc = _Allocator()) const
+ {
+ return { this->_M_str, this->_M_len, __alloc };
+ }
+
+ size_type
+ copy(_CharT* __str, size_type __n, size_type __pos = 0) const
+ {
+ gdb_assert (__str != nullptr || __n == 0);
+ if (__pos > this->_M_len)
+ error (_("basic_string_view::copy: __pos "
+ "(which is %zu) > this->size() "
+ "(which is %zu)"),
+ __pos, this->size());
+ size_type __rlen{std::min(__n, size_type{this->_M_len - __pos})};
+ for (auto __begin = this->_M_str + __pos,
+ __end = __begin + __rlen; __begin != __end;)
+ *__str++ = *__begin++;
+ return __rlen;
+ }
+
+
+ // [string.view.ops], string operations:
+
+ /*constexpr*/ basic_string_view
+ substr(size_type __pos, size_type __n=npos) const
+ {
+ return __pos <= this->_M_len
+ ? basic_string_view{this->_M_str + __pos,
+ std::min(__n, size_type{this->_M_len - __pos})}
+ : (error (_("basic_string_view::substr: __pos "
+ "(which is %zu) > this->size() "
+ "(which is %zu)"),
+ __pos, this->size()), basic_string_view{});
+ }
+
+ /*constexpr*/ int
+ compare(basic_string_view __str) const noexcept
+ {
+ int __ret = traits_type::compare(this->_M_str, __str._M_str,
+ std::min(this->_M_len, __str._M_len));
+ if (__ret == 0)
+ __ret = _S_compare(this->_M_len, __str._M_len);
+ return __ret;
+ }
+
+ /*constexpr*/ int
+ compare(size_type __pos1, size_type __n1, basic_string_view __str) const
+ { return this->substr(__pos1, __n1).compare(__str); }
+
+ /*constexpr*/ int
+ compare(size_type __pos1, size_type __n1,
+ basic_string_view __str, size_type __pos2, size_type __n2) const
+ { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); }
+
+ /*constexpr*/ int
+ compare(const _CharT* __str) const noexcept
+ { return this->compare(basic_string_view{__str}); }
+
+ /*constexpr*/ int
+ compare(size_type __pos1, size_type __n1, const _CharT* __str) const
+ { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
+
+ /*constexpr*/ int
+ compare(size_type __pos1, size_type __n1,
+ const _CharT* __str, size_type __n2) const
+ {
+ return this->substr(__pos1, __n1)
+ .compare(basic_string_view(__str, __n2));
+ }
+
+ /*constexpr*/ size_type
+ find(basic_string_view __str, size_type __pos = 0) const noexcept
+ { return this->find(__str._M_str, __pos, __str._M_len); }
+
+ /*constexpr*/ size_type
+ find(_CharT __c, size_type __pos=0) const noexcept;
+
+ /*constexpr*/ size_type
+ find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
+
+ /*constexpr*/ size_type
+ find(const _CharT* __str, size_type __pos=0) const noexcept
+ { return this->find(__str, __pos, traits_type::length(__str)); }
+
+ /*constexpr*/ size_type
+ rfind(basic_string_view __str, size_type __pos = npos) const noexcept
+ { return this->rfind(__str._M_str, __pos, __str._M_len); }
+
+ /*constexpr*/ size_type
+ rfind(_CharT __c, size_type __pos = npos) const noexcept;
+
+ /*constexpr*/ size_type
+ rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
+
+ /*constexpr*/ size_type
+ rfind(const _CharT* __str, size_type __pos = npos) const noexcept
+ { return this->rfind(__str, __pos, traits_type::length(__str)); }
+
+ /*constexpr*/ size_type
+ find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
+ { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
+
+ /*constexpr*/ size_type
+ find_first_of(_CharT __c, size_type __pos = 0) const noexcept
+ { return this->find(__c, __pos); }
+
+ /*constexpr*/ size_type
+ find_first_of(const _CharT* __str, size_type __pos, size_type __n) const;
+
+ /*constexpr*/ size_type
+ find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
+ { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
+
+ /*constexpr*/ size_type
+ find_last_of(basic_string_view __str,
+ size_type __pos = npos) const noexcept
+ { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
+
+ size_type
+ find_last_of(_CharT __c, size_type __pos=npos) const noexcept
+ { return this->rfind(__c, __pos); }
+
+ /*constexpr*/ size_type
+ find_last_of(const _CharT* __str, size_type __pos, size_type __n) const;
+
+ /*constexpr*/ size_type
+ find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
+ { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
+
+ /*constexpr*/ size_type
+ find_first_not_of(basic_string_view __str,
+ size_type __pos = 0) const noexcept
+ { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
+
+ /*constexpr*/ size_type
+ find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
+
+ /*constexpr*/ size_type
+ find_first_not_of(const _CharT* __str,
+ size_type __pos, size_type __n) const;
+
+ /*constexpr*/ size_type
+ find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
+ {
+ return this->find_first_not_of(__str, __pos,
+ traits_type::length(__str));
+ }
+
+ /*constexpr*/ size_type
+ find_last_not_of(basic_string_view __str,
+ size_type __pos = npos) const noexcept
+ { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
+
+ /*constexpr*/ size_type
+ find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
+
+ /*constexpr*/ size_type
+ find_last_not_of(const _CharT* __str,
+ size_type __pos, size_type __n) const;
+
+ /*constexpr*/ size_type
+ find_last_not_of(const _CharT* __str,
+ size_type __pos = npos) const noexcept
+ {
+ return this->find_last_not_of(__str, __pos,
+ traits_type::length(__str));
+ }
+
+ private:
+
+ static constexpr int
+ _S_compare(size_type __n1, size_type __n2) noexcept
+ {
+ return difference_type(__n1 - __n2) > std::numeric_limits<int>::max()
+ ? std::numeric_limits<int>::max()
+ : difference_type(__n1 - __n2) < std::numeric_limits<int>::min()
+ ? std::numeric_limits<int>::min()
+ : static_cast<int>(difference_type(__n1 - __n2));
+ }
+
+ size_t _M_len;
+ const _CharT* _M_str;
+ };
+
+ // [string.view.comparison], non-member basic_string_view comparison functions
+
+ namespace __detail
+ {
+ // Identity transform to create a non-deduced context, so that only one
+ // argument participates in template argument deduction and the other
+ // argument gets implicitly converted to the deduced type. See n3766.html.
+ template<typename _Tp>
+ using __idt = typename std::common_type<_Tp>::type;
+ }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator==(basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.size() == __y.size() && __x.compare(__y) == 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator==(basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return __x.size() == __y.size() && __x.compare(__y) == 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.size() == __y.size() && __x.compare(__y) == 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator!=(basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return !(__x == __y); }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator!=(basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return !(__x == __y); }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return !(__x == __y); }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator< (basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) < 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator< (basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return __x.compare(__y) < 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) < 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator> (basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) > 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator> (basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return __x.compare(__y) > 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) > 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator<=(basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) <= 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator<=(basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return __x.compare(__y) <= 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) <= 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator>=(basic_string_view<_CharT, _Traits> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) >= 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator>=(basic_string_view<_CharT, _Traits> __x,
+ __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ { return __x.compare(__y) >= 0; }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ bool
+ operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ basic_string_view<_CharT, _Traits> __y) noexcept
+ { return __x.compare(__y) >= 0; }
+
+ // basic_string_view typedef names
+
+ using string_view = basic_string_view<char>;
+} /* namespace gdb */
+
+#include "gdb_string_view.tcc"
+
+#endif // __cplusplus < 201703L
+
+#endif /* COMMON_GDB_STRING_VIEW_H */
diff --git a/gdb/gdbsupport/gdb_string_view.tcc b/gdb/gdbsupport/gdb_string_view.tcc
new file mode 100644
index 00000000000..c30aafab7d6
--- /dev/null
+++ b/gdb/gdbsupport/gdb_string_view.tcc
@@ -0,0 +1,219 @@
+// Components for manipulating non-owning sequences of characters -*- C++ -*-
+
+// Note: This file has been stolen from the gcc repo
+// (libstdc++-v3/include/experimental/bits/string_view.tcc) and has local
+// modifications.
+
+// Copyright (C) 2013-2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file experimental/bits/string_view.tcc
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{experimental/string_view}
+ */
+
+//
+// N3762 basic_string_view library
+//
+
+#ifndef GDB_STRING_VIEW_TCC
+#define GDB_STRING_VIEW_TCC 1
+
+namespace gdb
+{
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find(const _CharT* __str, size_type __pos, size_type __n) const noexcept
+ {
+ gdb_assert (__str != nullptr || __n == 0);
+
+ if (__n == 0)
+ return __pos <= this->_M_len ? __pos : npos;
+
+ if (__n <= this->_M_len)
+ {
+ for (; __pos <= this->_M_len - __n; ++__pos)
+ if (traits_type::eq(this->_M_str[__pos], __str[0])
+ && traits_type::compare(this->_M_str + __pos + 1,
+ __str + 1, __n - 1) == 0)
+ return __pos;
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find(_CharT __c, size_type __pos) const noexcept
+ {
+ size_type __ret = npos;
+ if (__pos < this->_M_len)
+ {
+ const size_type __n = this->_M_len - __pos;
+ const _CharT* __p = traits_type::find(this->_M_str + __pos, __n, __c);
+ if (__p)
+ __ret = __p - this->_M_str;
+ }
+ return __ret;
+ }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept
+ {
+ gdb_assert (__str != nullptr || __n == 0);
+
+ if (__n <= this->_M_len)
+ {
+ __pos = std::min(size_type(this->_M_len - __n), __pos);
+ do
+ {
+ if (traits_type::compare(this->_M_str + __pos, __str, __n) == 0)
+ return __pos;
+ }
+ while (__pos-- > 0);
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ rfind(_CharT __c, size_type __pos) const noexcept
+ {
+ size_type __size = this->_M_len;
+ if (__size > 0)
+ {
+ if (--__size > __pos)
+ __size = __pos;
+ for (++__size; __size-- > 0; )
+ if (traits_type::eq(this->_M_str[__size], __c))
+ return __size;
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_first_of(const _CharT* __str, size_type __pos, size_type __n) const
+ {
+ gdb_assert (__str != nullptr || __n == 0);
+ for (; __n && __pos < this->_M_len; ++__pos)
+ {
+ const _CharT* __p = traits_type::find(__str, __n,
+ this->_M_str[__pos]);
+ if (__p)
+ return __pos;
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_last_of(const _CharT* __str, size_type __pos, size_type __n) const
+ {
+ gdb_assert (__str != nullptr || __n == 0);
+ size_type __size = this->size();
+ if (__size && __n)
+ {
+ if (--__size > __pos)
+ __size = __pos;
+ do
+ {
+ if (traits_type::find(__str, __n, this->_M_str[__size]))
+ return __size;
+ }
+ while (__size-- != 0);
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_first_not_of(const _CharT* __str, size_type __pos, size_type __n) const
+ {
+ gdb_assert (__str != nullptr || __n == 0);
+ for (; __pos < this->_M_len; ++__pos)
+ if (!traits_type::find(__str, __n, this->_M_str[__pos]))
+ return __pos;
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_first_not_of(_CharT __c, size_type __pos) const noexcept
+ {
+ for (; __pos < this->_M_len; ++__pos)
+ if (!traits_type::eq(this->_M_str[__pos], __c))
+ return __pos;
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_last_not_of(const _CharT* __str, size_type __pos, size_type __n) const
+ {
+ gdb_assert (__str != nullptr || __n == 0);
+ size_type __size = this->_M_len;
+ if (__size)
+ {
+ if (--__size > __pos)
+ __size = __pos;
+ do
+ {
+ if (!traits_type::find(__str, __n, this->_M_str[__size]))
+ return __size;
+ }
+ while (__size--);
+ }
+ return npos;
+ }
+
+ template<typename _CharT, typename _Traits>
+ /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type
+ basic_string_view<_CharT, _Traits>::
+ find_last_not_of(_CharT __c, size_type __pos) const noexcept
+ {
+ size_type __size = this->_M_len;
+ if (__size)
+ {
+ if (--__size > __pos)
+ __size = __pos;
+ do
+ {
+ if (!traits_type::eq(this->_M_str[__size], __c))
+ return __size;
+ }
+ while (__size--);
+ }
+ return npos;
+ }
+} // namespace gdb
+
+#endif // GDB_STRING_VIEW_TCC
diff --git a/gdb/gdbsupport/gdb_sys_time.h b/gdb/gdbsupport/gdb_sys_time.h
new file mode 100644
index 00000000000..66c2bb355ff
--- /dev/null
+++ b/gdb/gdbsupport/gdb_sys_time.h
@@ -0,0 +1,38 @@
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_SYS_TIME_H
+#define COMMON_GDB_SYS_TIME_H
+
+#include <sys/time.h>
+
+/* On MinGW-w64, gnulib's sys/time.h replaces 'struct timeval' and
+ gettimeofday with versions that support 64-bit time_t, for POSIX
+ compliance. However, the gettimeofday replacement does not ever
+ return time_t values larger than 31-bit, as it simply returns the
+ system's gettimeofday's (signed) 32-bit result as (signed) 64-bit.
+ Because we don't really need the POSIX compliance, and it ends up
+ causing conflicts with other libraries we use that don't use gnulib
+ and thus work with the native struct timeval, such as Winsock2's
+ native 'select' and libiberty, simply undefine away gnulib's
+ replacements. */
+#if GNULIB_defined_struct_timeval
+# undef timeval
+# undef gettimeofday
+#endif
+
+#endif /* COMMON_GDB_SYS_TIME_H */
diff --git a/gdb/gdbsupport/gdb_tilde_expand.c b/gdb/gdbsupport/gdb_tilde_expand.c
new file mode 100644
index 00000000000..7e4b06da0e6
--- /dev/null
+++ b/gdb/gdbsupport/gdb_tilde_expand.c
@@ -0,0 +1,95 @@
+/* Perform tilde expansion on paths for GDB and gdbserver.
+
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "gdb_tilde_expand.h"
+#include <glob.h>
+
+/* RAII-style class wrapping "glob". */
+
+class gdb_glob
+{
+public:
+ /* Construct a "gdb_glob" object by calling "glob" with the provided
+ parameters. This function can throw if "glob" fails. */
+ gdb_glob (const char *pattern, int flags,
+ int (*errfunc) (const char *epath, int eerrno))
+ {
+ int ret = glob (pattern, flags, errfunc, &m_glob);
+
+ if (ret != 0)
+ {
+ if (ret == GLOB_NOMATCH)
+ error (_("Could not find a match for '%s'."), pattern);
+ else
+ error (_("glob could not process pattern '%s'."),
+ pattern);
+ }
+ }
+
+ /* Destroy the object and free M_GLOB. */
+ ~gdb_glob ()
+ {
+ globfree (&m_glob);
+ }
+
+ /* Return the GL_PATHC component of M_GLOB. */
+ int pathc () const
+ {
+ return m_glob.gl_pathc;
+ }
+
+ /* Return the GL_PATHV component of M_GLOB. */
+ char **pathv () const
+ {
+ return m_glob.gl_pathv;
+ }
+
+private:
+ /* The actual glob object we're dealing with. */
+ glob_t m_glob;
+};
+
+/* See gdbsupport/gdb_tilde_expand.h. */
+
+std::string
+gdb_tilde_expand (const char *dir)
+{
+ gdb_glob glob (dir, GLOB_TILDE_CHECK, NULL);
+
+ gdb_assert (glob.pathc () > 0);
+ /* "glob" may return more than one match to the path provided by the
+ user, but we are only interested in the first match. */
+ std::string expanded_dir = glob.pathv ()[0];
+
+ return expanded_dir;
+}
+
+/* See gdbsupport/gdb_tilde_expand.h. */
+
+gdb::unique_xmalloc_ptr<char>
+gdb_tilde_expand_up (const char *dir)
+{
+ gdb_glob glob (dir, GLOB_TILDE_CHECK, NULL);
+
+ gdb_assert (glob.pathc () > 0);
+ /* "glob" may return more than one match to the path provided by the
+ user, but we are only interested in the first match. */
+ return make_unique_xstrdup (glob.pathv ()[0]);
+}
diff --git a/gdb/gdbsupport/gdb_tilde_expand.h b/gdb/gdbsupport/gdb_tilde_expand.h
new file mode 100644
index 00000000000..b181b6a3e15
--- /dev/null
+++ b/gdb/gdbsupport/gdb_tilde_expand.h
@@ -0,0 +1,31 @@
+/* Perform tilde expansion on paths for GDB and gdbserver.
+
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_TILDE_EXPAND_H
+#define COMMON_GDB_TILDE_EXPAND_H
+
+/* Perform path expansion (i.e., tilde expansion) on DIR, and return
+ the full path. */
+extern std::string gdb_tilde_expand (const char *dir);
+
+/* Same as GDB_TILDE_EXPAND, but return the full path as a
+ gdb::unique_xmalloc_ptr<char>. */
+extern gdb::unique_xmalloc_ptr<char> gdb_tilde_expand_up (const char *dir);
+
+#endif /* COMMON_GDB_TILDE_EXPAND_H */
diff --git a/gdb/gdbsupport/gdb_unique_ptr.h b/gdb/gdbsupport/gdb_unique_ptr.h
new file mode 100644
index 00000000000..67a5f265353
--- /dev/null
+++ b/gdb/gdbsupport/gdb_unique_ptr.h
@@ -0,0 +1,67 @@
+/* std::unique_ptr specializations for GDB.
+
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_UNIQUE_PTR_H
+#define COMMON_GDB_UNIQUE_PTR_H
+
+#include <memory>
+
+namespace gdb
+{
+/* Define gdb::unique_xmalloc_ptr, a std::unique_ptr that manages
+ xmalloc'ed memory. */
+
+/* The deleter for std::unique_xmalloc_ptr. Uses xfree. */
+template <typename T>
+struct xfree_deleter
+{
+ void operator() (T *ptr) const { xfree (ptr); }
+};
+
+/* Same, for arrays. */
+template <typename T>
+struct xfree_deleter<T[]>
+{
+ void operator() (T *ptr) const { xfree (ptr); }
+};
+
+/* Import the standard unique_ptr to our namespace with a custom
+ deleter. */
+
+template<typename T> using unique_xmalloc_ptr
+ = std::unique_ptr<T, xfree_deleter<T>>;
+
+/* A no-op deleter. */
+template<typename T>
+struct noop_deleter
+{
+ void operator() (T *ptr) const { }
+};
+
+} /* namespace gdb */
+
+/* Dup STR and return a unique_xmalloc_ptr for the result. */
+
+static inline gdb::unique_xmalloc_ptr<char>
+make_unique_xstrdup (const char *str)
+{
+ return gdb::unique_xmalloc_ptr<char> (xstrdup (str));
+}
+
+#endif /* COMMON_GDB_UNIQUE_PTR_H */
diff --git a/gdb/gdbsupport/gdb_unlinker.h b/gdb/gdbsupport/gdb_unlinker.h
new file mode 100644
index 00000000000..193c2f847c9
--- /dev/null
+++ b/gdb/gdbsupport/gdb_unlinker.h
@@ -0,0 +1,60 @@
+/* Unlinking class
+
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_UNLINKER_H
+#define COMMON_GDB_UNLINKER_H
+
+namespace gdb
+{
+
+/* An object of this class holds a filename and, when the object goes
+ of scope, the file is removed using unlink.
+
+ A user of this class can request that the file be preserved using
+ the "keep" method. */
+class unlinker
+{
+ public:
+
+ unlinker (const char *filename) ATTRIBUTE_NONNULL (2)
+ : m_filename (filename)
+ {
+ gdb_assert (filename != NULL);
+ }
+
+ ~unlinker ()
+ {
+ if (m_filename != NULL)
+ unlink (m_filename);
+ }
+
+ /* Keep the file, rather than unlink it. */
+ void keep ()
+ {
+ m_filename = NULL;
+ }
+
+ private:
+
+ const char *m_filename;
+};
+
+}
+
+#endif /* COMMON_GDB_UNLINKER_H */
diff --git a/gdb/gdbsupport/gdb_vecs.c b/gdb/gdbsupport/gdb_vecs.c
new file mode 100644
index 00000000000..38f42f54c9a
--- /dev/null
+++ b/gdb/gdbsupport/gdb_vecs.c
@@ -0,0 +1,88 @@
+/* Some commonly-used VEC types.
+
+ Copyright (C) 2012-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "gdb_vecs.h"
+#include "host-defs.h"
+
+/* Worker function to split character delimiter separated string of fields
+ STR into a char pointer vector. */
+
+static void
+delim_string_to_char_ptr_vec_append
+ (std::vector<gdb::unique_xmalloc_ptr<char>> *vecp, const char *str,
+ char delimiter)
+{
+ do
+ {
+ size_t this_len;
+ const char *next_field;
+ char *this_field;
+
+ next_field = strchr (str, delimiter);
+ if (next_field == NULL)
+ this_len = strlen (str);
+ else
+ {
+ this_len = next_field - str;
+ next_field++;
+ }
+
+ this_field = (char *) xmalloc (this_len + 1);
+ memcpy (this_field, str, this_len);
+ this_field[this_len] = '\0';
+ vecp->emplace_back (this_field);
+
+ str = next_field;
+ }
+ while (str != NULL);
+}
+
+/* See gdb_vecs.h. */
+
+std::vector<gdb::unique_xmalloc_ptr<char>>
+delim_string_to_char_ptr_vec (const char *str, char delimiter)
+{
+ std::vector<gdb::unique_xmalloc_ptr<char>> retval;
+
+ delim_string_to_char_ptr_vec_append (&retval, str, delimiter);
+
+ return retval;
+}
+
+/* See gdb_vecs.h. */
+
+void
+dirnames_to_char_ptr_vec_append
+ (std::vector<gdb::unique_xmalloc_ptr<char>> *vecp, const char *dirnames)
+{
+ delim_string_to_char_ptr_vec_append (vecp, dirnames, DIRNAME_SEPARATOR);
+}
+
+/* See gdb_vecs.h. */
+
+std::vector<gdb::unique_xmalloc_ptr<char>>
+dirnames_to_char_ptr_vec (const char *dirnames)
+{
+ std::vector<gdb::unique_xmalloc_ptr<char>> retval;
+
+ dirnames_to_char_ptr_vec_append (&retval, dirnames);
+
+ return retval;
+}
diff --git a/gdb/gdbsupport/gdb_vecs.h b/gdb/gdbsupport/gdb_vecs.h
new file mode 100644
index 00000000000..017bf9383dc
--- /dev/null
+++ b/gdb/gdbsupport/gdb_vecs.h
@@ -0,0 +1,89 @@
+/* Some commonly-used VEC types.
+
+ Copyright (C) 2012-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_VECS_H
+#define COMMON_GDB_VECS_H
+
+#include "vec.h"
+
+/* Split STR, a list of DELIMITER-separated fields, into a char pointer vector.
+
+ You may modify the returned strings. */
+
+extern std::vector<gdb::unique_xmalloc_ptr<char>>
+ delim_string_to_char_ptr_vec (const char *str, char delimiter);
+
+/* Like dirnames_to_char_ptr_vec, but append the directories to *VECP. */
+
+extern void dirnames_to_char_ptr_vec_append
+ (std::vector<gdb::unique_xmalloc_ptr<char>> *vecp, const char *dirnames);
+
+/* Split DIRNAMES by DIRNAME_SEPARATOR delimiter and return a list of all the
+ elements in their original order. For empty string ("") DIRNAMES return
+ list of one empty string ("") element.
+
+ You may modify the returned strings. */
+
+extern std::vector<gdb::unique_xmalloc_ptr<char>>
+ dirnames_to_char_ptr_vec (const char *dirnames);
+
+/* Remove the element pointed by iterator IT from VEC, not preserving the order
+ of the remaining elements. Return the removed element. */
+
+template <typename T>
+T
+unordered_remove (std::vector<T> &vec, typename std::vector<T>::iterator it)
+{
+ gdb_assert (it >= vec.begin () && it < vec.end ());
+
+ T removed = std::move (*it);
+ *it = std::move (vec.back ());
+ vec.pop_back ();
+
+ return removed;
+}
+
+/* Remove the element at position IX from VEC, not preserving the order of the
+ remaining elements. Return the removed element. */
+
+template <typename T>
+T
+unordered_remove (std::vector<T> &vec, typename std::vector<T>::size_type ix)
+{
+ gdb_assert (ix < vec.size ());
+
+ return unordered_remove (vec, vec.begin () + ix);
+}
+
+/* Remove the element at position IX from VEC, preserving the order the
+ remaining elements. Return the removed element. */
+
+template <typename T>
+T
+ordered_remove (std::vector<T> &vec, typename std::vector<T>::size_type ix)
+{
+ gdb_assert (ix < vec.size ());
+
+ T removed = std::move (vec[ix]);
+ vec.erase (vec.begin () + ix);
+
+ return removed;
+}
+
+#endif /* COMMON_GDB_VECS_H */
diff --git a/gdb/gdbsupport/gdb_wait.h b/gdb/gdbsupport/gdb_wait.h
new file mode 100644
index 00000000000..b3b752cf3a2
--- /dev/null
+++ b/gdb/gdbsupport/gdb_wait.h
@@ -0,0 +1,113 @@
+/* Standard wait macros.
+ Copyright (C) 2000-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_GDB_WAIT_H
+#define COMMON_GDB_WAIT_H
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h> /* POSIX */
+#else
+#ifdef HAVE_WAIT_H
+#include <wait.h> /* legacy */
+#endif
+#endif
+
+/* Define how to access the int that the wait system call stores.
+ This has been compatible in all Unix systems since time immemorial,
+ but various well-meaning people have defined various different
+ words for the same old bits in the same old int (sometimes claimed
+ to be a struct). We just know it's an int and we use these macros
+ to access the bits. */
+
+/* The following macros are defined equivalently to their definitions
+ in POSIX.1. We fail to define WNOHANG and WUNTRACED, which POSIX.1
+ <sys/wait.h> defines, since our code does not use waitpid() (but
+ NOTE exception for GNU/Linux below). We also fail to declare
+ wait() and waitpid(). */
+
+#ifndef WIFEXITED
+#define WIFEXITED(w) (((w)&0377) == 0)
+#endif
+
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
+#endif
+
+#ifndef WIFSTOPPED
+#ifdef IBM6000
+
+/* Unfortunately, the above comment (about being compatible in all Unix
+ systems) is not quite correct for AIX, sigh. And AIX 3.2 can generate
+ status words like 0x57c (sigtrap received after load), and gdb would
+ choke on it. */
+
+#define WIFSTOPPED(w) ((w)&0x40)
+
+#else
+#define WIFSTOPPED(w) (((w)&0377) == 0177)
+#endif
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(w) (((w) >> 8) & 0377) /* same as WRETCODE */
+#endif
+
+#ifndef WTERMSIG
+#define WTERMSIG(w) ((w) & 0177)
+#endif
+
+#ifndef WSTOPSIG
+#define WSTOPSIG WEXITSTATUS
+#endif
+
+/* These are not defined in POSIX, but are used by our programs. */
+
+#ifndef WSETEXIT
+# ifdef W_EXITCODE
+#define WSETEXIT(w,status) ((w) = W_EXITCODE(status,0))
+# else
+#define WSETEXIT(w,status) ((w) = (0 | ((status) << 8)))
+# endif
+#endif
+
+#ifndef W_STOPCODE
+#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
+#endif
+
+#ifndef WSETSTOP
+#define WSETSTOP(w,sig) ((w) = W_STOPCODE(sig))
+#endif
+
+/* For native GNU/Linux we may use waitpid and the __WCLONE option.
+ <GRIPE> It is of course dangerous not to use the REAL header file...
+ </GRIPE>. */
+
+/* Bits in the third argument to `waitpid'. */
+#ifndef WNOHANG
+#define WNOHANG 1 /* Don't block waiting. */
+#endif
+
+#ifndef WUNTRACED
+#define WUNTRACED 2 /* Report status of stopped children. */
+#endif
+
+#ifndef __WCLONE
+#define __WCLONE 0x80000000 /* Wait for cloned process. */
+#endif
+
+#endif /* COMMON_GDB_WAIT_H */
diff --git a/gdb/gdbsupport/hash_enum.h b/gdb/gdbsupport/hash_enum.h
new file mode 100644
index 00000000000..4baf01eb9ca
--- /dev/null
+++ b/gdb/gdbsupport/hash_enum.h
@@ -0,0 +1,45 @@
+/* A hasher for enums.
+
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_HASH_ENUM_H
+#define COMMON_HASH_ENUM_H
+
+/* A hasher for enums, which was missing in C++11:
+ http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2148
+*/
+
+namespace gdb {
+
+/* Helper struct for hashing enum types. */
+template<typename T>
+struct hash_enum
+{
+ typedef size_t result_type;
+ typedef T argument_type;
+
+ size_t operator() (T val) const noexcept
+ {
+ using underlying = typename std::underlying_type<T>::type;
+ return std::hash<underlying> () (static_cast<underlying> (val));
+ }
+};
+
+} /* namespace gdb */
+
+#endif /* COMMON_HASH_ENUM_H */
diff --git a/gdb/gdbsupport/host-defs.h b/gdb/gdbsupport/host-defs.h
new file mode 100644
index 00000000000..dedd9b6fa99
--- /dev/null
+++ b/gdb/gdbsupport/host-defs.h
@@ -0,0 +1,61 @@
+/* Basic host-specific definitions for GDB.
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_HOST_DEFS_H
+#define COMMON_HOST_DEFS_H
+
+#include <limits.h>
+
+/* Static host-system-dependent parameters for GDB. */
+
+/* * Number of bits in a char or unsigned char for the target machine.
+ Just like CHAR_BIT in <limits.h> but describes the target machine. */
+#if !defined (TARGET_CHAR_BIT)
+#define TARGET_CHAR_BIT 8
+#endif
+
+/* * If we picked up a copy of CHAR_BIT from a configuration file
+ (which may get it by including <limits.h>) then use it to set
+ the number of bits in a host char. If not, use the same size
+ as the target. */
+
+#if defined (CHAR_BIT)
+#define HOST_CHAR_BIT CHAR_BIT
+#else
+#define HOST_CHAR_BIT TARGET_CHAR_BIT
+#endif
+
+#ifdef __MSDOS__
+# define CANT_FORK
+# define GLOBAL_CURDIR
+# define DIRNAME_SEPARATOR ';'
+#endif
+
+#if !defined (__CYGWIN__) && defined (_WIN32)
+# define DIRNAME_SEPARATOR ';'
+#endif
+
+#ifndef DIRNAME_SEPARATOR
+#define DIRNAME_SEPARATOR ':'
+#endif
+
+#ifndef SLASH_STRING
+#define SLASH_STRING "/"
+#endif
+
+#endif /* COMMON_HOST_DEFS_H */
diff --git a/gdb/gdbsupport/job-control.c b/gdb/gdbsupport/job-control.c
new file mode 100644
index 00000000000..cd3dde12fbf
--- /dev/null
+++ b/gdb/gdbsupport/job-control.c
@@ -0,0 +1,86 @@
+/* Job control and terminal related functions, for GDB and gdbserver
+ when running under Unix.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "job-control.h"
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+#include <unistd.h>
+
+/* Nonzero if we have job control. */
+int job_control;
+
+/* Set the process group ID of the inferior.
+
+ Just using job_control only does part of it because setpgid or
+ setpgrp might not exist on a system without job control.
+
+ For a more clean implementation, in libiberty, put a setpgid which merely
+ calls setpgrp and a setpgrp which does nothing (any system with job control
+ will have one or the other). */
+
+int
+gdb_setpgid ()
+{
+ int retval = 0;
+
+ if (job_control)
+ {
+#ifdef HAVE_SETPGID
+ /* The call setpgid (0, 0) is supposed to work and mean the same
+ thing as this, but on Ultrix 4.2A it fails with EPERM (and
+ setpgid (getpid (), getpid ()) succeeds). */
+ retval = setpgid (getpid (), getpid ());
+#else
+#ifdef HAVE_SETPGRP
+#ifdef SETPGRP_VOID
+ retval = setpgrp ();
+#else
+ retval = setpgrp (getpid (), getpid ());
+#endif
+#endif /* HAVE_SETPGRP */
+#endif /* HAVE_SETPGID */
+ }
+
+ return retval;
+}
+
+/* See gdbsupport/common-terminal.h. */
+
+void
+have_job_control ()
+{
+ /* OK, figure out whether we have job control. If termios is not
+ available, leave job_control 0. */
+#if defined (HAVE_TERMIOS_H)
+ /* Do all systems with termios have the POSIX way of identifying job
+ control? I hope so. */
+#ifdef _POSIX_JOB_CONTROL
+ job_control = 1;
+#else
+#ifdef _SC_JOB_CONTROL
+ job_control = sysconf (_SC_JOB_CONTROL);
+#else
+ job_control = 0; /* Have to assume the worst. */
+#endif /* _SC_JOB_CONTROL */
+#endif /* _POSIX_JOB_CONTROL */
+#endif /* HAVE_TERMIOS_H */
+}
diff --git a/gdb/gdbsupport/job-control.h b/gdb/gdbsupport/job-control.h
new file mode 100644
index 00000000000..e4660ae50cb
--- /dev/null
+++ b/gdb/gdbsupport/job-control.h
@@ -0,0 +1,38 @@
+/* Job control and terminal related functions, for GDB and gdbserver
+ when running under Unix.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_JOB_CONTROL_H
+#define COMMON_JOB_CONTROL_H
+
+/* Do we have job control? Can be assumed to always be the same
+ within a given run of GDB. Use in gdb/inflow.c and
+ gdbsupport/common-inflow.c. */
+extern int job_control;
+
+/* Set the process group of the caller to its own pid, or do nothing
+ if we lack job control. */
+extern int gdb_setpgid ();
+
+/* Determine whether we have job control, and set variable JOB_CONTROL
+ accordingly. This function must be called before any use of
+ JOB_CONTROL. */
+extern void have_job_control ();
+
+#endif /* COMMON_JOB_CONTROL_H */
diff --git a/gdb/gdbsupport/mingw-strerror.c b/gdb/gdbsupport/mingw-strerror.c
new file mode 100644
index 00000000000..6386330062c
--- /dev/null
+++ b/gdb/gdbsupport/mingw-strerror.c
@@ -0,0 +1,64 @@
+/* Safe version of strerror for MinGW, for GDB, the GNU debugger.
+
+ Copyright (C) 2006-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+
+#include <windows.h>
+
+/* Implementation of safe_strerror as defined in common-utils.h.
+
+ The Windows runtime implementation of strerror never returns NULL,
+ but does return a useless string for anything above sys_nerr;
+ unfortunately this includes all socket-related error codes.
+ This replacement tries to find a system-provided error message. */
+
+char *
+safe_strerror (int errnum)
+{
+ static char *buffer;
+ int len;
+
+ if (errnum >= 0 && errnum < sys_nerr)
+ return strerror (errnum);
+
+ if (buffer)
+ {
+ LocalFree (buffer);
+ buffer = NULL;
+ }
+
+ if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, errnum,
+ MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &buffer, 0, NULL) == 0)
+ {
+ static char buf[32];
+ xsnprintf (buf, sizeof buf, "(undocumented errno %d)", errnum);
+ return buf;
+ }
+
+ /* Windows error messages end with a period and a CR-LF; strip that
+ out. */
+ len = strlen (buffer);
+ if (len > 3 && strcmp (buffer + len - 3, ".\r\n") == 0)
+ buffer[len - 3] = '\0';
+
+ return buffer;
+}
diff --git a/gdb/gdbsupport/netstuff.c b/gdb/gdbsupport/netstuff.c
new file mode 100644
index 00000000000..a7dc3465913
--- /dev/null
+++ b/gdb/gdbsupport/netstuff.c
@@ -0,0 +1,154 @@
+/* Operations on network stuff.
+ Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "netstuff.h"
+#include <algorithm>
+
+#ifdef USE_WIN32API
+#include <ws2tcpip.h>
+#else
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+#endif
+
+/* See gdbsupport/netstuff.h. */
+
+scoped_free_addrinfo::~scoped_free_addrinfo ()
+{
+ freeaddrinfo (m_res);
+}
+
+/* See gdbsupport/netstuff.h. */
+
+parsed_connection_spec
+parse_connection_spec_without_prefix (std::string spec, struct addrinfo *hint)
+{
+ parsed_connection_spec ret;
+ size_t last_colon_pos = 0;
+ /* We're dealing with IPv6 if:
+
+ - ai_family is AF_INET6, or
+ - ai_family is not AF_INET, and
+ - spec[0] is '[', or
+ - the number of ':' on spec is greater than 1. */
+ bool is_ipv6 = (hint->ai_family == AF_INET6
+ || (hint->ai_family != AF_INET
+ && (spec[0] == '['
+ || std::count (spec.begin (),
+ spec.end (), ':') > 1)));
+
+ if (is_ipv6)
+ {
+ if (spec[0] == '[')
+ {
+ /* IPv6 addresses can be written as '[ADDR]:PORT', and we
+ support this notation. */
+ size_t close_bracket_pos = spec.find_first_of (']');
+
+ if (close_bracket_pos == std::string::npos)
+ error (_("Missing close bracket in hostname '%s'"),
+ spec.c_str ());
+
+ hint->ai_family = AF_INET6;
+
+ const char c = spec[close_bracket_pos + 1];
+
+ if (c == '\0')
+ last_colon_pos = std::string::npos;
+ else if (c != ':')
+ error (_("Invalid cruft after close bracket in '%s'"),
+ spec.c_str ());
+
+ /* Erase both '[' and ']'. */
+ spec.erase (0, 1);
+ spec.erase (close_bracket_pos - 1, 1);
+ }
+ else if (spec.find_first_of (']') != std::string::npos)
+ error (_("Missing open bracket in hostname '%s'"),
+ spec.c_str ());
+ }
+
+ if (last_colon_pos == 0)
+ last_colon_pos = spec.find_last_of (':');
+
+ /* The length of the hostname part. */
+ size_t host_len;
+
+ if (last_colon_pos != std::string::npos)
+ {
+ /* The user has provided a port. */
+ host_len = last_colon_pos;
+ ret.port_str = spec.substr (last_colon_pos + 1);
+ }
+ else
+ host_len = spec.size ();
+
+ ret.host_str = spec.substr (0, host_len);
+
+ /* Default hostname is localhost. */
+ if (ret.host_str.empty ())
+ ret.host_str = "localhost";
+
+ return ret;
+}
+
+/* See gdbsupport/netstuff.h. */
+
+parsed_connection_spec
+parse_connection_spec (const char *spec, struct addrinfo *hint)
+{
+ /* Struct to hold the association between valid prefixes, their
+ family and socktype. */
+ struct host_prefix
+ {
+ /* The prefix. */
+ const char *prefix;
+
+ /* The 'ai_family'. */
+ int family;
+
+ /* The 'ai_socktype'. */
+ int socktype;
+ };
+ static const struct host_prefix prefixes[] =
+ {
+ { "udp:", AF_UNSPEC, SOCK_DGRAM },
+ { "tcp:", AF_UNSPEC, SOCK_STREAM },
+ { "udp4:", AF_INET, SOCK_DGRAM },
+ { "tcp4:", AF_INET, SOCK_STREAM },
+ { "udp6:", AF_INET6, SOCK_DGRAM },
+ { "tcp6:", AF_INET6, SOCK_STREAM },
+ };
+
+ for (const host_prefix prefix : prefixes)
+ if (startswith (spec, prefix.prefix))
+ {
+ spec += strlen (prefix.prefix);
+ hint->ai_family = prefix.family;
+ hint->ai_socktype = prefix.socktype;
+ hint->ai_protocol
+ = hint->ai_socktype == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
+ break;
+ }
+
+ return parse_connection_spec_without_prefix (spec, hint);
+}
diff --git a/gdb/gdbsupport/netstuff.h b/gdb/gdbsupport/netstuff.h
new file mode 100644
index 00000000000..0d39fb5eea8
--- /dev/null
+++ b/gdb/gdbsupport/netstuff.h
@@ -0,0 +1,76 @@
+/* Operations on network stuff.
+ Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_NETSTUFF_H
+#define COMMON_NETSTUFF_H
+
+#include <string>
+
+/* Like NI_MAXHOST/NI_MAXSERV, but enough for numeric forms. */
+#define GDB_NI_MAX_ADDR 64
+#define GDB_NI_MAX_PORT 16
+
+/* Helper class to guarantee that we always call 'freeaddrinfo'. */
+
+class scoped_free_addrinfo
+{
+public:
+ /* Default constructor. */
+ explicit scoped_free_addrinfo (struct addrinfo *ainfo)
+ : m_res (ainfo)
+ {
+ }
+
+ /* Destructor responsible for free'ing M_RES by calling
+ 'freeaddrinfo'. */
+ ~scoped_free_addrinfo ();
+
+ DISABLE_COPY_AND_ASSIGN (scoped_free_addrinfo);
+
+private:
+ /* The addrinfo resource. */
+ struct addrinfo *m_res;
+};
+
+/* The struct we return after parsing the connection spec. */
+
+struct parsed_connection_spec
+{
+ /* The hostname. */
+ std::string host_str;
+
+ /* The port, if any. */
+ std::string port_str;
+};
+
+
+/* Parse SPEC (which is a string in the form of "ADDR:PORT") and
+ return a 'parsed_connection_spec' structure with the proper fields
+ filled in. Also adjust HINT accordingly. */
+extern parsed_connection_spec
+ parse_connection_spec_without_prefix (std::string spec,
+ struct addrinfo *hint);
+
+/* Parse SPEC (which is a string in the form of
+ "[tcp[6]:|udp[6]:]ADDR:PORT") and return a 'parsed_connection_spec'
+ structure with the proper fields filled in. Also adjust HINT
+ accordingly. */
+extern parsed_connection_spec parse_connection_spec (const char *spec,
+ struct addrinfo *hint);
+
+#endif /* COMMON_NETSTUFF_H */
diff --git a/gdb/gdbsupport/new-op.c b/gdb/gdbsupport/new-op.c
new file mode 100644
index 00000000000..7c5dba0be6d
--- /dev/null
+++ b/gdb/gdbsupport/new-op.c
@@ -0,0 +1,95 @@
+/* Replace operator new/new[], for GDB, the GNU debugger.
+
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* GCC does not understand __has_feature. */
+#if !defined(__has_feature)
+# define __has_feature(x) 0
+#endif
+
+#if !__has_feature(address_sanitizer) && !defined(__SANITIZE_ADDRESS__)
+#include "common-defs.h"
+#include "host-defs.h"
+#include <new>
+
+/* Override operator new / operator new[], in order to internal_error
+ on allocation failure and thus query the user for abort/core
+ dump/continue, just like xmalloc does. We don't do this from a
+ new-handler function instead (std::set_new_handler) because we want
+ to catch allocation errors from within global constructors too.
+
+ Skip overriding if building with -fsanitize=address though.
+ Address sanitizer wants to override operator new/delete too in
+ order to detect malloc+delete and new+free mismatches. Our
+ versions would mask out ASan's, with the result of losing that
+ useful mismatch detection.
+
+ Note that C++ implementations could either have their throw
+ versions call the nothrow versions (libstdc++), or the other way
+ around (clang/libc++). For that reason, we replace both throw and
+ nothrow variants and call malloc directly. */
+
+void *
+operator new (std::size_t sz)
+{
+ /* malloc (0) is unpredictable; avoid it. */
+ if (sz == 0)
+ sz = 1;
+
+ void *p = malloc (sz); /* ARI: malloc */
+ if (p == NULL)
+ {
+ /* If the user decides to continue debugging, throw a
+ gdb_quit_bad_alloc exception instead of a regular QUIT
+ gdb_exception. The former extends both std::bad_alloc and a
+ QUIT gdb_exception. This is necessary because operator new
+ can only ever throw std::bad_alloc, or something that extends
+ it. */
+ try
+ {
+ malloc_failure (sz);
+ }
+ catch (gdb_exception &ex)
+ {
+ throw gdb_quit_bad_alloc (std::move (ex));
+ }
+ }
+ return p;
+}
+
+void *
+operator new (std::size_t sz, const std::nothrow_t&) noexcept
+{
+ /* malloc (0) is unpredictable; avoid it. */
+ if (sz == 0)
+ sz = 1;
+ return malloc (sz); /* ARI: malloc */
+}
+
+void *
+operator new[] (std::size_t sz)
+{
+ return ::operator new (sz);
+}
+
+void*
+operator new[] (std::size_t sz, const std::nothrow_t&) noexcept
+{
+ return ::operator new (sz, std::nothrow);
+}
+#endif
diff --git a/gdb/gdbsupport/next-iterator.h b/gdb/gdbsupport/next-iterator.h
new file mode 100644
index 00000000000..b61b253bd9d
--- /dev/null
+++ b/gdb/gdbsupport/next-iterator.h
@@ -0,0 +1,102 @@
+/* A "next" iterator for GDB, the GNU debugger.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_NEXT_ITERATOR_H
+#define COMMON_NEXT_ITERATOR_H
+
+/* An iterator that uses the 'next' field of a type to iterate. This
+ can be used with various GDB types that are stored as linked
+ lists. */
+
+template<typename T>
+struct next_iterator
+{
+ typedef next_iterator self_type;
+ typedef T *value_type;
+ typedef T *&reference;
+ typedef T **pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef int difference_type;
+
+ explicit next_iterator (T *item)
+ : m_item (item)
+ {
+ }
+
+ /* Create a one-past-the-end iterator. */
+ next_iterator ()
+ : m_item (nullptr)
+ {
+ }
+
+ value_type operator* () const
+ {
+ return m_item;
+ }
+
+ bool operator== (const self_type &other) const
+ {
+ return m_item == other.m_item;
+ }
+
+ bool operator!= (const self_type &other) const
+ {
+ return m_item != other.m_item;
+ }
+
+ self_type &operator++ ()
+ {
+ m_item = m_item->next;
+ return *this;
+ }
+
+private:
+
+ T *m_item;
+};
+
+/* A range adapter that allows iterating over a linked list. */
+
+template<typename T, typename Iterator = next_iterator<T>>
+class next_adapter
+{
+public:
+
+ explicit next_adapter (T *item)
+ : m_item (item)
+ {
+ }
+
+ using iterator = Iterator;
+
+ iterator begin () const
+ {
+ return iterator (m_item);
+ }
+
+ iterator end () const
+ {
+ return iterator ();
+ }
+
+private:
+
+ T *m_item;
+};
+
+#endif /* COMMON_NEXT_ITERATOR_H */
diff --git a/gdb/gdbsupport/observable.h b/gdb/gdbsupport/observable.h
new file mode 100644
index 00000000000..205c30382c6
--- /dev/null
+++ b/gdb/gdbsupport/observable.h
@@ -0,0 +1,119 @@
+/* Observers
+
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_OBSERVABLE_H
+#define COMMON_OBSERVABLE_H
+
+#include <algorithm>
+#include <functional>
+#include <vector>
+
+namespace gdb
+{
+
+namespace observers
+{
+
+extern unsigned int observer_debug;
+
+/* An observer is an entity which is interested in being notified
+ when GDB reaches certain states, or certain events occur in GDB.
+ The entity being observed is called the observable. To receive
+ notifications, the observer attaches a callback to the observable.
+ One observable can have several observers.
+
+ The observer implementation is also currently not reentrant. In
+ particular, it is therefore not possible to call the attach or
+ detach routines during a notification. */
+
+/* The type of a key that can be passed to attach, which can be passed
+ to detach to remove associated observers. Tokens have address
+ identity, and are thus usually const globals. */
+struct token
+{
+ token () = default;
+
+ DISABLE_COPY_AND_ASSIGN (token);
+};
+
+template<typename... T>
+class observable
+{
+public:
+
+ typedef std::function<void (T...)> func_type;
+
+ explicit observable (const char *name)
+ : m_name (name)
+ {
+ }
+
+ DISABLE_COPY_AND_ASSIGN (observable);
+
+ /* Attach F as an observer to this observable. F cannot be
+ detached. */
+ void attach (const func_type &f)
+ {
+ m_observers.emplace_back (nullptr, f);
+ }
+
+ /* Attach F as an observer to this observable. T is a reference to
+ a token that can be used to later remove F. */
+ void attach (const func_type &f, const token &t)
+ {
+ m_observers.emplace_back (&t, f);
+ }
+
+ /* Remove observers associated with T from this observable. T is
+ the token that was previously passed to any number of "attach"
+ calls. */
+ void detach (const token &t)
+ {
+ auto iter = std::remove_if (m_observers.begin (),
+ m_observers.end (),
+ [&] (const std::pair<const token *,
+ func_type> &e)
+ {
+ return e.first == &t;
+ });
+
+ m_observers.erase (iter, m_observers.end ());
+ }
+
+ /* Notify all observers that are attached to this observable. */
+ void notify (T... args) const
+ {
+ if (observer_debug)
+ fprintf_unfiltered (gdb_stdlog, "observable %s notify() called\n",
+ m_name);
+ for (auto &&e : m_observers)
+ e.second (args...);
+ }
+
+private:
+
+ std::vector<std::pair<const token *, func_type>> m_observers;
+ const char *m_name;
+};
+
+} /* namespace observers */
+
+} /* namespace gdb */
+
+#endif /* COMMON_OBSERVABLE_H */
diff --git a/gdb/gdbsupport/offset-type.h b/gdb/gdbsupport/offset-type.h
new file mode 100644
index 00000000000..e1495b28017
--- /dev/null
+++ b/gdb/gdbsupport/offset-type.h
@@ -0,0 +1,133 @@
+/* Offset types for GDB.
+
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Define an "offset" type. Offset types are distinct integer types
+ that are used to represent an offset into anything that is
+ addressable. For example, an offset into a DWARF debug section.
+ The idea is catch mixing unrelated offset types at compile time, in
+ code that needs to manipulate multiple different kinds of offsets
+ that are easily confused. They're safer to use than native
+ integers, because they have no implicit conversion to anything.
+ And also, since they're implemented as "enum class" strong
+ typedefs, they're still integers ABI-wise, making them a bit more
+ efficient than wrapper structs on some ABIs.
+
+ Some properties of offset types, loosely modeled on pointers:
+
+ - You can compare offsets of the same type for equality and order.
+ You can't compare an offset with an unrelated type.
+
+ - You can add/substract an integer to/from an offset, which gives
+ you back a shifted offset.
+
+ - You can subtract two offsets of the same type, which gives you
+ back the delta as an integer (of the enum class's underlying
+ type), not as an offset type.
+
+ - You can't add two offsets of the same type, as that would not
+ make sense.
+
+ However, unlike pointers, you can't deference offset types. */
+
+#ifndef COMMON_OFFSET_TYPE_H
+#define COMMON_OFFSET_TYPE_H
+
+/* Declare TYPE as being an offset type. This declares the type and
+ enables the operators defined below. */
+#define DEFINE_OFFSET_TYPE(TYPE, UNDERLYING) \
+ enum class TYPE : UNDERLYING {}; \
+ void is_offset_type (TYPE)
+
+/* The macro macro is all you need to know use offset types. The rest
+ below is all implementation detail. */
+
+/* For each enum class type that you want to support arithmetic
+ operators, declare an "is_offset_type" overload that has exactly
+ one parameter, of type that enum class. E.g.,:
+
+ void is_offset_type (sect_offset);
+
+ The function does not need to be defined, only declared.
+ DEFINE_OFFSET_TYPE declares this.
+
+ A function declaration is preferred over a traits type, because the
+ former allows calling the DEFINE_OFFSET_TYPE macro inside a
+ namespace to define the corresponding offset type in that
+ namespace. The compiler finds the corresponding is_offset_type
+ function via ADL.
+*/
+
+/* Adding or subtracting an integer to an offset type shifts the
+ offset. This is like "PTR = PTR + INT" and "PTR += INT". */
+
+#define DEFINE_OFFSET_ARITHM_OP(OP) \
+ template<typename E, \
+ typename = decltype (is_offset_type (std::declval<E> ()))> \
+ constexpr E \
+ operator OP (E lhs, typename std::underlying_type<E>::type rhs) \
+ { \
+ using underlying = typename std::underlying_type<E>::type; \
+ return (E) (static_cast<underlying> (lhs) OP rhs); \
+ } \
+ \
+ template<typename E, \
+ typename = decltype (is_offset_type (std::declval<E> ()))> \
+ constexpr E \
+ operator OP (typename std::underlying_type<E>::type lhs, E rhs) \
+ { \
+ using underlying = typename std::underlying_type<E>::type; \
+ return (E) (lhs OP static_cast<underlying> (rhs)); \
+ } \
+ \
+ template<typename E, \
+ typename = decltype (is_offset_type (std::declval<E> ()))> \
+ E & \
+ operator OP ## = (E &lhs, typename std::underlying_type<E>::type rhs) \
+ { \
+ using underlying = typename std::underlying_type<E>::type; \
+ lhs = (E) (static_cast<underlying> (lhs) OP rhs); \
+ return lhs; \
+ }
+
+DEFINE_OFFSET_ARITHM_OP(+)
+DEFINE_OFFSET_ARITHM_OP(-)
+
+/* Adding two offset types doesn't make sense, just like "PTR + PTR"
+ doesn't make sense. This is defined as a deleted function so that
+ a compile error easily brings you to this comment. */
+
+template<typename E,
+ typename = decltype (is_offset_type (std::declval<E> ()))>
+constexpr typename std::underlying_type<E>::type
+operator+ (E lhs, E rhs) = delete;
+
+/* Subtracting two offset types, however, gives you back the
+ difference between the offsets, as an underlying type. Similar to
+ how "PTR2 - PTR1" returns a ptrdiff_t. */
+
+template<typename E,
+ typename = decltype (is_offset_type (std::declval<E> ()))>
+constexpr typename std::underlying_type<E>::type
+operator- (E lhs, E rhs)
+{
+ using underlying = typename std::underlying_type<E>::type;
+ return static_cast<underlying> (lhs) - static_cast<underlying> (rhs);
+}
+
+#endif /* COMMON_OFFSET_TYPE_H */
diff --git a/gdb/gdbsupport/pathstuff.c b/gdb/gdbsupport/pathstuff.c
new file mode 100644
index 00000000000..fafecd543d3
--- /dev/null
+++ b/gdb/gdbsupport/pathstuff.c
@@ -0,0 +1,290 @@
+/* Path manipulation routines for GDB and gdbserver.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "pathstuff.h"
+#include "host-defs.h"
+#include "filenames.h"
+#include "gdb_tilde_expand.h"
+
+#ifdef USE_WIN32API
+#include <windows.h>
+#endif
+
+/* See gdbsupport/pathstuff.h. */
+
+gdb::unique_xmalloc_ptr<char>
+gdb_realpath (const char *filename)
+{
+/* On most hosts, we rely on canonicalize_file_name to compute
+ the FILENAME's realpath.
+
+ But the situation is slightly more complex on Windows, due to some
+ versions of GCC which were reported to generate paths where
+ backlashes (the directory separator) were doubled. For instance:
+ c:\\some\\double\\slashes\\dir
+ ... instead of ...
+ c:\some\double\slashes\dir
+ Those double-slashes were getting in the way when comparing paths,
+ for instance when trying to insert a breakpoint as follow:
+ (gdb) b c:/some/double/slashes/dir/foo.c:4
+ No source file named c:/some/double/slashes/dir/foo.c:4.
+ (gdb) b c:\some\double\slashes\dir\foo.c:4
+ No source file named c:\some\double\slashes\dir\foo.c:4.
+ To prevent this from happening, we need this function to always
+ strip those extra backslashes. While canonicalize_file_name does
+ perform this simplification, it only works when the path is valid.
+ Since the simplification would be useful even if the path is not
+ valid (one can always set a breakpoint on a file, even if the file
+ does not exist locally), we rely instead on GetFullPathName to
+ perform the canonicalization. */
+
+#if defined (_WIN32)
+ {
+ char buf[MAX_PATH];
+ DWORD len = GetFullPathName (filename, MAX_PATH, buf, NULL);
+
+ /* The file system is case-insensitive but case-preserving.
+ So it is important we do not lowercase the path. Otherwise,
+ we might not be able to display the original casing in a given
+ path. */
+ if (len > 0 && len < MAX_PATH)
+ return make_unique_xstrdup (buf);
+ }
+#else
+ {
+ char *rp = canonicalize_file_name (filename);
+
+ if (rp != NULL)
+ return gdb::unique_xmalloc_ptr<char> (rp);
+ }
+#endif
+
+ /* This system is a lost cause, just dup the buffer. */
+ return make_unique_xstrdup (filename);
+}
+
+/* See gdbsupport/pathstuff.h. */
+
+gdb::unique_xmalloc_ptr<char>
+gdb_realpath_keepfile (const char *filename)
+{
+ const char *base_name = lbasename (filename);
+ char *dir_name;
+ char *result;
+
+ /* Extract the basename of filename, and return immediately
+ a copy of filename if it does not contain any directory prefix. */
+ if (base_name == filename)
+ return make_unique_xstrdup (filename);
+
+ dir_name = (char *) alloca ((size_t) (base_name - filename + 2));
+ /* Allocate enough space to store the dir_name + plus one extra
+ character sometimes needed under Windows (see below), and
+ then the closing \000 character. */
+ strncpy (dir_name, filename, base_name - filename);
+ dir_name[base_name - filename] = '\000';
+
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ /* We need to be careful when filename is of the form 'd:foo', which
+ is equivalent of d:./foo, which is totally different from d:/foo. */
+ if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':')
+ {
+ dir_name[2] = '.';
+ dir_name[3] = '\000';
+ }
+#endif
+
+ /* Canonicalize the directory prefix, and build the resulting
+ filename. If the dirname realpath already contains an ending
+ directory separator, avoid doubling it. */
+ gdb::unique_xmalloc_ptr<char> path_storage = gdb_realpath (dir_name);
+ const char *real_path = path_storage.get ();
+ if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1]))
+ result = concat (real_path, base_name, (char *) NULL);
+ else
+ result = concat (real_path, SLASH_STRING, base_name, (char *) NULL);
+
+ return gdb::unique_xmalloc_ptr<char> (result);
+}
+
+/* See gdbsupport/pathstuff.h. */
+
+gdb::unique_xmalloc_ptr<char>
+gdb_abspath (const char *path)
+{
+ gdb_assert (path != NULL && path[0] != '\0');
+
+ if (path[0] == '~')
+ return gdb_tilde_expand_up (path);
+
+ if (IS_ABSOLUTE_PATH (path))
+ return make_unique_xstrdup (path);
+
+ /* Beware the // my son, the Emacs barfs, the botch that catch... */
+ return gdb::unique_xmalloc_ptr<char>
+ (concat (current_directory,
+ IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
+ ? "" : SLASH_STRING,
+ path, (char *) NULL));
+}
+
+/* See gdbsupport/pathstuff.h. */
+
+const char *
+child_path (const char *parent, const char *child)
+{
+ /* The child path must start with the parent path. */
+ size_t parent_len = strlen (parent);
+ if (filename_ncmp (parent, child, parent_len) != 0)
+ return NULL;
+
+ /* The parent path must be a directory and the child must contain at
+ least one component underneath the parent. */
+ const char *child_component;
+ if (parent_len > 0 && IS_DIR_SEPARATOR (parent[parent_len - 1]))
+ {
+ /* The parent path ends in a directory separator, so it is a
+ directory. The first child component starts after the common
+ prefix. */
+ child_component = child + parent_len;
+ }
+ else
+ {
+ /* The parent path does not end in a directory separator. The
+ first character in the child after the common prefix must be
+ a directory separator.
+
+ Note that CHILD must hold at least parent_len characters for
+ filename_ncmp to return zero. If the character at parent_len
+ is nul due to CHILD containing the same path as PARENT, the
+ IS_DIR_SEPARATOR check will fail here. */
+ if (!IS_DIR_SEPARATOR (child[parent_len]))
+ return NULL;
+
+ /* The first child component starts after the separator after the
+ common prefix. */
+ child_component = child + parent_len + 1;
+ }
+
+ /* The child must contain at least one non-separator character after
+ the parent. */
+ while (*child_component != '\0')
+ {
+ if (!IS_DIR_SEPARATOR (*child_component))
+ return child_component;
+
+ child_component++;
+ }
+ return NULL;
+}
+
+/* See gdbsupport/pathstuff.h. */
+
+bool
+contains_dir_separator (const char *path)
+{
+ for (; *path != '\0'; path++)
+ {
+ if (IS_DIR_SEPARATOR (*path))
+ return true;
+ }
+
+ return false;
+}
+
+/* See gdbsupport/pathstuff.h. */
+
+std::string
+get_standard_cache_dir ()
+{
+#ifdef __APPLE__
+#define HOME_CACHE_DIR "Library/Caches"
+#else
+#define HOME_CACHE_DIR ".cache"
+#endif
+
+#ifndef __APPLE__
+ const char *xdg_cache_home = getenv ("XDG_CACHE_HOME");
+ if (xdg_cache_home != NULL)
+ {
+ /* Make sure the path is absolute and tilde-expanded. */
+ gdb::unique_xmalloc_ptr<char> abs (gdb_abspath (xdg_cache_home));
+ return string_printf ("%s/gdb", abs.get ());
+ }
+#endif
+
+ const char *home = getenv ("HOME");
+ if (home != NULL)
+ {
+ /* Make sure the path is absolute and tilde-expanded. */
+ gdb::unique_xmalloc_ptr<char> abs (gdb_abspath (home));
+ return string_printf ("%s/" HOME_CACHE_DIR "/gdb", abs.get ());
+ }
+
+ return {};
+}
+
+/* See gdbsupport/pathstuff.h. */
+
+std::string
+get_standard_temp_dir ()
+{
+#ifdef WIN32
+ const char *tmp = getenv ("TMP");
+ if (tmp != nullptr)
+ return tmp;
+
+ tmp = getenv ("TEMP");
+ if (tmp != nullptr)
+ return tmp;
+
+ error (_("Couldn't find temp dir path, both TMP and TEMP are unset."));
+
+#else
+ const char *tmp = getenv ("TMPDIR");
+ if (tmp != nullptr)
+ return tmp;
+
+ return "/tmp";
+#endif
+}
+
+/* See gdbsupport/pathstuff.h. */
+
+const char *
+get_shell ()
+{
+ const char *ret = getenv ("SHELL");
+ if (ret == NULL)
+ ret = "/bin/sh";
+
+ return ret;
+}
+
+/* See gdbsupport/pathstuff.h. */
+
+gdb::char_vector
+make_temp_filename (const std::string &f)
+{
+ gdb::char_vector filename_temp (f.length () + 8);
+ strcpy (filename_temp.data (), f.c_str ());
+ strcat (filename_temp.data () + f.size (), "-XXXXXX");
+ return filename_temp;
+}
diff --git a/gdb/gdbsupport/pathstuff.h b/gdb/gdbsupport/pathstuff.h
new file mode 100644
index 00000000000..7d7c8cd0281
--- /dev/null
+++ b/gdb/gdbsupport/pathstuff.h
@@ -0,0 +1,95 @@
+/* Path manipulation routines for GDB and gdbserver.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_PATHSTUFF_H
+#define COMMON_PATHSTUFF_H
+
+#include "gdbsupport/byte-vector.h"
+
+/* Path utilities. */
+
+/* Return the real path of FILENAME, expanding all the symbolic links.
+
+ Contrary to "gdb_abspath", this function does not use
+ CURRENT_DIRECTORY for path expansion. Instead, it relies on the
+ current working directory (CWD) of GDB or gdbserver. */
+
+extern gdb::unique_xmalloc_ptr<char> gdb_realpath (const char *filename);
+
+/* Return a copy of FILENAME, with its directory prefix canonicalized
+ by gdb_realpath. */
+
+extern gdb::unique_xmalloc_ptr<char>
+ gdb_realpath_keepfile (const char *filename);
+
+/* Return PATH in absolute form, performing tilde-expansion if necessary.
+ PATH cannot be NULL or the empty string.
+ This does not resolve symlinks however, use gdb_realpath for that.
+
+ Contrary to "gdb_realpath", this function uses CURRENT_DIRECTORY
+ for the path expansion. This may lead to scenarios the current
+ working directory (CWD) is different than CURRENT_DIRECTORY. */
+
+extern gdb::unique_xmalloc_ptr<char> gdb_abspath (const char *path);
+
+/* If the path in CHILD is a child of the path in PARENT, return a
+ pointer to the first component in the CHILD's pathname below the
+ PARENT. Otherwise, return NULL. */
+
+extern const char *child_path (const char *parent, const char *child);
+
+/* Return whether PATH contains a directory separator character. */
+
+extern bool contains_dir_separator (const char *path);
+
+/* Get the usual user cache directory for the current platform.
+
+ On Linux, it follows the XDG Base Directory specification: use
+ $XDG_CACHE_HOME/gdb if the XDG_CACHE_HOME environment variable is
+ defined, otherwise $HOME/.cache.
+
+ On macOS, it follows the local convention and uses
+ ~/Library/Caches/gdb.
+
+ The return value is absolute and tilde-expanded. Return an empty
+ string if neither XDG_CACHE_HOME (on Linux) or HOME are defined. */
+
+extern std::string get_standard_cache_dir ();
+
+/* Get the usual temporary directory for the current platform.
+
+ On Windows, this is the TMP or TEMP environment variable.
+
+ On the rest, this is the TMPDIR environment variable, if defined, else /tmp.
+
+ Throw an exception on error. */
+
+extern std::string get_standard_temp_dir ();
+
+/* Return the file name of the user's shell. Normally this comes from
+ the SHELL environment variable. */
+
+extern const char *get_shell ();
+
+/* Make a filename suitable to pass to mkstemp based on F (e.g.
+ /tmp/foo -> /tmp/foo-XXXXXX). */
+
+extern gdb::char_vector make_temp_filename (const std::string &f);
+
+#endif /* COMMON_PATHSTUFF_H */
diff --git a/gdb/gdbsupport/poison.h b/gdb/gdbsupport/poison.h
new file mode 100644
index 00000000000..699de513bab
--- /dev/null
+++ b/gdb/gdbsupport/poison.h
@@ -0,0 +1,248 @@
+/* Poison symbols at compile time.
+
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_POISON_H
+#define COMMON_POISON_H
+
+#include "traits.h"
+#include "obstack.h"
+
+/* Poison memset of non-POD types. The idea is catching invalid
+ initialization of non-POD structs that is easy to be introduced as
+ side effect of refactoring. For example, say this:
+
+ struct S { VEC(foo_s) *m_data; };
+
+is converted to this at some point:
+
+ struct S {
+ S() { m_data.reserve (10); }
+ std::vector<foo> m_data;
+ };
+
+and old code was initializing S objects like this:
+
+ struct S s;
+ memset (&s, 0, sizeof (S)); // whoops, now wipes vector.
+
+Declaring memset as deleted for non-POD types makes the memset above
+be a compile-time error. */
+
+/* Helper for SFINAE. True if "T *" is memsettable. I.e., if T is
+ either void, or POD. */
+template<typename T>
+struct IsMemsettable
+ : gdb::Or<std::is_void<T>,
+ std::is_pod<T>>
+{};
+
+template <typename T,
+ typename = gdb::Requires<gdb::Not<IsMemsettable<T>>>>
+void *memset (T *s, int c, size_t n) = delete;
+
+#if HAVE_IS_TRIVIALLY_COPYABLE
+
+/* Similarly, poison memcpy and memmove of non trivially-copyable
+ types, which is undefined. */
+
+/* True if "T *" is relocatable. I.e., copyable with memcpy/memmove.
+ I.e., T is either trivially copyable, or void. */
+template<typename T>
+struct IsRelocatable
+ : gdb::Or<std::is_void<T>,
+ std::is_trivially_copyable<T>>
+{};
+
+/* True if both source and destination are relocatable. */
+
+template <typename D, typename S>
+using BothAreRelocatable
+ = gdb::And<IsRelocatable<D>, IsRelocatable<S>>;
+
+template <typename D, typename S,
+ typename = gdb::Requires<gdb::Not<BothAreRelocatable<D, S>>>>
+void *memcpy (D *dest, const S *src, size_t n) = delete;
+
+template <typename D, typename S,
+ typename = gdb::Requires<gdb::Not<BothAreRelocatable<D, S>>>>
+void *memmove (D *dest, const S *src, size_t n) = delete;
+
+#endif /* HAVE_IS_TRIVIALLY_COPYABLE */
+
+/* Poison XNEW and friends to catch usages of malloc-style allocations on
+ objects that require new/delete. */
+
+template<typename T>
+#if HAVE_IS_TRIVIALLY_CONSTRUCTIBLE
+using IsMallocable = std::is_trivially_constructible<T>;
+#else
+using IsMallocable = std::true_type;
+#endif
+
+template<typename T>
+using IsFreeable = gdb::Or<std::is_trivially_destructible<T>, std::is_void<T>>;
+
+template <typename T, typename = gdb::Requires<gdb::Not<IsFreeable<T>>>>
+void free (T *ptr) = delete;
+
+template<typename T>
+static T *
+xnew ()
+{
+ static_assert (IsMallocable<T>::value, "Trying to use XNEW with a non-POD \
+data type. Use operator new instead.");
+ return XNEW (T);
+}
+
+#undef XNEW
+#define XNEW(T) xnew<T>()
+
+template<typename T>
+static T *
+xcnew ()
+{
+ static_assert (IsMallocable<T>::value, "Trying to use XCNEW with a non-POD \
+data type. Use operator new instead.");
+ return XCNEW (T);
+}
+
+#undef XCNEW
+#define XCNEW(T) xcnew<T>()
+
+template<typename T>
+static void
+xdelete (T *p)
+{
+ static_assert (IsFreeable<T>::value, "Trying to use XDELETE with a non-POD \
+data type. Use operator delete instead.");
+ XDELETE (p);
+}
+
+#undef XDELETE
+#define XDELETE(P) xdelete (P)
+
+template<typename T>
+static T *
+xnewvec (size_t n)
+{
+ static_assert (IsMallocable<T>::value, "Trying to use XNEWVEC with a \
+non-POD data type. Use operator new[] (or std::vector) instead.");
+ return XNEWVEC (T, n);
+}
+
+#undef XNEWVEC
+#define XNEWVEC(T, N) xnewvec<T> (N)
+
+template<typename T>
+static T *
+xcnewvec (size_t n)
+{
+ static_assert (IsMallocable<T>::value, "Trying to use XCNEWVEC with a \
+non-POD data type. Use operator new[] (or std::vector) instead.");
+ return XCNEWVEC (T, n);
+}
+
+#undef XCNEWVEC
+#define XCNEWVEC(T, N) xcnewvec<T> (N)
+
+template<typename T>
+static T *
+xresizevec (T *p, size_t n)
+{
+ static_assert (IsMallocable<T>::value, "Trying to use XRESIZEVEC with a \
+non-POD data type.");
+ return XRESIZEVEC (T, p, n);
+}
+
+#undef XRESIZEVEC
+#define XRESIZEVEC(T, P, N) xresizevec<T> (P, N)
+
+template<typename T>
+static void
+xdeletevec (T *p)
+{
+ static_assert (IsFreeable<T>::value, "Trying to use XDELETEVEC with a \
+non-POD data type. Use operator delete[] (or std::vector) instead.");
+ XDELETEVEC (p);
+}
+
+#undef XDELETEVEC
+#define XDELETEVEC(P) xdeletevec (P)
+
+template<typename T>
+static T *
+xnewvar (size_t s)
+{
+ static_assert (IsMallocable<T>::value, "Trying to use XNEWVAR with a \
+non-POD data type.");
+ return XNEWVAR (T, s);;
+}
+
+#undef XNEWVAR
+#define XNEWVAR(T, S) xnewvar<T> (S)
+
+template<typename T>
+static T *
+xcnewvar (size_t s)
+{
+ static_assert (IsMallocable<T>::value, "Trying to use XCNEWVAR with a \
+non-POD data type.");
+ return XCNEWVAR (T, s);
+}
+
+#undef XCNEWVAR
+#define XCNEWVAR(T, S) xcnewvar<T> (S)
+
+template<typename T>
+static T *
+xresizevar (T *p, size_t s)
+{
+ static_assert (IsMallocable<T>::value, "Trying to use XRESIZEVAR with a \
+non-POD data type.");
+ return XRESIZEVAR (T, p, s);
+}
+
+#undef XRESIZEVAR
+#define XRESIZEVAR(T, P, S) xresizevar<T> (P, S)
+
+template<typename T>
+static T *
+xobnew (obstack *ob)
+{
+ static_assert (IsMallocable<T>::value, "Trying to use XOBNEW with a \
+non-POD data type.");
+ return XOBNEW (ob, T);
+}
+
+#undef XOBNEW
+#define XOBNEW(O, T) xobnew<T> (O)
+
+template<typename T>
+static T *
+xobnewvec (obstack *ob, size_t n)
+{
+ static_assert (IsMallocable<T>::value, "Trying to use XOBNEWVEC with a \
+non-POD data type.");
+ return XOBNEWVEC (ob, T, n);
+}
+
+#undef XOBNEWVEC
+#define XOBNEWVEC(O, T, N) xobnewvec<T> (O, N)
+
+#endif /* COMMON_POISON_H */
diff --git a/gdb/gdbsupport/posix-strerror.c b/gdb/gdbsupport/posix-strerror.c
new file mode 100644
index 00000000000..a8651b706d7
--- /dev/null
+++ b/gdb/gdbsupport/posix-strerror.c
@@ -0,0 +1,38 @@
+/* Safe version of strerror for POSIX systems for GDB, the GNU debugger.
+
+ Copyright (C) 2006-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+
+/* Implementation of safe_strerror as defined in common-utils.h. */
+
+char *
+safe_strerror (int errnum)
+{
+ char *msg;
+
+ msg = strerror (errnum);
+ if (msg == NULL)
+ {
+ static char buf[32];
+
+ xsnprintf (buf, sizeof buf, "(undocumented errno %d)", errnum);
+ msg = buf;
+ }
+ return (msg);
+}
diff --git a/gdb/gdbsupport/preprocessor.h b/gdb/gdbsupport/preprocessor.h
new file mode 100644
index 00000000000..cb735c34bbe
--- /dev/null
+++ b/gdb/gdbsupport/preprocessor.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_PREPROCESSOR_H
+#define COMMON_PREPROCESSOR_H
+
+/* Generally useful preprocessor bits. */
+
+/* Concatenate two tokens. */
+#define CONCAT_1(a, b) a ## b
+#define CONCAT(a, b) CONCAT_1 (a, b)
+
+/* Stringification. */
+#define STRINGIFY_1(x) #x
+#define STRINGIFY(x) STRINGIFY_1 (x)
+
+/* Escape parens out. Useful if you need to pass an argument that
+ includes commas to another macro. */
+#define ESC_PARENS(...) __VA_ARGS__
+
+#endif /* COMMON_PREPROCESSOR_H */
diff --git a/gdb/gdbsupport/print-utils.c b/gdb/gdbsupport/print-utils.c
new file mode 100644
index 00000000000..051c4541b28
--- /dev/null
+++ b/gdb/gdbsupport/print-utils.c
@@ -0,0 +1,326 @@
+/* Cell-based print utility routines for GDB, the GNU debugger.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "print-utils.h"
+/* Temporary storage using circular buffer. */
+
+/* Number of cells in the circular buffer. */
+#define NUMCELLS 16
+
+/* Return the next entry in the circular buffer. */
+
+char *
+get_print_cell (void)
+{
+ static char buf[NUMCELLS][PRINT_CELL_SIZE];
+ static int cell = 0;
+
+ if (++cell >= NUMCELLS)
+ cell = 0;
+ return buf[cell];
+}
+
+static char *
+decimal2str (const char *sign, ULONGEST addr, int width)
+{
+ /* Steal code from valprint.c:print_decimal(). Should this worry
+ about the real size of addr as the above does? */
+ unsigned long temp[3];
+ char *str = get_print_cell ();
+ int i = 0;
+
+ do
+ {
+ temp[i] = addr % (1000 * 1000 * 1000);
+ addr /= (1000 * 1000 * 1000);
+ i++;
+ width -= 9;
+ }
+ while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
+
+ width += 9;
+ if (width < 0)
+ width = 0;
+
+ switch (i)
+ {
+ case 1:
+ xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu", sign, width, temp[0]);
+ break;
+ case 2:
+ xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu", sign, width,
+ temp[1], temp[0]);
+ break;
+ case 3:
+ xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu%09lu", sign, width,
+ temp[2], temp[1], temp[0]);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("failed internal consistency check"));
+ }
+
+ return str;
+}
+
+static char *
+octal2str (ULONGEST addr, int width)
+{
+ unsigned long temp[3];
+ char *str = get_print_cell ();
+ int i = 0;
+
+ do
+ {
+ temp[i] = addr % (0100000 * 0100000);
+ addr /= (0100000 * 0100000);
+ i++;
+ width -= 10;
+ }
+ while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
+
+ width += 10;
+ if (width < 0)
+ width = 0;
+
+ switch (i)
+ {
+ case 1:
+ if (temp[0] == 0)
+ xsnprintf (str, PRINT_CELL_SIZE, "%*o", width, 0);
+ else
+ xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo", width, temp[0]);
+ break;
+ case 2:
+ xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo", width, temp[1], temp[0]);
+ break;
+ case 3:
+ xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo%010lo", width,
+ temp[2], temp[1], temp[0]);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("failed internal consistency check"));
+ }
+
+ return str;
+}
+
+/* See print-utils.h. */
+
+char *
+pulongest (ULONGEST u)
+{
+ return decimal2str ("", u, 0);
+}
+
+/* See print-utils.h. */
+
+char *
+plongest (LONGEST l)
+{
+ if (l < 0)
+ return decimal2str ("-", -l, 0);
+ else
+ return decimal2str ("", l, 0);
+}
+
+/* Eliminate warning from compiler on 32-bit systems. */
+static int thirty_two = 32;
+
+/* See print-utils.h. */
+
+char *
+phex (ULONGEST l, int sizeof_l)
+{
+ char *str;
+
+ switch (sizeof_l)
+ {
+ case 8:
+ str = get_print_cell ();
+ xsnprintf (str, PRINT_CELL_SIZE, "%08lx%08lx",
+ (unsigned long) (l >> thirty_two),
+ (unsigned long) (l & 0xffffffff));
+ break;
+ case 4:
+ str = get_print_cell ();
+ xsnprintf (str, PRINT_CELL_SIZE, "%08lx", (unsigned long) l);
+ break;
+ case 2:
+ str = get_print_cell ();
+ xsnprintf (str, PRINT_CELL_SIZE, "%04x", (unsigned short) (l & 0xffff));
+ break;
+ default:
+ str = phex (l, sizeof (l));
+ break;
+ }
+
+ return str;
+}
+
+/* See print-utils.h. */
+
+char *
+phex_nz (ULONGEST l, int sizeof_l)
+{
+ char *str;
+
+ switch (sizeof_l)
+ {
+ case 8:
+ {
+ unsigned long high = (unsigned long) (l >> thirty_two);
+
+ str = get_print_cell ();
+ if (high == 0)
+ xsnprintf (str, PRINT_CELL_SIZE, "%lx",
+ (unsigned long) (l & 0xffffffff));
+ else
+ xsnprintf (str, PRINT_CELL_SIZE, "%lx%08lx", high,
+ (unsigned long) (l & 0xffffffff));
+ break;
+ }
+ case 4:
+ str = get_print_cell ();
+ xsnprintf (str, PRINT_CELL_SIZE, "%lx", (unsigned long) l);
+ break;
+ case 2:
+ str = get_print_cell ();
+ xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xffff));
+ break;
+ default:
+ str = phex_nz (l, sizeof (l));
+ break;
+ }
+
+ return str;
+}
+
+/* See print-utils.h. */
+
+char *
+hex_string (LONGEST num)
+{
+ char *result = get_print_cell ();
+
+ xsnprintf (result, PRINT_CELL_SIZE, "0x%s", phex_nz (num, sizeof (num)));
+ return result;
+}
+
+/* See print-utils.h. */
+
+char *
+hex_string_custom (LONGEST num, int width)
+{
+ char *result = get_print_cell ();
+ char *result_end = result + PRINT_CELL_SIZE - 1;
+ const char *hex = phex_nz (num, sizeof (num));
+ int hex_len = strlen (hex);
+
+ if (hex_len > width)
+ width = hex_len;
+ if (width + 2 >= PRINT_CELL_SIZE)
+ internal_error (__FILE__, __LINE__, _("\
+hex_string_custom: insufficient space to store result"));
+
+ strcpy (result_end - width - 2, "0x");
+ memset (result_end - width, '0', width);
+ strcpy (result_end - hex_len, hex);
+ return result_end - width - 2;
+}
+
+/* See print-utils.h. */
+
+char *
+int_string (LONGEST val, int radix, int is_signed, int width,
+ int use_c_format)
+{
+ switch (radix)
+ {
+ case 16:
+ {
+ char *result;
+
+ if (width == 0)
+ result = hex_string (val);
+ else
+ result = hex_string_custom (val, width);
+ if (! use_c_format)
+ result += 2;
+ return result;
+ }
+ case 10:
+ {
+ if (is_signed && val < 0)
+ return decimal2str ("-", -val, width);
+ else
+ return decimal2str ("", val, width);
+ }
+ case 8:
+ {
+ char *result = octal2str (val, width);
+
+ if (use_c_format || val == 0)
+ return result;
+ else
+ return result + 1;
+ }
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("failed internal consistency check"));
+ }
+}
+
+/* See print-utils.h. */
+
+const char *
+core_addr_to_string (const CORE_ADDR addr)
+{
+ char *str = get_print_cell ();
+
+ strcpy (str, "0x");
+ strcat (str, phex (addr, sizeof (addr)));
+ return str;
+}
+
+/* See print-utils.h. */
+
+const char *
+core_addr_to_string_nz (const CORE_ADDR addr)
+{
+ char *str = get_print_cell ();
+
+ strcpy (str, "0x");
+ strcat (str, phex_nz (addr, sizeof (addr)));
+ return str;
+}
+
+/* See print-utils.h. */
+
+const char *
+host_address_to_string_1 (const void *addr)
+{
+ char *str = get_print_cell ();
+
+ xsnprintf (str, PRINT_CELL_SIZE, "0x%s",
+ phex_nz ((uintptr_t) addr, sizeof (addr)));
+ return str;
+}
diff --git a/gdb/gdbsupport/print-utils.h b/gdb/gdbsupport/print-utils.h
new file mode 100644
index 00000000000..815b14cbed3
--- /dev/null
+++ b/gdb/gdbsupport/print-utils.h
@@ -0,0 +1,82 @@
+/* Cell-based print utility routines for GDB, the GNU debugger.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_PRINT_UTILS_H
+#define COMMON_PRINT_UTILS_H
+
+/* How many characters (including the terminating null byte) fit in a
+ cell. */
+#define PRINT_CELL_SIZE 50
+
+/* %d for LONGEST. The result is stored in a circular static buffer,
+ NUMCELLS deep. */
+
+extern char *pulongest (ULONGEST u);
+
+/* %u for ULONGEST. The result is stored in a circular static buffer,
+ NUMCELLS deep. */
+
+extern char *plongest (LONGEST l);
+
+extern char *phex (ULONGEST l, int sizeof_l);
+
+/* Convert a ULONGEST into a HEX string, like %lx. The result is
+ stored in a circular static buffer, NUMCELLS deep. */
+
+extern char *phex_nz (ULONGEST l, int sizeof_l);
+
+/* Converts a LONGEST to a C-format hexadecimal literal and stores it
+ in a static string. Returns a pointer to this string. */
+
+extern char *hex_string (LONGEST num);
+
+/* Converts a LONGEST number to a C-format hexadecimal literal and
+ stores it in a static string. Returns a pointer to this string
+ that is valid until the next call. The number is padded on the
+ left with 0s to at least WIDTH characters. */
+
+extern char *hex_string_custom (LONGEST num, int width);
+
+/* Convert VAL to a numeral in the given radix. For
+ * radix 10, IS_SIGNED may be true, indicating a signed quantity;
+ * otherwise VAL is interpreted as unsigned. If WIDTH is supplied,
+ * it is the minimum width (0-padded if needed). USE_C_FORMAT means
+ * to use C format in all cases. If it is false, then 'x'
+ * and 'o' formats do not include a prefix (0x or leading 0). */
+
+extern char *int_string (LONGEST val, int radix, int is_signed, int width,
+ int use_c_format);
+
+/* Convert a CORE_ADDR into a string. */
+
+extern const char *core_addr_to_string (const CORE_ADDR addr);
+
+extern const char *core_addr_to_string_nz (const CORE_ADDR addr);
+
+extern const char *host_address_to_string_1 (const void *addr);
+
+/* Wrapper that avoids adding a pointless cast to all callers. */
+#define host_address_to_string(ADDR) \
+ host_address_to_string_1 ((const void *) (ADDR))
+
+/* Return the next entry in the circular print buffer. */
+
+extern char *get_print_cell (void);
+
+#endif /* COMMON_PRINT_UTILS_H */
diff --git a/gdb/gdbsupport/ptid.c b/gdb/gdbsupport/ptid.c
new file mode 100644
index 00000000000..c025511a37b
--- /dev/null
+++ b/gdb/gdbsupport/ptid.c
@@ -0,0 +1,26 @@
+/* The ptid_t type and common functions operating on it.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "ptid.h"
+
+/* See ptid.h for these. */
+
+ptid_t const null_ptid = ptid_t::make_null ();
+ptid_t const minus_one_ptid = ptid_t::make_minus_one ();
diff --git a/gdb/gdbsupport/ptid.h b/gdb/gdbsupport/ptid.h
new file mode 100644
index 00000000000..f5625a61387
--- /dev/null
+++ b/gdb/gdbsupport/ptid.h
@@ -0,0 +1,155 @@
+/* The ptid_t type and common functions operating on it.
+
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_PTID_H
+#define COMMON_PTID_H
+
+/* The ptid struct is a collection of the various "ids" necessary for
+ identifying the inferior process/thread being debugged. This
+ consists of the process id (pid), lightweight process id (lwp) and
+ thread id (tid). When manipulating ptids, the constructors,
+ accessors, and predicates declared in this file should be used. Do
+ NOT access the struct ptid members directly.
+
+ process_stratum targets that handle threading themselves should
+ prefer using the ptid.lwp field, leaving the ptid.tid field for any
+ thread_stratum target that might want to sit on top.
+*/
+
+class ptid_t
+{
+public:
+ /* Must have a trivial defaulted default constructor so that the
+ type remains POD. */
+ ptid_t () noexcept = default;
+
+ /* Make a ptid given the necessary PID, LWP, and TID components.
+
+ A ptid with only a PID (LWP and TID equal to zero) is usually used to
+ represent a whole process, including all its lwps/threads. */
+
+ explicit constexpr ptid_t (int pid, long lwp = 0, long tid = 0)
+ : m_pid (pid), m_lwp (lwp), m_tid (tid)
+ {}
+
+ /* Fetch the pid (process id) component from the ptid. */
+
+ constexpr int pid () const
+ { return m_pid; }
+
+ /* Return true if the ptid's lwp member is non-zero. */
+
+ constexpr bool lwp_p () const
+ { return m_lwp != 0; }
+
+ /* Fetch the lwp (lightweight process) component from the ptid. */
+
+ constexpr long lwp () const
+ { return m_lwp; }
+
+ /* Return true if the ptid's tid member is non-zero. */
+
+ constexpr bool tid_p () const
+ { return m_tid != 0; }
+
+ /* Fetch the tid (thread id) component from a ptid. */
+
+ constexpr long tid () const
+ { return m_tid; }
+
+ /* Return true if the ptid represents a whole process, including all its
+ lwps/threads. Such ptids have the form of (pid, 0, 0), with
+ pid != -1. */
+
+ constexpr bool is_pid () const
+ {
+ return (*this != make_null ()
+ && *this != make_minus_one ()
+ && m_lwp == 0
+ && m_tid == 0);
+ }
+
+ /* Compare two ptids to see if they are equal. */
+
+ constexpr bool operator== (const ptid_t &other) const
+ {
+ return (m_pid == other.m_pid
+ && m_lwp == other.m_lwp
+ && m_tid == other.m_tid);
+ }
+
+ /* Compare two ptids to see if they are different. */
+
+ constexpr bool operator!= (const ptid_t &other) const
+ {
+ return !(*this == other);
+ }
+
+ /* Return true if the ptid matches FILTER. FILTER can be the wild
+ card MINUS_ONE_PTID (all ptids match it); can be a ptid representing
+ a process (ptid.is_pid () returns true), in which case, all lwps and
+ threads of that given process match, lwps and threads of other
+ processes do not; or, it can represent a specific thread, in which
+ case, only that thread will match true. The ptid must represent a
+ specific LWP or THREAD, it can never be a wild card. */
+
+ constexpr bool matches (const ptid_t &filter) const
+ {
+ return (/* If filter represents any ptid, it's always a match. */
+ filter == make_minus_one ()
+ /* If filter is only a pid, any ptid with that pid
+ matches. */
+ || (filter.is_pid () && m_pid == filter.pid ())
+
+ /* Otherwise, this ptid only matches if it's exactly equal
+ to filter. */
+ || *this == filter);
+ }
+
+ /* Make a null ptid. */
+
+ static constexpr ptid_t make_null ()
+ { return ptid_t (0, 0, 0); }
+
+ /* Make a minus one ptid. */
+
+ static constexpr ptid_t make_minus_one ()
+ { return ptid_t (-1, 0, 0); }
+
+private:
+ /* Process id. */
+ int m_pid;
+
+ /* Lightweight process id. */
+ long m_lwp;
+
+ /* Thread id. */
+ long m_tid;
+};
+
+/* The null or zero ptid, often used to indicate no process. */
+
+extern const ptid_t null_ptid;
+
+/* The (-1,0,0) ptid, often used to indicate either an error condition
+ or a "don't care" condition, i.e, "run all threads." */
+
+extern const ptid_t minus_one_ptid;
+
+#endif /* COMMON_PTID_H */
diff --git a/gdb/gdbsupport/refcounted-object.h b/gdb/gdbsupport/refcounted-object.h
new file mode 100644
index 00000000000..4bf7fcf1c94
--- /dev/null
+++ b/gdb/gdbsupport/refcounted-object.h
@@ -0,0 +1,70 @@
+/* Base class of intrusively reference-counted objects.
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_REFCOUNTED_OBJECT_H
+#define COMMON_REFCOUNTED_OBJECT_H
+
+/* Base class of intrusively reference-countable objects.
+ Incrementing and decrementing the reference count is an external
+ responsibility. */
+
+class refcounted_object
+{
+public:
+ refcounted_object () = default;
+
+ /* Increase the refcount. */
+ void incref ()
+ {
+ gdb_assert (m_refcount >= 0);
+ m_refcount++;
+ }
+
+ /* Decrease the refcount. */
+ void decref ()
+ {
+ m_refcount--;
+ gdb_assert (m_refcount >= 0);
+ }
+
+ int refcount () const { return m_refcount; }
+
+private:
+ DISABLE_COPY_AND_ASSIGN (refcounted_object);
+
+ /* The reference count. */
+ int m_refcount = 0;
+};
+
+/* A policy class to interface gdb::ref_ptr with a
+ refcounted_object. */
+
+struct refcounted_object_ref_policy
+{
+ static void incref (refcounted_object *ptr)
+ {
+ ptr->incref ();
+ }
+
+ static void decref (refcounted_object *ptr)
+ {
+ ptr->decref ();
+ }
+};
+
+#endif /* COMMON_REFCOUNTED_OBJECT_H */
diff --git a/gdb/gdbsupport/rsp-low.c b/gdb/gdbsupport/rsp-low.c
new file mode 100644
index 00000000000..4bb49418499
--- /dev/null
+++ b/gdb/gdbsupport/rsp-low.c
@@ -0,0 +1,307 @@
+/* Low-level RSP routines for GDB, the GNU debugger.
+
+ Copyright (C) 1988-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "rsp-low.h"
+
+/* See rsp-low.h. */
+
+int
+fromhex (int a)
+{
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ else if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ else if (a >= 'A' && a <= 'F')
+ return a - 'A' + 10;
+ else
+ error (_("Reply contains invalid hex digit %d"), a);
+}
+
+/* See rsp-low.h. */
+
+int
+tohex (int nib)
+{
+ if (nib < 10)
+ return '0' + nib;
+ else
+ return 'a' + nib - 10;
+}
+
+/* Encode 64 bits in 16 chars of hex. */
+
+static const char hexchars[] = "0123456789abcdef";
+
+static int
+ishex (int ch, int *val)
+{
+ if ((ch >= 'a') && (ch <= 'f'))
+ {
+ *val = ch - 'a' + 10;
+ return 1;
+ }
+ if ((ch >= 'A') && (ch <= 'F'))
+ {
+ *val = ch - 'A' + 10;
+ return 1;
+ }
+ if ((ch >= '0') && (ch <= '9'))
+ {
+ *val = ch - '0';
+ return 1;
+ }
+ return 0;
+}
+
+/* See rsp-low.h. */
+
+char *
+pack_nibble (char *buf, int nibble)
+{
+ *buf++ = hexchars[(nibble & 0x0f)];
+ return buf;
+}
+
+/* See rsp-low.h. */
+
+char *
+pack_hex_byte (char *pkt, int byte)
+{
+ *pkt++ = hexchars[(byte >> 4) & 0xf];
+ *pkt++ = hexchars[(byte & 0xf)];
+ return pkt;
+}
+
+/* See rsp-low.h. */
+
+const char *
+unpack_varlen_hex (const char *buff, /* packet to parse */
+ ULONGEST *result)
+{
+ int nibble;
+ ULONGEST retval = 0;
+
+ while (ishex (*buff, &nibble))
+ {
+ buff++;
+ retval = retval << 4;
+ retval |= nibble & 0x0f;
+ }
+ *result = retval;
+ return buff;
+}
+
+/* See rsp-low.h. */
+
+int
+hex2bin (const char *hex, gdb_byte *bin, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (hex[0] == 0 || hex[1] == 0)
+ {
+ /* Hex string is short, or of uneven length.
+ Return the count that has been converted so far. */
+ return i;
+ }
+ *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
+ hex += 2;
+ }
+ return i;
+}
+
+/* See rsp-low.h. */
+
+gdb::byte_vector
+hex2bin (const char *hex)
+{
+ size_t bin_len = strlen (hex) / 2;
+ gdb::byte_vector bin (bin_len);
+
+ hex2bin (hex, bin.data (), bin_len);
+
+ return bin;
+}
+
+/* See rsp-low.h. */
+
+std::string
+hex2str (const char *hex)
+{
+ return hex2str (hex, strlen (hex));
+}
+
+/* See rsp-low.h. */
+
+std::string
+hex2str (const char *hex, int count)
+{
+ std::string ret;
+
+ ret.reserve (count);
+ for (size_t i = 0; i < count; ++i)
+ {
+ if (hex[0] == '\0' || hex[1] == '\0')
+ {
+ /* Hex string is short, or of uneven length. Return what we
+ have so far. */
+ return ret;
+ }
+ ret += fromhex (hex[0]) * 16 + fromhex (hex[1]);
+ hex += 2;
+ }
+
+ return ret;
+}
+
+/* See rsp-low.h. */
+
+int
+bin2hex (const gdb_byte *bin, char *hex, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ *hex++ = tohex ((*bin >> 4) & 0xf);
+ *hex++ = tohex (*bin++ & 0xf);
+ }
+ *hex = 0;
+ return i;
+}
+
+/* See rsp-low.h. */
+
+std::string
+bin2hex (const gdb_byte *bin, int count)
+{
+ std::string ret;
+
+ ret.reserve (count * 2);
+ for (int i = 0; i < count; ++i)
+ {
+ ret += tohex ((*bin >> 4) & 0xf);
+ ret += tohex (*bin++ & 0xf);
+ }
+
+ return ret;
+}
+
+/* Return whether byte B needs escaping when sent as part of binary data. */
+
+static int
+needs_escaping (gdb_byte b)
+{
+ return b == '$' || b == '#' || b == '}' || b == '*';
+}
+
+/* See rsp-low.h. */
+
+int
+remote_escape_output (const gdb_byte *buffer, int len_units, int unit_size,
+ gdb_byte *out_buf, int *out_len_units,
+ int out_maxlen_bytes)
+{
+ int input_unit_index, output_byte_index = 0, byte_index_in_unit;
+ int number_escape_bytes_needed;
+
+ /* Try to copy integral addressable memory units until
+ (1) we run out of space or
+ (2) we copied all of them. */
+ for (input_unit_index = 0;
+ input_unit_index < len_units;
+ input_unit_index++)
+ {
+ /* Find out how many escape bytes we need for this unit. */
+ number_escape_bytes_needed = 0;
+ for (byte_index_in_unit = 0;
+ byte_index_in_unit < unit_size;
+ byte_index_in_unit++)
+ {
+ int idx = input_unit_index * unit_size + byte_index_in_unit;
+ gdb_byte b = buffer[idx];
+ if (needs_escaping (b))
+ number_escape_bytes_needed++;
+ }
+
+ /* Check if we have room to fit this escaped unit. */
+ if (output_byte_index + unit_size + number_escape_bytes_needed >
+ out_maxlen_bytes)
+ break;
+
+ /* Copy the unit byte per byte, adding escapes. */
+ for (byte_index_in_unit = 0;
+ byte_index_in_unit < unit_size;
+ byte_index_in_unit++)
+ {
+ int idx = input_unit_index * unit_size + byte_index_in_unit;
+ gdb_byte b = buffer[idx];
+ if (needs_escaping (b))
+ {
+ out_buf[output_byte_index++] = '}';
+ out_buf[output_byte_index++] = b ^ 0x20;
+ }
+ else
+ out_buf[output_byte_index++] = b;
+ }
+ }
+
+ *out_len_units = input_unit_index;
+ return output_byte_index;
+}
+
+/* See rsp-low.h. */
+
+int
+remote_unescape_input (const gdb_byte *buffer, int len,
+ gdb_byte *out_buf, int out_maxlen)
+{
+ int input_index, output_index;
+ int escaped;
+
+ output_index = 0;
+ escaped = 0;
+ for (input_index = 0; input_index < len; input_index++)
+ {
+ gdb_byte b = buffer[input_index];
+
+ if (output_index + 1 > out_maxlen)
+ error (_("Received too much data from the target."));
+
+ if (escaped)
+ {
+ out_buf[output_index++] = b ^ 0x20;
+ escaped = 0;
+ }
+ else if (b == '}')
+ escaped = 1;
+ else
+ out_buf[output_index++] = b;
+ }
+
+ if (escaped)
+ error (_("Unmatched escape character in target response."));
+
+ return output_index;
+}
+
diff --git a/gdb/gdbsupport/rsp-low.h b/gdb/gdbsupport/rsp-low.h
new file mode 100644
index 00000000000..b2b62c9e5b8
--- /dev/null
+++ b/gdb/gdbsupport/rsp-low.h
@@ -0,0 +1,101 @@
+/* Low-level RSP routines for GDB, the GNU debugger.
+
+ Copyright (C) 1988-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_RSP_LOW_H
+#define COMMON_RSP_LOW_H
+
+#include "gdbsupport/byte-vector.h"
+
+/* Convert hex digit A to a number, or throw an exception. */
+
+extern int fromhex (int a);
+
+/* Convert number NIB to a hex digit. */
+
+extern int tohex (int nib);
+
+/* Write a character representing the low order four bits of NIBBLE in
+ hex to *BUF. Returns BUF+1. */
+
+extern char *pack_nibble (char *buf, int nibble);
+
+/* Write the low byte of BYTE in hex to *BUF. Returns BUF+2. */
+
+extern char *pack_hex_byte (char *pkt, int byte);
+
+/* Read hex digits from BUFF and convert to a number, which is stored
+ in RESULT. Reads until a non-hex digit is seen. Returns a pointer
+ to the terminating character. */
+
+extern const char *unpack_varlen_hex (const char *buff, ULONGEST *result);
+
+/* HEX is a string of characters representing hexadecimal digits.
+ Convert pairs of hex digits to bytes and store sequentially into
+ BIN. COUNT is the maximum number of characters to convert. This
+ will convert fewer characters if the number of hex characters
+ actually seen is odd, or if HEX terminates before COUNT characters.
+ Returns the number of characters actually converted. */
+
+extern int hex2bin (const char *hex, gdb_byte *bin, int count);
+
+/* Like the above, but return a gdb::byte_vector. */
+
+gdb::byte_vector hex2bin (const char *hex);
+
+/* Like hex2bin, but return a std::string. */
+
+extern std::string hex2str (const char *hex);
+
+/* Like hex2bin, but return a std::string. */
+
+extern std::string hex2str (const char *hex, int count);
+
+/* Convert some bytes to a hexadecimal representation. BIN holds the
+ bytes to convert. COUNT says how many bytes to convert. The
+ resulting characters are stored in HEX, followed by a NUL
+ character. Returns the number of bytes actually converted. */
+
+extern int bin2hex (const gdb_byte *bin, char *hex, int count);
+
+/* Overloaded version of bin2hex that returns a std::string. */
+
+extern std::string bin2hex (const gdb_byte *bin, int count);
+
+/* Convert BUFFER, binary data at least LEN_UNITS addressable memory units
+ long, into escaped binary data in OUT_BUF. Only copy memory units that fit
+ completely in OUT_BUF. Set *OUT_LEN_UNITS to the number of units from
+ BUFFER successfully encoded in OUT_BUF, and return the number of bytes used
+ in OUT_BUF. The total number of bytes in the output buffer will be at most
+ OUT_MAXLEN_BYTES. This function properly escapes '*', and so is suitable
+ for the server side as well as the client. */
+
+extern int remote_escape_output (const gdb_byte *buffer, int len_units,
+ int unit_size, gdb_byte *out_buf,
+ int *out_len_units, int out_maxlen_bytes);
+
+/* Convert BUFFER, escaped data LEN bytes long, into binary data
+ in OUT_BUF. Return the number of bytes written to OUT_BUF.
+ Raise an error if the total number of bytes exceeds OUT_MAXLEN.
+
+ This function reverses remote_escape_output. */
+
+extern int remote_unescape_input (const gdb_byte *buffer, int len,
+ gdb_byte *out_buf, int out_maxlen);
+
+#endif /* COMMON_RSP_LOW_H */
diff --git a/gdb/gdbsupport/run-time-clock.c b/gdb/gdbsupport/run-time-clock.c
new file mode 100644
index 00000000000..26378a05d91
--- /dev/null
+++ b/gdb/gdbsupport/run-time-clock.c
@@ -0,0 +1,58 @@
+/* User/system CPU time clocks that follow the std::chrono interface.
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "run-time-clock.h"
+#if defined HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+using namespace std::chrono;
+
+run_time_clock::time_point
+run_time_clock::now () noexcept
+{
+ return time_point (microseconds (get_run_time ()));
+}
+
+#ifdef HAVE_GETRUSAGE
+static std::chrono::microseconds
+timeval_to_microseconds (struct timeval *tv)
+{
+ return (seconds (tv->tv_sec) + microseconds (tv->tv_usec));
+}
+#endif
+
+void
+run_time_clock::now (user_cpu_time_clock::time_point &user,
+ system_cpu_time_clock::time_point &system) noexcept
+{
+#ifdef HAVE_GETRUSAGE
+ struct rusage rusage;
+
+ getrusage (RUSAGE_SELF, &rusage);
+
+ microseconds utime = timeval_to_microseconds (&rusage.ru_utime);
+ microseconds stime = timeval_to_microseconds (&rusage.ru_stime);
+ user = user_cpu_time_clock::time_point (utime);
+ system = system_cpu_time_clock::time_point (stime);
+#else
+ user = user_cpu_time_clock::time_point (microseconds (get_run_time ()));
+ system = system_cpu_time_clock::time_point (microseconds::zero ());
+#endif
+}
diff --git a/gdb/gdbsupport/run-time-clock.h b/gdb/gdbsupport/run-time-clock.h
new file mode 100644
index 00000000000..9c15dd7ab12
--- /dev/null
+++ b/gdb/gdbsupport/run-time-clock.h
@@ -0,0 +1,75 @@
+/* User/system CPU time clocks that follow the std::chrono interface.
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_RUN_TIME_CLOCK_H
+#define COMMON_RUN_TIME_CLOCK_H
+
+#include <chrono>
+
+/* Count the total amount of time spent executing in user mode. */
+
+struct user_cpu_time_clock
+{
+ using duration = std::chrono::microseconds;
+ using rep = duration::rep;
+ using period = duration::period;
+ using time_point = std::chrono::time_point<user_cpu_time_clock>;
+
+ static constexpr bool is_steady = true;
+
+ /* Use run_time_clock::now instead. */
+ static time_point now () noexcept = delete;
+};
+
+/* Count the total amount of time spent executing in kernel mode. */
+
+struct system_cpu_time_clock
+{
+ using duration = std::chrono::microseconds;
+ using rep = duration::rep;
+ using period = duration::period;
+ using time_point = std::chrono::time_point<system_cpu_time_clock>;
+
+ static constexpr bool is_steady = true;
+
+ /* Use run_time_clock::now instead. */
+ static time_point now () noexcept = delete;
+};
+
+/* Count the total amount of time spent executing in userspace+kernel
+ mode. */
+
+struct run_time_clock
+{
+ using duration = std::chrono::microseconds;
+ using rep = duration::rep;
+ using period = duration::period;
+ using time_point = std::chrono::time_point<run_time_clock>;
+
+ static constexpr bool is_steady = true;
+
+ static time_point now () noexcept;
+
+ /* Return the user/system time as separate time points, if
+ supported. If not supported, then the combined user+kernel time
+ is returned in USER and SYSTEM is set to zero. */
+ static void now (user_cpu_time_clock::time_point &user,
+ system_cpu_time_clock::time_point &system) noexcept;
+};
+
+#endif /* COMMON_RUN_TIME_CLOCK_H */
diff --git a/gdb/gdbsupport/safe-iterator.h b/gdb/gdbsupport/safe-iterator.h
new file mode 100644
index 00000000000..89aec01884f
--- /dev/null
+++ b/gdb/gdbsupport/safe-iterator.h
@@ -0,0 +1,93 @@
+/* A safe iterator for GDB, the GNU debugger.
+ Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_SAFE_ITERATOR_H
+#define COMMON_SAFE_ITERATOR_H
+
+/* A forward iterator that wraps Iterator, such that when iterating
+ with iterator IT, it is possible to delete *IT without invalidating
+ IT. Suitably wrapped in a range type and used with range-for, this
+ allow convenient patterns like this:
+
+ // range_safe() returns a range type whose begin()/end() methods
+ // return safe iterators.
+ for (foo *f : range_safe ())
+ {
+ if (f->should_delete ())
+ {
+ // The ++it operation implicitly done by the range-for is
+ // still OK after this.
+ delete f;
+ }
+ }
+*/
+
+template<typename Iterator>
+class basic_safe_iterator
+{
+public:
+ typedef basic_safe_iterator self_type;
+ typedef typename Iterator::value_type value_type;
+ typedef typename Iterator::reference reference;
+ typedef typename Iterator::pointer pointer;
+ typedef typename Iterator::iterator_category iterator_category;
+ typedef typename Iterator::difference_type difference_type;
+
+ /* Construct by forwarding all arguments to the underlying
+ iterator. */
+ template<typename... Args>
+ explicit basic_safe_iterator (Args &&...args)
+ : m_it (std::forward<Args> (args)...),
+ m_next (m_it)
+ {
+ if (m_it != m_end)
+ ++m_next;
+ }
+
+ /* Create a one-past-end iterator. */
+ basic_safe_iterator ()
+ {}
+
+ value_type operator* () const { return *m_it; }
+
+ self_type &operator++ ()
+ {
+ m_it = m_next;
+ if (m_it != m_end)
+ ++m_next;
+ return *this;
+ }
+
+ bool operator== (const self_type &other) const
+ { return m_it == other.m_it; }
+
+ bool operator!= (const self_type &other) const
+ { return m_it != other.m_it; }
+
+private:
+ /* The current element. */
+ Iterator m_it {};
+
+ /* The next element. Always one element ahead of M_IT. */
+ Iterator m_next {};
+
+ /* A one-past-end iterator. */
+ Iterator m_end {};
+};
+
+#endif /* COMMON_SAFE_ITERATOR_H */
diff --git a/gdb/gdbsupport/scope-exit.h b/gdb/gdbsupport/scope-exit.h
new file mode 100644
index 00000000000..e2e6818295e
--- /dev/null
+++ b/gdb/gdbsupport/scope-exit.h
@@ -0,0 +1,186 @@
+/* Copyright (C) 2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_SCOPE_EXIT_H
+#define COMMON_SCOPE_EXIT_H
+
+#include <functional>
+#include <type_traits>
+#include "gdbsupport/preprocessor.h"
+
+/* scope_exit is a general-purpose scope guard that calls its exit
+ function at the end of the current scope. A scope_exit may be
+ canceled by calling the "release" method. The API is modeled on
+ P0052R5 - Generic Scope Guard and RAII Wrapper for the Standard
+ Library, which is itself based on Andrej Alexandrescu's
+ ScopeGuard/SCOPE_EXIT.
+
+ There are two forms available:
+
+ - The "make_scope_exit" form allows canceling the scope guard. Use
+ it like this:
+
+ auto cleanup = make_scope_exit ( <function, function object, lambda> );
+ ...
+ cleanup.release (); // cancel
+
+ - If you don't need to cancel the guard, you can use the SCOPE_EXIT
+ macro, like this:
+
+ SCOPE_EXIT
+ {
+ // any code you like here.
+ }
+
+ See also forward_scope_exit.
+*/
+
+/* CRTP base class for cancelable scope_exit-like classes. Implements
+ the common call-custom-function-from-dtor functionality. Classes
+ that inherit this implement the on_exit() method, which is called
+ from scope_exit_base's dtor. */
+
+template <typename CRTP>
+class scope_exit_base
+{
+public:
+ scope_exit_base () = default;
+
+ ~scope_exit_base ()
+ {
+ if (!m_released)
+ {
+ auto *self = static_cast<CRTP *> (this);
+ self->on_exit ();
+ }
+ }
+
+ /* This is needed for make_scope_exit because copy elision isn't
+ guaranteed until C++17. An optimizing compiler will usually skip
+ calling this, but it must exist. */
+ scope_exit_base (const scope_exit_base &other)
+ : m_released (other.m_released)
+ {
+ other.m_released = true;
+ }
+
+ void operator= (const scope_exit_base &) = delete;
+
+ /* If this is called, then the wrapped function will not be called
+ on destruction. */
+ void release () noexcept
+ {
+ m_released = true;
+ }
+
+private:
+
+ /* True if released. Mutable because of the copy ctor hack
+ above. */
+ mutable bool m_released = false;
+};
+
+/* The scope_exit class. */
+
+template<typename EF>
+class scope_exit : public scope_exit_base<scope_exit<EF>>
+{
+ /* For access to on_exit(). */
+ friend scope_exit_base<scope_exit<EF>>;
+
+public:
+
+ template<typename EFP,
+ typename = gdb::Requires<std::is_constructible<EF, EFP>>>
+ scope_exit (EFP &&f)
+ try : m_exit_function ((!std::is_lvalue_reference<EFP>::value
+ && std::is_nothrow_constructible<EF, EFP>::value)
+ ? std::move (f)
+ : f)
+ {
+ }
+ catch (...)
+ {
+ /* "If the initialization of exit_function throws an exception,
+ calls f()." */
+ f ();
+ }
+
+ template<typename EFP,
+ typename = gdb::Requires<std::is_constructible<EF, EFP>>>
+ scope_exit (scope_exit &&rhs)
+ noexcept (std::is_nothrow_move_constructible<EF>::value
+ || std::is_nothrow_copy_constructible<EF>::value)
+ : m_exit_function (std::is_nothrow_constructible<EFP>::value
+ ? std::move (rhs)
+ : rhs)
+ {
+ rhs.release ();
+ }
+
+ /* This is needed for make_scope_exit because copy elision isn't
+ guaranteed until C++17. An optimizing compiler will usually skip
+ calling this, but it must exist. */
+ scope_exit (const scope_exit &other)
+ : scope_exit_base<scope_exit<EF>> (other),
+ m_exit_function (other.m_exit_function)
+ {
+ }
+
+ void operator= (const scope_exit &) = delete;
+ void operator= (scope_exit &&) = delete;
+
+private:
+ void on_exit ()
+ {
+ m_exit_function ();
+ }
+
+ /* The function to call on scope exit. */
+ EF m_exit_function;
+};
+
+template <typename EF>
+scope_exit<typename std::decay<EF>::type>
+make_scope_exit (EF &&f)
+{
+ return scope_exit<typename std::decay<EF>::type> (std::forward<EF> (f));
+}
+
+namespace detail
+{
+
+enum class scope_exit_lhs {};
+
+template<typename EF>
+scope_exit<typename std::decay<EF>::type>
+operator+ (scope_exit_lhs, EF &&rhs)
+{
+ return scope_exit<typename std::decay<EF>::type> (std::forward<EF> (rhs));
+}
+
+}
+
+/* Register a block of code to run on scope exit. Note that the local
+ context is captured by reference, which means you should be careful
+ to avoid inadvertently changing a captured local's value before the
+ scope exit runs. */
+
+#define SCOPE_EXIT \
+ auto CONCAT(scope_exit_, __LINE__) = ::detail::scope_exit_lhs () + [&] ()
+
+#endif /* COMMON_SCOPE_EXIT_H */
diff --git a/gdb/gdbsupport/scoped_fd.h b/gdb/gdbsupport/scoped_fd.h
new file mode 100644
index 00000000000..c4a494b7018
--- /dev/null
+++ b/gdb/gdbsupport/scoped_fd.h
@@ -0,0 +1,87 @@
+/* scoped_fd, automatically close a file descriptor
+
+ Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_SCOPED_FD_H
+#define COMMON_SCOPED_FD_H
+
+#include <unistd.h>
+#include "filestuff.h"
+
+/* A smart-pointer-like class to automatically close a file descriptor. */
+
+class scoped_fd
+{
+public:
+ explicit scoped_fd (int fd = -1) noexcept : m_fd (fd) {}
+
+ scoped_fd (scoped_fd &&other)
+ : m_fd (other.m_fd)
+ {
+ other.m_fd = -1;
+ }
+
+ ~scoped_fd ()
+ {
+ if (m_fd >= 0)
+ close (m_fd);
+ }
+
+ scoped_fd &operator= (scoped_fd &&other)
+ {
+ if (m_fd != other.m_fd)
+ {
+ if (m_fd >= 0)
+ close (m_fd);
+ m_fd = other.m_fd;
+ other.m_fd = -1;
+ }
+ return *this;
+ }
+
+ DISABLE_COPY_AND_ASSIGN (scoped_fd);
+
+ ATTRIBUTE_UNUSED_RESULT int release () noexcept
+ {
+ int fd = m_fd;
+ m_fd = -1;
+ return fd;
+ }
+
+ /* Like release, but return a gdb_file_up that owns the file
+ descriptor. On success, this scoped_fd will be released. On
+ failure, return NULL and leave this scoped_fd in possession of
+ the fd. */
+ gdb_file_up to_file (const char *mode) noexcept
+ {
+ gdb_file_up result (fdopen (m_fd, mode));
+ if (result != nullptr)
+ m_fd = -1;
+ return result;
+ }
+
+ int get () const noexcept
+ {
+ return m_fd;
+ }
+
+private:
+ int m_fd;
+};
+
+#endif /* COMMON_SCOPED_FD_H */
diff --git a/gdb/gdbsupport/scoped_mmap.c b/gdb/gdbsupport/scoped_mmap.c
new file mode 100644
index 00000000000..9e0af57e4c9
--- /dev/null
+++ b/gdb/gdbsupport/scoped_mmap.c
@@ -0,0 +1,49 @@
+/* scoped_mmap, automatically unmap files
+
+ Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "scoped_mmap.h"
+#include "scoped_fd.h"
+#include "gdbsupport/filestuff.h"
+
+#ifdef HAVE_SYS_MMAN_H
+
+scoped_mmap
+mmap_file (const char *filename)
+{
+ scoped_fd fd (gdb_open_cloexec (filename, O_RDONLY, 0));
+ if (fd.get () < 0)
+ perror_with_name (("open"));
+
+ off_t size = lseek (fd.get (), 0, SEEK_END);
+ if (size < 0)
+ perror_with_name (("lseek"));
+
+ /* We can't map an empty file. */
+ if (size == 0)
+ error (_("file to mmap is empty"));
+
+ scoped_mmap mmapped_file (nullptr, size, PROT_READ, MAP_PRIVATE, fd.get (), 0);
+ if (mmapped_file.get () == MAP_FAILED)
+ perror_with_name (("mmap"));
+
+ return mmapped_file;
+}
+
+#endif /* HAVE_SYS_MMAN_H */
diff --git a/gdb/gdbsupport/scoped_mmap.h b/gdb/gdbsupport/scoped_mmap.h
new file mode 100644
index 00000000000..05cca9efa7d
--- /dev/null
+++ b/gdb/gdbsupport/scoped_mmap.h
@@ -0,0 +1,94 @@
+/* scoped_mmap, automatically unmap files
+
+ Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_SCOPED_MMAP_H
+#define COMMON_SCOPED_MMAP_H
+
+#ifdef HAVE_SYS_MMAN_H
+
+#include <sys/mman.h>
+
+/* A smart-pointer-like class to mmap() and automatically munmap() a memory
+ mapping. */
+
+class scoped_mmap
+{
+public:
+ scoped_mmap () noexcept : m_mem (MAP_FAILED), m_length (0) {}
+ scoped_mmap (void *addr, size_t length, int prot, int flags, int fd,
+ off_t offset) noexcept : m_length (length)
+ {
+ m_mem = mmap (addr, m_length, prot, flags, fd, offset);
+ }
+
+ ~scoped_mmap ()
+ {
+ destroy ();
+ }
+
+ scoped_mmap (scoped_mmap &&rhs)
+ {
+ destroy ();
+
+ m_mem = rhs.m_mem;
+ m_length = rhs.m_length;
+
+ rhs.m_mem = MAP_FAILED;
+ rhs.m_length = 0;
+ }
+
+ DISABLE_COPY_AND_ASSIGN (scoped_mmap);
+
+ ATTRIBUTE_UNUSED_RESULT void *release () noexcept
+ {
+ void *mem = m_mem;
+ m_mem = MAP_FAILED;
+ m_length = 0;
+ return mem;
+ }
+
+ void reset (void *addr, size_t length, int prot, int flags, int fd,
+ off_t offset) noexcept
+ {
+ destroy ();
+
+ m_length = length;
+ m_mem = mmap (addr, m_length, prot, flags, fd, offset);
+ }
+
+ size_t size () const noexcept { return m_length; }
+ void *get () const noexcept { return m_mem; }
+
+private:
+ void destroy ()
+ {
+ if (m_mem != MAP_FAILED)
+ munmap (m_mem, m_length);
+ }
+
+ void *m_mem;
+ size_t m_length;
+};
+
+/* Map FILENAME in memory. Throw an error if anything goes wrong. */
+scoped_mmap mmap_file (const char *filename);
+
+#endif /* HAVE_SYS_MMAN_H */
+
+#endif /* COMMON_SCOPED_MMAP_H */
diff --git a/gdb/gdbsupport/scoped_restore.h b/gdb/gdbsupport/scoped_restore.h
new file mode 100644
index 00000000000..54c3ff5f8a5
--- /dev/null
+++ b/gdb/gdbsupport/scoped_restore.h
@@ -0,0 +1,118 @@
+/* scoped_restore, a simple class for saving and restoring a value
+
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_SCOPED_RESTORE_H
+#define COMMON_SCOPED_RESTORE_H
+
+/* Base class for scoped_restore_tmpl. */
+class scoped_restore_base
+{
+public:
+ /* This informs the (scoped_restore_tmpl<T>) dtor that you no longer
+ want the original value restored. */
+ void release () const
+ { m_saved_var = NULL; }
+
+protected:
+ scoped_restore_base (void *saved_var)
+ : m_saved_var (saved_var)
+ {}
+
+ /* The type-erased saved variable. This is here so that clients can
+ call release() on a "scoped_restore" local, which is a typedef to
+ a scoped_restore_base. See below. */
+ mutable void *m_saved_var;
+};
+
+/* A convenience typedef. Users of make_scoped_restore declare the
+ local RAII object as having this type. */
+typedef const scoped_restore_base &scoped_restore;
+
+/* An RAII-based object that saves a variable's value, and then
+ restores it again when this object is destroyed. */
+template<typename T>
+class scoped_restore_tmpl : public scoped_restore_base
+{
+ public:
+
+ /* Create a new scoped_restore object that saves the current value
+ of *VAR. *VAR will be restored when this scoped_restore object
+ is destroyed. */
+ scoped_restore_tmpl (T *var)
+ : scoped_restore_base (var),
+ m_saved_value (*var)
+ {
+ }
+
+ /* Create a new scoped_restore object that saves the current value
+ of *VAR, and sets *VAR to VALUE. *VAR will be restored when this
+ scoped_restore object is destroyed. This is templated on T2 to
+ allow passing VALUEs of types convertible to T.
+ E.g.: T='base'; T2='derived'. */
+ template <typename T2>
+ scoped_restore_tmpl (T *var, T2 value)
+ : scoped_restore_base (var),
+ m_saved_value (*var)
+ {
+ *var = value;
+ }
+
+ scoped_restore_tmpl (const scoped_restore_tmpl<T> &other)
+ : scoped_restore_base {other.m_saved_var},
+ m_saved_value (other.m_saved_value)
+ {
+ other.m_saved_var = NULL;
+ }
+
+ ~scoped_restore_tmpl ()
+ {
+ if (saved_var () != NULL)
+ *saved_var () = m_saved_value;
+ }
+
+private:
+ /* Return a pointer to the saved variable with its type
+ restored. */
+ T *saved_var ()
+ { return static_cast<T *> (m_saved_var); }
+
+ /* No need for this. It is intentionally not defined anywhere. */
+ scoped_restore_tmpl &operator= (const scoped_restore_tmpl &);
+
+ /* The saved value. */
+ const T m_saved_value;
+};
+
+/* Make a scoped_restore. This is useful because it lets template
+ argument deduction work. */
+template<typename T>
+scoped_restore_tmpl<T> make_scoped_restore (T *var)
+{
+ return scoped_restore_tmpl<T> (var);
+}
+
+/* Make a scoped_restore. This is useful because it lets template
+ argument deduction work. */
+template<typename T, typename T2>
+scoped_restore_tmpl<T> make_scoped_restore (T *var, T2 value)
+{
+ return scoped_restore_tmpl<T> (var, value);
+}
+
+#endif /* COMMON_SCOPED_RESTORE_H */
diff --git a/gdb/gdbsupport/selftest.c b/gdb/gdbsupport/selftest.c
new file mode 100644
index 00000000000..f5a7b3c344b
--- /dev/null
+++ b/gdb/gdbsupport/selftest.c
@@ -0,0 +1,111 @@
+/* GDB self-testing.
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "common-exceptions.h"
+#include "common-debug.h"
+#include "selftest.h"
+#include <map>
+
+namespace selftests
+{
+/* All the tests that have been registered. Using an std::map allows keeping
+ the order of tests stable and easily looking up whether a test name
+ exists. */
+
+static std::map<std::string, std::unique_ptr<selftest>> tests;
+
+/* A selftest that calls the test function without arguments. */
+
+struct simple_selftest : public selftest
+{
+ simple_selftest (self_test_function *function_)
+ : function (function_)
+ {}
+
+ void operator() () const override
+ {
+ function ();
+ }
+
+ self_test_function *function;
+};
+
+/* See selftest.h. */
+
+void
+register_test (const std::string &name, selftest *test)
+{
+ /* Check that no test with this name already exist. */
+ gdb_assert (tests.find (name) == tests.end ());
+
+ tests[name] = std::unique_ptr<selftest> (test);
+}
+
+/* See selftest.h. */
+
+void
+register_test (const std::string &name, self_test_function *function)
+{
+ register_test (name, new simple_selftest (function));
+}
+
+/* See selftest.h. */
+
+void
+run_tests (const char *filter)
+{
+ int ran = 0, failed = 0;
+
+ for (const auto &pair : tests)
+ {
+ const std::string &name = pair.first;
+ const std::unique_ptr<selftest> &test = pair.second;
+
+ if (filter != NULL && *filter != '\0'
+ && name.find (filter) == std::string::npos)
+ continue;
+
+ try
+ {
+ debug_printf (_("Running selftest %s.\n"), name.c_str ());
+ ++ran;
+ (*test) ();
+ }
+ catch (const gdb_exception_error &ex)
+ {
+ ++failed;
+ debug_printf ("Self test failed: %s\n", ex.what ());
+ }
+
+ reset ();
+ }
+
+ debug_printf (_("Ran %d unit tests, %d failed\n"),
+ ran, failed);
+}
+
+/* See selftest.h. */
+
+void for_each_selftest (for_each_selftest_ftype func)
+{
+ for (const auto &pair : tests)
+ func (pair.first);
+}
+
+} // namespace selftests
diff --git a/gdb/gdbsupport/selftest.h b/gdb/gdbsupport/selftest.h
new file mode 100644
index 00000000000..c566ec5f3db
--- /dev/null
+++ b/gdb/gdbsupport/selftest.h
@@ -0,0 +1,73 @@
+/* GDB self-testing.
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_SELFTEST_H
+#define COMMON_SELFTEST_H
+
+/* A test is just a function that does some checks and throws an
+ exception if something has gone wrong. */
+
+typedef void self_test_function (void);
+
+namespace selftests
+{
+
+/* Interface for the various kinds of selftests. */
+
+struct selftest
+{
+ virtual ~selftest () = default;
+ virtual void operator() () const = 0;
+};
+
+/* Register a new self-test. */
+
+extern void register_test (const std::string &name, selftest *test);
+
+/* Register a new self-test. */
+
+extern void register_test (const std::string &name,
+ self_test_function *function);
+
+/* Run all the self tests. This print a message describing the number
+ of test and the number of failures.
+
+ If FILTER is not NULL and not empty, only tests with names containing FILTER
+ will be ran. */
+
+extern void run_tests (const char *filter);
+
+/* Reset GDB or GDBserver's internal state. */
+extern void reset ();
+
+typedef void for_each_selftest_ftype (const std::string &name);
+
+/* Call FUNC for each registered selftest. */
+
+extern void for_each_selftest (for_each_selftest_ftype func);
+}
+
+/* Check that VALUE is true, and, if not, throw an exception. */
+
+#define SELF_CHECK(VALUE) \
+ do { \
+ if (!(VALUE)) \
+ error (_("self-test failed at %s:%d"), __FILE__, __LINE__); \
+ } while (0)
+
+#endif /* COMMON_SELFTEST_H */
diff --git a/gdb/gdbsupport/signals-state-save-restore.c b/gdb/gdbsupport/signals-state-save-restore.c
new file mode 100644
index 00000000000..c66d2ddc62f
--- /dev/null
+++ b/gdb/gdbsupport/signals-state-save-restore.c
@@ -0,0 +1,117 @@
+/* Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "signals-state-save-restore.h"
+
+#include <signal.h>
+
+/* The original signal actions and mask. */
+
+#ifdef HAVE_SIGACTION
+static struct sigaction original_signal_actions[NSIG];
+
+/* Note that we use sigprocmask without worrying about threads because
+ the save/restore functions are called either from main, or after a
+ fork. In both cases, we know the calling process is single
+ threaded. */
+static sigset_t original_signal_mask;
+#endif
+
+/* See signals-state-save-restore.h. */
+
+void
+save_original_signals_state (bool quiet)
+{
+#ifdef HAVE_SIGACTION
+ int i;
+ int res;
+
+ res = sigprocmask (0, NULL, &original_signal_mask);
+ if (res == -1)
+ perror_with_name (("sigprocmask"));
+
+ bool found_preinstalled = false;
+
+ for (i = 1; i < NSIG; i++)
+ {
+ struct sigaction *oldact = &original_signal_actions[i];
+
+ res = sigaction (i, NULL, oldact);
+ if (res == -1 && errno == EINVAL)
+ {
+ /* Some signal numbers in the range are invalid. */
+ continue;
+ }
+ else if (res == -1)
+ perror_with_name (("sigaction"));
+
+ /* If we find a custom signal handler already installed, then
+ this function was called too late. This is a warning instead
+ of an internal error because this can also happen if you
+ LD_PRELOAD a library that installs a signal handler early via
+ __attribute__((constructor)), like libSegFault.so. */
+ if (!quiet
+ && oldact->sa_handler != SIG_DFL
+ && oldact->sa_handler != SIG_IGN)
+ {
+ found_preinstalled = true;
+
+ /* Use raw fprintf here because we're being called in early
+ startup, before GDB's filtered streams are created. */
+ fprintf (stderr,
+ _("warning: Found custom handler for signal "
+ "%d (%s) preinstalled.\n"), i,
+ strsignal (i));
+ }
+ }
+
+ if (found_preinstalled)
+ {
+ fprintf (stderr, _("\
+Some signal dispositions inherited from the environment (SIG_DFL/SIG_IGN)\n\
+won't be propagated to spawned programs.\n"));
+ }
+#endif
+}
+
+/* See signals-state-save-restore.h. */
+
+void
+restore_original_signals_state (void)
+{
+#ifdef HAVE_SIGACTION
+ int i;
+ int res;
+
+ for (i = 1; i < NSIG; i++)
+ {
+ res = sigaction (i, &original_signal_actions[i], NULL);
+ if (res == -1 && errno == EINVAL)
+ {
+ /* Some signal numbers in the range are invalid. */
+ continue;
+ }
+ else if (res == -1)
+ perror_with_name (("sigaction"));
+ }
+
+ res = sigprocmask (SIG_SETMASK, &original_signal_mask, NULL);
+ if (res == -1)
+ perror_with_name (("sigprocmask"));
+#endif
+}
diff --git a/gdb/gdbsupport/signals-state-save-restore.h b/gdb/gdbsupport/signals-state-save-restore.h
new file mode 100644
index 00000000000..de3d896621b
--- /dev/null
+++ b/gdb/gdbsupport/signals-state-save-restore.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_SIGNALS_STATE_SAVE_RESTORE_H
+#define COMMON_SIGNALS_STATE_SAVE_RESTORE_H
+
+/* Save/restore the signal actions of all signals, and the signal
+ mask.
+
+ Since the exec family of functions does not reset the signal
+ disposition of signals set to SIG_IGN, nor does it reset the signal
+ mask, in order to be transparent, when spawning new child processes
+ to debug (with "run", etc.), we must reset signal actions and mask
+ back to what was originally inherited from gdb/gdbserver's parent,
+ just before execing the target program to debug. */
+
+/* Save the signal state of all signals. If !QUIET, warn if we detect
+ a custom signal handler preinstalled. */
+
+extern void save_original_signals_state (bool quiet);
+
+/* Restore the signal state of all signals. */
+
+extern void restore_original_signals_state (void);
+
+#endif /* COMMON_SIGNALS_STATE_SAVE_RESTORE_H */
diff --git a/gdb/gdbsupport/signals.c b/gdb/gdbsupport/signals.c
new file mode 100644
index 00000000000..707bbe9fa3b
--- /dev/null
+++ b/gdb/gdbsupport/signals.c
@@ -0,0 +1,653 @@
+/* Target signal translation functions for GDB.
+ Copyright (C) 1990-2019 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#include "gdb_signals.h"
+
+struct gdbarch;
+
+/* Always use __SIGRTMIN if it's available. SIGRTMIN is the lowest
+ _available_ realtime signal, not the lowest supported; glibc takes
+ several for its own use. */
+
+#ifndef REALTIME_LO
+# if defined(__SIGRTMIN)
+# define REALTIME_LO __SIGRTMIN
+# define REALTIME_HI (__SIGRTMAX + 1)
+# elif defined(SIGRTMIN)
+# define REALTIME_LO SIGRTMIN
+# define REALTIME_HI (SIGRTMAX + 1)
+# endif
+#endif
+
+/* This table must match in order and size the signals in enum
+ gdb_signal. */
+
+static const struct {
+ const char *symbol;
+ const char *name;
+ const char *string;
+ } signals [] =
+{
+#define SET(symbol, constant, name, string) { #symbol, name, string },
+#include "gdb/signals.def"
+#undef SET
+};
+
+const char *
+gdb_signal_to_symbol_string (enum gdb_signal sig)
+{
+ gdb_assert ((int) sig >= GDB_SIGNAL_FIRST && (int) sig <= GDB_SIGNAL_LAST);
+
+ return signals[sig].symbol;
+}
+
+/* Return the string for a signal. */
+const char *
+gdb_signal_to_string (enum gdb_signal sig)
+{
+ if ((int) sig >= GDB_SIGNAL_FIRST && (int) sig <= GDB_SIGNAL_LAST)
+ return signals[sig].string;
+ else
+ return signals[GDB_SIGNAL_UNKNOWN].string;
+}
+
+/* Return the name for a signal. */
+const char *
+gdb_signal_to_name (enum gdb_signal sig)
+{
+ if ((int) sig >= GDB_SIGNAL_FIRST && (int) sig <= GDB_SIGNAL_LAST
+ && signals[sig].name != NULL)
+ return signals[sig].name;
+ else
+ /* I think the code which prints this will always print it along
+ with the string, so no need to be verbose (very old comment). */
+ return "?";
+}
+
+/* Given a name, return its signal. */
+enum gdb_signal
+gdb_signal_from_name (const char *name)
+{
+ enum gdb_signal sig;
+
+ /* It's possible we also should allow "SIGCLD" as well as "SIGCHLD"
+ for GDB_SIGNAL_SIGCHLD. SIGIOT, on the other hand, is more
+ questionable; seems like by now people should call it SIGABRT
+ instead. */
+
+ /* This ugly cast brought to you by the native VAX compiler. */
+ for (sig = GDB_SIGNAL_HUP;
+ sig < GDB_SIGNAL_LAST;
+ sig = (enum gdb_signal) ((int) sig + 1))
+ if (signals[sig].name != NULL
+ && strcmp (name, signals[sig].name) == 0)
+ return sig;
+ return GDB_SIGNAL_UNKNOWN;
+}
+
+/* The following functions are to help certain targets deal
+ with the signal/waitstatus stuff. They could just as well be in
+ a file called native-utils.c or unixwaitstatus-utils.c or whatever. */
+
+/* Convert host signal to our signals. */
+enum gdb_signal
+gdb_signal_from_host (int hostsig)
+{
+ /* A switch statement would make sense but would require special
+ kludges to deal with the cases where more than one signal has the
+ same number. Signals are ordered ANSI-standard signals first,
+ other signals second, with signals in each block ordered by their
+ numerical values on a typical POSIX platform. */
+
+ if (hostsig == 0)
+ return GDB_SIGNAL_0;
+
+ /* SIGINT, SIGILL, SIGABRT, SIGFPE, SIGSEGV and SIGTERM
+ are ANSI-standard signals and are always available. */
+ if (hostsig == SIGINT)
+ return GDB_SIGNAL_INT;
+ if (hostsig == SIGILL)
+ return GDB_SIGNAL_ILL;
+ if (hostsig == SIGABRT)
+ return GDB_SIGNAL_ABRT;
+ if (hostsig == SIGFPE)
+ return GDB_SIGNAL_FPE;
+ if (hostsig == SIGSEGV)
+ return GDB_SIGNAL_SEGV;
+ if (hostsig == SIGTERM)
+ return GDB_SIGNAL_TERM;
+
+ /* All other signals need preprocessor conditionals. */
+#if defined (SIGHUP)
+ if (hostsig == SIGHUP)
+ return GDB_SIGNAL_HUP;
+#endif
+#if defined (SIGQUIT)
+ if (hostsig == SIGQUIT)
+ return GDB_SIGNAL_QUIT;
+#endif
+#if defined (SIGTRAP)
+ if (hostsig == SIGTRAP)
+ return GDB_SIGNAL_TRAP;
+#endif
+#if defined (SIGEMT)
+ if (hostsig == SIGEMT)
+ return GDB_SIGNAL_EMT;
+#endif
+#if defined (SIGKILL)
+ if (hostsig == SIGKILL)
+ return GDB_SIGNAL_KILL;
+#endif
+#if defined (SIGBUS)
+ if (hostsig == SIGBUS)
+ return GDB_SIGNAL_BUS;
+#endif
+#if defined (SIGSYS)
+ if (hostsig == SIGSYS)
+ return GDB_SIGNAL_SYS;
+#endif
+#if defined (SIGPIPE)
+ if (hostsig == SIGPIPE)
+ return GDB_SIGNAL_PIPE;
+#endif
+#if defined (SIGALRM)
+ if (hostsig == SIGALRM)
+ return GDB_SIGNAL_ALRM;
+#endif
+#if defined (SIGUSR1)
+ if (hostsig == SIGUSR1)
+ return GDB_SIGNAL_USR1;
+#endif
+#if defined (SIGUSR2)
+ if (hostsig == SIGUSR2)
+ return GDB_SIGNAL_USR2;
+#endif
+#if defined (SIGCLD)
+ if (hostsig == SIGCLD)
+ return GDB_SIGNAL_CHLD;
+#endif
+#if defined (SIGCHLD)
+ if (hostsig == SIGCHLD)
+ return GDB_SIGNAL_CHLD;
+#endif
+#if defined (SIGPWR)
+ if (hostsig == SIGPWR)
+ return GDB_SIGNAL_PWR;
+#endif
+#if defined (SIGWINCH)
+ if (hostsig == SIGWINCH)
+ return GDB_SIGNAL_WINCH;
+#endif
+#if defined (SIGURG)
+ if (hostsig == SIGURG)
+ return GDB_SIGNAL_URG;
+#endif
+#if defined (SIGIO)
+ if (hostsig == SIGIO)
+ return GDB_SIGNAL_IO;
+#endif
+#if defined (SIGPOLL)
+ if (hostsig == SIGPOLL)
+ return GDB_SIGNAL_POLL;
+#endif
+#if defined (SIGSTOP)
+ if (hostsig == SIGSTOP)
+ return GDB_SIGNAL_STOP;
+#endif
+#if defined (SIGTSTP)
+ if (hostsig == SIGTSTP)
+ return GDB_SIGNAL_TSTP;
+#endif
+#if defined (SIGCONT)
+ if (hostsig == SIGCONT)
+ return GDB_SIGNAL_CONT;
+#endif
+#if defined (SIGTTIN)
+ if (hostsig == SIGTTIN)
+ return GDB_SIGNAL_TTIN;
+#endif
+#if defined (SIGTTOU)
+ if (hostsig == SIGTTOU)
+ return GDB_SIGNAL_TTOU;
+#endif
+#if defined (SIGVTALRM)
+ if (hostsig == SIGVTALRM)
+ return GDB_SIGNAL_VTALRM;
+#endif
+#if defined (SIGPROF)
+ if (hostsig == SIGPROF)
+ return GDB_SIGNAL_PROF;
+#endif
+#if defined (SIGXCPU)
+ if (hostsig == SIGXCPU)
+ return GDB_SIGNAL_XCPU;
+#endif
+#if defined (SIGXFSZ)
+ if (hostsig == SIGXFSZ)
+ return GDB_SIGNAL_XFSZ;
+#endif
+#if defined (SIGWIND)
+ if (hostsig == SIGWIND)
+ return GDB_SIGNAL_WIND;
+#endif
+#if defined (SIGPHONE)
+ if (hostsig == SIGPHONE)
+ return GDB_SIGNAL_PHONE;
+#endif
+#if defined (SIGLOST)
+ if (hostsig == SIGLOST)
+ return GDB_SIGNAL_LOST;
+#endif
+#if defined (SIGWAITING)
+ if (hostsig == SIGWAITING)
+ return GDB_SIGNAL_WAITING;
+#endif
+#if defined (SIGCANCEL)
+ if (hostsig == SIGCANCEL)
+ return GDB_SIGNAL_CANCEL;
+#endif
+#if defined (SIGLWP)
+ if (hostsig == SIGLWP)
+ return GDB_SIGNAL_LWP;
+#endif
+#if defined (SIGDANGER)
+ if (hostsig == SIGDANGER)
+ return GDB_SIGNAL_DANGER;
+#endif
+#if defined (SIGGRANT)
+ if (hostsig == SIGGRANT)
+ return GDB_SIGNAL_GRANT;
+#endif
+#if defined (SIGRETRACT)
+ if (hostsig == SIGRETRACT)
+ return GDB_SIGNAL_RETRACT;
+#endif
+#if defined (SIGMSG)
+ if (hostsig == SIGMSG)
+ return GDB_SIGNAL_MSG;
+#endif
+#if defined (SIGSOUND)
+ if (hostsig == SIGSOUND)
+ return GDB_SIGNAL_SOUND;
+#endif
+#if defined (SIGSAK)
+ if (hostsig == SIGSAK)
+ return GDB_SIGNAL_SAK;
+#endif
+#if defined (SIGPRIO)
+ if (hostsig == SIGPRIO)
+ return GDB_SIGNAL_PRIO;
+#endif
+
+ /* Mach exceptions. Assumes that the values for EXC_ are positive! */
+#if defined (EXC_BAD_ACCESS) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BAD_ACCESS)
+ return GDB_EXC_BAD_ACCESS;
+#endif
+#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BAD_INSTRUCTION)
+ return GDB_EXC_BAD_INSTRUCTION;
+#endif
+#if defined (EXC_ARITHMETIC) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_ARITHMETIC)
+ return GDB_EXC_ARITHMETIC;
+#endif
+#if defined (EXC_EMULATION) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_EMULATION)
+ return GDB_EXC_EMULATION;
+#endif
+#if defined (EXC_SOFTWARE) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_SOFTWARE)
+ return GDB_EXC_SOFTWARE;
+#endif
+#if defined (EXC_BREAKPOINT) && defined (_NSIG)
+ if (hostsig == _NSIG + EXC_BREAKPOINT)
+ return GDB_EXC_BREAKPOINT;
+#endif
+
+#if defined (SIGINFO)
+ if (hostsig == SIGINFO)
+ return GDB_SIGNAL_INFO;
+#endif
+#if defined (SIGLIBRT)
+ if (hostsig == SIGLIBRT)
+ return GDB_SIGNAL_LIBRT;
+#endif
+
+#if defined (REALTIME_LO)
+ if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI)
+ {
+ /* This block of GDB_SIGNAL_REALTIME value is in order. */
+ if (33 <= hostsig && hostsig <= 63)
+ return (enum gdb_signal)
+ (hostsig - 33 + (int) GDB_SIGNAL_REALTIME_33);
+ else if (hostsig == 32)
+ return GDB_SIGNAL_REALTIME_32;
+ else if (64 <= hostsig && hostsig <= 127)
+ return (enum gdb_signal)
+ (hostsig - 64 + (int) GDB_SIGNAL_REALTIME_64);
+ else
+ error (_("GDB bug: target.c (gdb_signal_from_host): "
+ "unrecognized real-time signal"));
+ }
+#endif
+
+ return GDB_SIGNAL_UNKNOWN;
+}
+
+/* Convert a OURSIG (an enum gdb_signal) to the form used by the
+ target operating system (refered to as the ``host'') or zero if the
+ equivalent host signal is not available. Set/clear OURSIG_OK
+ accordingly. */
+
+static int
+do_gdb_signal_to_host (enum gdb_signal oursig,
+ int *oursig_ok)
+{
+ int retsig;
+ /* Silence the 'not used' warning, for targets that
+ do not support signals. */
+ (void) retsig;
+
+ /* Signals are ordered ANSI-standard signals first, other signals
+ second, with signals in each block ordered by their numerical
+ values on a typical POSIX platform. */
+
+ *oursig_ok = 1;
+ switch (oursig)
+ {
+ case GDB_SIGNAL_0:
+ return 0;
+
+ /* SIGINT, SIGILL, SIGABRT, SIGFPE, SIGSEGV and SIGTERM
+ are ANSI-standard signals and are always available. */
+ case GDB_SIGNAL_INT:
+ return SIGINT;
+ case GDB_SIGNAL_ILL:
+ return SIGILL;
+ case GDB_SIGNAL_ABRT:
+ return SIGABRT;
+ case GDB_SIGNAL_FPE:
+ return SIGFPE;
+ case GDB_SIGNAL_SEGV:
+ return SIGSEGV;
+ case GDB_SIGNAL_TERM:
+ return SIGTERM;
+
+ /* All other signals need preprocessor conditionals. */
+#if defined (SIGHUP)
+ case GDB_SIGNAL_HUP:
+ return SIGHUP;
+#endif
+#if defined (SIGQUIT)
+ case GDB_SIGNAL_QUIT:
+ return SIGQUIT;
+#endif
+#if defined (SIGTRAP)
+ case GDB_SIGNAL_TRAP:
+ return SIGTRAP;
+#endif
+#if defined (SIGEMT)
+ case GDB_SIGNAL_EMT:
+ return SIGEMT;
+#endif
+#if defined (SIGKILL)
+ case GDB_SIGNAL_KILL:
+ return SIGKILL;
+#endif
+#if defined (SIGBUS)
+ case GDB_SIGNAL_BUS:
+ return SIGBUS;
+#endif
+#if defined (SIGSYS)
+ case GDB_SIGNAL_SYS:
+ return SIGSYS;
+#endif
+#if defined (SIGPIPE)
+ case GDB_SIGNAL_PIPE:
+ return SIGPIPE;
+#endif
+#if defined (SIGALRM)
+ case GDB_SIGNAL_ALRM:
+ return SIGALRM;
+#endif
+#if defined (SIGUSR1)
+ case GDB_SIGNAL_USR1:
+ return SIGUSR1;
+#endif
+#if defined (SIGUSR2)
+ case GDB_SIGNAL_USR2:
+ return SIGUSR2;
+#endif
+#if defined (SIGCHLD) || defined (SIGCLD)
+ case GDB_SIGNAL_CHLD:
+#if defined (SIGCHLD)
+ return SIGCHLD;
+#else
+ return SIGCLD;
+#endif
+#endif /* SIGCLD or SIGCHLD */
+#if defined (SIGPWR)
+ case GDB_SIGNAL_PWR:
+ return SIGPWR;
+#endif
+#if defined (SIGWINCH)
+ case GDB_SIGNAL_WINCH:
+ return SIGWINCH;
+#endif
+#if defined (SIGURG)
+ case GDB_SIGNAL_URG:
+ return SIGURG;
+#endif
+#if defined (SIGIO)
+ case GDB_SIGNAL_IO:
+ return SIGIO;
+#endif
+#if defined (SIGPOLL)
+ case GDB_SIGNAL_POLL:
+ return SIGPOLL;
+#endif
+#if defined (SIGSTOP)
+ case GDB_SIGNAL_STOP:
+ return SIGSTOP;
+#endif
+#if defined (SIGTSTP)
+ case GDB_SIGNAL_TSTP:
+ return SIGTSTP;
+#endif
+#if defined (SIGCONT)
+ case GDB_SIGNAL_CONT:
+ return SIGCONT;
+#endif
+#if defined (SIGTTIN)
+ case GDB_SIGNAL_TTIN:
+ return SIGTTIN;
+#endif
+#if defined (SIGTTOU)
+ case GDB_SIGNAL_TTOU:
+ return SIGTTOU;
+#endif
+#if defined (SIGVTALRM)
+ case GDB_SIGNAL_VTALRM:
+ return SIGVTALRM;
+#endif
+#if defined (SIGPROF)
+ case GDB_SIGNAL_PROF:
+ return SIGPROF;
+#endif
+#if defined (SIGXCPU)
+ case GDB_SIGNAL_XCPU:
+ return SIGXCPU;
+#endif
+#if defined (SIGXFSZ)
+ case GDB_SIGNAL_XFSZ:
+ return SIGXFSZ;
+#endif
+#if defined (SIGWIND)
+ case GDB_SIGNAL_WIND:
+ return SIGWIND;
+#endif
+#if defined (SIGPHONE)
+ case GDB_SIGNAL_PHONE:
+ return SIGPHONE;
+#endif
+#if defined (SIGLOST)
+ case GDB_SIGNAL_LOST:
+ return SIGLOST;
+#endif
+#if defined (SIGWAITING)
+ case GDB_SIGNAL_WAITING:
+ return SIGWAITING;
+#endif
+#if defined (SIGCANCEL)
+ case GDB_SIGNAL_CANCEL:
+ return SIGCANCEL;
+#endif
+#if defined (SIGLWP)
+ case GDB_SIGNAL_LWP:
+ return SIGLWP;
+#endif
+#if defined (SIGDANGER)
+ case GDB_SIGNAL_DANGER:
+ return SIGDANGER;
+#endif
+#if defined (SIGGRANT)
+ case GDB_SIGNAL_GRANT:
+ return SIGGRANT;
+#endif
+#if defined (SIGRETRACT)
+ case GDB_SIGNAL_RETRACT:
+ return SIGRETRACT;
+#endif
+#if defined (SIGMSG)
+ case GDB_SIGNAL_MSG:
+ return SIGMSG;
+#endif
+#if defined (SIGSOUND)
+ case GDB_SIGNAL_SOUND:
+ return SIGSOUND;
+#endif
+#if defined (SIGSAK)
+ case GDB_SIGNAL_SAK:
+ return SIGSAK;
+#endif
+#if defined (SIGPRIO)
+ case GDB_SIGNAL_PRIO:
+ return SIGPRIO;
+#endif
+
+ /* Mach exceptions. Assumes that the values for EXC_ are positive! */
+#if defined (EXC_BAD_ACCESS) && defined (_NSIG)
+ case GDB_EXC_BAD_ACCESS:
+ return _NSIG + EXC_BAD_ACCESS;
+#endif
+#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG)
+ case GDB_EXC_BAD_INSTRUCTION:
+ return _NSIG + EXC_BAD_INSTRUCTION;
+#endif
+#if defined (EXC_ARITHMETIC) && defined (_NSIG)
+ case GDB_EXC_ARITHMETIC:
+ return _NSIG + EXC_ARITHMETIC;
+#endif
+#if defined (EXC_EMULATION) && defined (_NSIG)
+ case GDB_EXC_EMULATION:
+ return _NSIG + EXC_EMULATION;
+#endif
+#if defined (EXC_SOFTWARE) && defined (_NSIG)
+ case GDB_EXC_SOFTWARE:
+ return _NSIG + EXC_SOFTWARE;
+#endif
+#if defined (EXC_BREAKPOINT) && defined (_NSIG)
+ case GDB_EXC_BREAKPOINT:
+ return _NSIG + EXC_BREAKPOINT;
+#endif
+
+#if defined (SIGINFO)
+ case GDB_SIGNAL_INFO:
+ return SIGINFO;
+#endif
+#if defined (SIGLIBRT)
+ case GDB_SIGNAL_LIBRT:
+ return SIGLIBRT;
+#endif
+
+ default:
+#if defined (REALTIME_LO)
+ retsig = 0;
+
+ if (oursig >= GDB_SIGNAL_REALTIME_33
+ && oursig <= GDB_SIGNAL_REALTIME_63)
+ {
+ /* This block of signals is continuous, and
+ GDB_SIGNAL_REALTIME_33 is 33 by definition. */
+ retsig = (int) oursig - (int) GDB_SIGNAL_REALTIME_33 + 33;
+ }
+ else if (oursig == GDB_SIGNAL_REALTIME_32)
+ {
+ /* GDB_SIGNAL_REALTIME_32 isn't contiguous with
+ GDB_SIGNAL_REALTIME_33. It is 32 by definition. */
+ retsig = 32;
+ }
+ else if (oursig >= GDB_SIGNAL_REALTIME_64
+ && oursig <= GDB_SIGNAL_REALTIME_127)
+ {
+ /* This block of signals is continuous, and
+ GDB_SIGNAL_REALTIME_64 is 64 by definition. */
+ retsig = (int) oursig - (int) GDB_SIGNAL_REALTIME_64 + 64;
+ }
+
+ if (retsig >= REALTIME_LO && retsig < REALTIME_HI)
+ return retsig;
+#endif
+
+ *oursig_ok = 0;
+ return 0;
+ }
+}
+
+int
+gdb_signal_to_host_p (enum gdb_signal oursig)
+{
+ int oursig_ok;
+ do_gdb_signal_to_host (oursig, &oursig_ok);
+ return oursig_ok;
+}
+
+int
+gdb_signal_to_host (enum gdb_signal oursig)
+{
+ int oursig_ok;
+ int targ_signo = do_gdb_signal_to_host (oursig, &oursig_ok);
+ if (!oursig_ok)
+ {
+ /* The user might be trying to do "signal SIGSAK" where this system
+ doesn't have SIGSAK. */
+ warning (_("Signal %s does not exist on this system."),
+ gdb_signal_to_name (oursig));
+ return 0;
+ }
+ else
+ return targ_signo;
+}
diff --git a/gdb/gdbsupport/symbol.h b/gdb/gdbsupport/symbol.h
new file mode 100644
index 00000000000..a42d50a194c
--- /dev/null
+++ b/gdb/gdbsupport/symbol.h
@@ -0,0 +1,37 @@
+/* Declarations of common symbol functions.
+
+ Copyright (C) 2014-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_SYMBOL_H
+#define COMMON_SYMBOL_H
+
+struct objfile;
+
+/* Find a symbol that matches NAME. Limit the search to OBJFILE if
+ OBJFILE is non-NULL and the implementation supports limiting the
+ search to specific object files. NAME may be mangled or demangled.
+ If a match is found, store the matching symbol's address in ADDR
+ and return zero. Returns nonzero if no symbol matching NAME is
+ found. Raise an exception if OBJFILE is non-NULL and the
+ implementation does not support limiting searches to specific
+ object files. This function must be provided by the client. */
+
+extern int find_minimal_symbol_address (const char *name, CORE_ADDR *addr,
+ struct objfile *objfile);
+
+#endif /* COMMON_SYMBOL_H */
diff --git a/gdb/gdbsupport/tdesc.c b/gdb/gdbsupport/tdesc.c
new file mode 100644
index 00000000000..1e2a3148132
--- /dev/null
+++ b/gdb/gdbsupport/tdesc.c
@@ -0,0 +1,401 @@
+/* Target description support for GDB.
+
+ Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "gdbsupport/tdesc.h"
+
+tdesc_reg::tdesc_reg (struct tdesc_feature *feature, const std::string &name_,
+ int regnum, int save_restore_, const char *group_,
+ int bitsize_, const char *type_)
+ : name (name_), target_regnum (regnum),
+ save_restore (save_restore_),
+ group (group_ != NULL ? group_ : ""),
+ bitsize (bitsize_),
+ type (type_ != NULL ? type_ : "<unknown>")
+{
+ /* If the register's type is target-defined, look it up now. We may not
+ have easy access to the containing feature when we want it later. */
+ tdesc_type = tdesc_named_type (feature, type.c_str ());
+}
+
+/* Predefined types. */
+static tdesc_type_builtin tdesc_predefined_types[] =
+{
+ { "bool", TDESC_TYPE_BOOL },
+ { "int8", TDESC_TYPE_INT8 },
+ { "int16", TDESC_TYPE_INT16 },
+ { "int32", TDESC_TYPE_INT32 },
+ { "int64", TDESC_TYPE_INT64 },
+ { "int128", TDESC_TYPE_INT128 },
+ { "uint8", TDESC_TYPE_UINT8 },
+ { "uint16", TDESC_TYPE_UINT16 },
+ { "uint32", TDESC_TYPE_UINT32 },
+ { "uint64", TDESC_TYPE_UINT64 },
+ { "uint128", TDESC_TYPE_UINT128 },
+ { "code_ptr", TDESC_TYPE_CODE_PTR },
+ { "data_ptr", TDESC_TYPE_DATA_PTR },
+ { "ieee_half", TDESC_TYPE_IEEE_HALF },
+ { "ieee_single", TDESC_TYPE_IEEE_SINGLE },
+ { "ieee_double", TDESC_TYPE_IEEE_DOUBLE },
+ { "arm_fpa_ext", TDESC_TYPE_ARM_FPA_EXT },
+ { "i387_ext", TDESC_TYPE_I387_EXT }
+};
+
+void tdesc_feature::accept (tdesc_element_visitor &v) const
+{
+ v.visit_pre (this);
+
+ for (const tdesc_type_up &type : types)
+ type->accept (v);
+
+ for (const tdesc_reg_up &reg : registers)
+ reg->accept (v);
+
+ v.visit_post (this);
+}
+
+bool tdesc_feature::operator== (const tdesc_feature &other) const
+{
+ if (name != other.name)
+ return false;
+
+ if (registers.size () != other.registers.size ())
+ return false;
+
+ for (int ix = 0; ix < registers.size (); ix++)
+ {
+ const tdesc_reg_up &reg1 = registers[ix];
+ const tdesc_reg_up &reg2 = other.registers[ix];
+
+ if (reg1 != reg2 && *reg1 != *reg2)
+ return false;
+ }
+
+ if (types.size () != other.types.size ())
+ return false;
+
+ for (int ix = 0; ix < types.size (); ix++)
+ {
+ const tdesc_type_up &type1 = types[ix];
+ const tdesc_type_up &type2 = other.types[ix];
+
+ if (type1 != type2 && *type1 != *type2)
+ return false;
+ }
+
+ return true;
+}
+
+/* Lookup a predefined type. */
+
+static struct tdesc_type *
+tdesc_predefined_type (enum tdesc_type_kind kind)
+{
+ for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
+ if (tdesc_predefined_types[ix].kind == kind)
+ return &tdesc_predefined_types[ix];
+
+ gdb_assert_not_reached ("bad predefined tdesc type");
+}
+
+/* See gdbsupport/tdesc.h. */
+
+struct tdesc_type *
+tdesc_named_type (const struct tdesc_feature *feature, const char *id)
+{
+ /* First try target-defined types. */
+ for (const tdesc_type_up &type : feature->types)
+ if (type->name == id)
+ return type.get ();
+
+ /* Next try the predefined types. */
+ for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
+ if (tdesc_predefined_types[ix].name == id)
+ return &tdesc_predefined_types[ix];
+
+ return NULL;
+}
+
+/* See gdbsupport/tdesc.h. */
+
+void
+tdesc_create_reg (struct tdesc_feature *feature, const char *name,
+ int regnum, int save_restore, const char *group,
+ int bitsize, const char *type)
+{
+ tdesc_reg *reg = new tdesc_reg (feature, name, regnum, save_restore,
+ group, bitsize, type);
+
+ feature->registers.emplace_back (reg);
+}
+
+/* See gdbsupport/tdesc.h. */
+
+struct tdesc_type *
+tdesc_create_vector (struct tdesc_feature *feature, const char *name,
+ struct tdesc_type *field_type, int count)
+{
+ tdesc_type_vector *type = new tdesc_type_vector (name, field_type, count);
+ feature->types.emplace_back (type);
+
+ return type;
+}
+
+/* See gdbsupport/tdesc.h. */
+
+tdesc_type_with_fields *
+tdesc_create_struct (struct tdesc_feature *feature, const char *name)
+{
+ tdesc_type_with_fields *type
+ = new tdesc_type_with_fields (name, TDESC_TYPE_STRUCT);
+ feature->types.emplace_back (type);
+
+ return type;
+}
+
+/* See gdbsupport/tdesc.h. */
+
+void
+tdesc_set_struct_size (tdesc_type_with_fields *type, int size)
+{
+ gdb_assert (type->kind == TDESC_TYPE_STRUCT);
+ gdb_assert (size > 0);
+ type->size = size;
+}
+
+/* See gdbsupport/tdesc.h. */
+
+tdesc_type_with_fields *
+tdesc_create_union (struct tdesc_feature *feature, const char *name)
+{
+ tdesc_type_with_fields *type
+ = new tdesc_type_with_fields (name, TDESC_TYPE_UNION);
+ feature->types.emplace_back (type);
+
+ return type;
+}
+
+/* See gdbsupport/tdesc.h. */
+
+tdesc_type_with_fields *
+tdesc_create_flags (struct tdesc_feature *feature, const char *name,
+ int size)
+{
+ gdb_assert (size > 0);
+
+ tdesc_type_with_fields *type
+ = new tdesc_type_with_fields (name, TDESC_TYPE_FLAGS, size);
+ feature->types.emplace_back (type);
+
+ return type;
+}
+
+/* See gdbsupport/tdesc.h. */
+
+tdesc_type_with_fields *
+tdesc_create_enum (struct tdesc_feature *feature, const char *name,
+ int size)
+{
+ gdb_assert (size > 0);
+
+ tdesc_type_with_fields *type
+ = new tdesc_type_with_fields (name, TDESC_TYPE_ENUM, size);
+ feature->types.emplace_back (type);
+
+ return type;
+}
+
+/* See gdbsupport/tdesc.h. */
+
+void
+tdesc_add_field (tdesc_type_with_fields *type, const char *field_name,
+ struct tdesc_type *field_type)
+{
+ gdb_assert (type->kind == TDESC_TYPE_UNION
+ || type->kind == TDESC_TYPE_STRUCT);
+
+ /* Initialize start and end so we know this is not a bit-field
+ when we print-c-tdesc. */
+ type->fields.emplace_back (field_name, field_type, -1, -1);
+}
+
+/* See gdbsupport/tdesc.h. */
+
+void
+tdesc_add_typed_bitfield (tdesc_type_with_fields *type, const char *field_name,
+ int start, int end, struct tdesc_type *field_type)
+{
+ gdb_assert (type->kind == TDESC_TYPE_STRUCT
+ || type->kind == TDESC_TYPE_FLAGS);
+ gdb_assert (start >= 0 && end >= start);
+
+ type->fields.emplace_back (field_name, field_type, start, end);
+}
+
+/* See gdbsupport/tdesc.h. */
+
+void
+tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name,
+ int start, int end)
+{
+ struct tdesc_type *field_type;
+
+ gdb_assert (start >= 0 && end >= start);
+
+ if (type->size > 4)
+ field_type = tdesc_predefined_type (TDESC_TYPE_UINT64);
+ else
+ field_type = tdesc_predefined_type (TDESC_TYPE_UINT32);
+
+ tdesc_add_typed_bitfield (type, field_name, start, end, field_type);
+}
+
+/* See gdbsupport/tdesc.h. */
+
+void
+tdesc_add_flag (tdesc_type_with_fields *type, int start,
+ const char *flag_name)
+{
+ gdb_assert (type->kind == TDESC_TYPE_FLAGS
+ || type->kind == TDESC_TYPE_STRUCT);
+
+ type->fields.emplace_back (flag_name,
+ tdesc_predefined_type (TDESC_TYPE_BOOL),
+ start, start);
+}
+
+/* See gdbsupport/tdesc.h. */
+
+void
+tdesc_add_enum_value (tdesc_type_with_fields *type, int value,
+ const char *name)
+{
+ gdb_assert (type->kind == TDESC_TYPE_ENUM);
+ type->fields.emplace_back (name,
+ tdesc_predefined_type (TDESC_TYPE_INT32),
+ value, -1);
+}
+
+void print_xml_feature::visit_pre (const tdesc_feature *e)
+{
+ string_appendf (*m_buffer, "<feature name=\"%s\">\n", e->name.c_str ());
+}
+
+void print_xml_feature::visit_post (const tdesc_feature *e)
+{
+ string_appendf (*m_buffer, "</feature>\n");
+}
+
+void print_xml_feature::visit (const tdesc_type_builtin *t)
+{
+ error (_("xml output is not supported for type \"%s\"."), t->name.c_str ());
+}
+
+void print_xml_feature::visit (const tdesc_type_vector *t)
+{
+ string_appendf (*m_buffer, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>\n",
+ t->name.c_str (), t->element_type->name.c_str (), t->count);
+}
+
+void print_xml_feature::visit (const tdesc_type_with_fields *t)
+{
+ const static char *types[] = { "struct", "union", "flags", "enum" };
+
+ gdb_assert (t->kind >= TDESC_TYPE_STRUCT && t->kind <= TDESC_TYPE_ENUM);
+
+ string_appendf (*m_buffer,
+ "<%s id=\"%s\"", types[t->kind - TDESC_TYPE_STRUCT],
+ t->name.c_str ());
+
+ switch (t->kind)
+ {
+ case TDESC_TYPE_STRUCT:
+ case TDESC_TYPE_FLAGS:
+ if (t->size > 0)
+ string_appendf (*m_buffer, " size=\"%d\"", t->size);
+ string_appendf (*m_buffer, ">\n");
+
+ for (const tdesc_type_field &f : t->fields)
+ {
+ string_appendf (*m_buffer, " <field name=\"%s\" ", f.name.c_str ());
+ if (f.start == -1)
+ string_appendf (*m_buffer, "type=\"%s\"/>\n",
+ f.type->name.c_str ());
+ else
+ string_appendf (*m_buffer, "start=\"%d\" end=\"%d\"/>\n", f.start,
+ f.end);
+ }
+ break;
+
+ case TDESC_TYPE_ENUM:
+ string_appendf (*m_buffer, ">\n");
+ for (const tdesc_type_field &f : t->fields)
+ string_appendf (*m_buffer, " <field name=\"%s\" start=\"%d\"/>\n",
+ f.name.c_str (), f.start);
+ break;
+
+ case TDESC_TYPE_UNION:
+ string_appendf (*m_buffer, ">\n");
+ for (const tdesc_type_field &f : t->fields)
+ string_appendf (*m_buffer, " <field name=\"%s\" type=\"%s\"/>\n",
+ f.name.c_str (), f.type->name.c_str ());
+ break;
+
+ default:
+ error (_("xml output is not supported for type \"%s\"."),
+ t->name.c_str ());
+ }
+
+ string_appendf (*m_buffer, "</%s>\n", types[t->kind - TDESC_TYPE_STRUCT]);
+}
+
+void print_xml_feature::visit (const tdesc_reg *r)
+{
+ string_appendf (*m_buffer,
+ "<reg name=\"%s\" bitsize=\"%d\" type=\"%s\" regnum=\"%ld\"",
+ r->name.c_str (), r->bitsize, r->type.c_str (),
+ r->target_regnum);
+
+ if (r->group.length () > 0)
+ string_appendf (*m_buffer, " group=\"%s\"", r->group.c_str ());
+
+ if (r->save_restore == 0)
+ string_appendf (*m_buffer, " save-restore=\"no\"");
+
+ string_appendf (*m_buffer, "/>\n");
+}
+
+void print_xml_feature::visit_pre (const target_desc *e)
+{
+#ifndef IN_PROCESS_AGENT
+ string_appendf (*m_buffer, "<?xml version=\"1.0\"?>\n");
+ string_appendf (*m_buffer, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n");
+ string_appendf (*m_buffer, "<target>\n<architecture>%s</architecture>\n",
+ tdesc_architecture_name (e));
+
+ const char *osabi = tdesc_osabi_name (e);
+ if (osabi != nullptr)
+ string_appendf (*m_buffer, "<osabi>%s</osabi>", osabi);
+#endif
+}
+
+void print_xml_feature::visit_post (const target_desc *e)
+{
+ string_appendf (*m_buffer, "</target>\n");
+}
diff --git a/gdb/gdbsupport/tdesc.h b/gdb/gdbsupport/tdesc.h
new file mode 100644
index 00000000000..9eb3d5ea312
--- /dev/null
+++ b/gdb/gdbsupport/tdesc.h
@@ -0,0 +1,408 @@
+/* Copyright (C) 2006-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_TDESC_H
+#define COMMON_TDESC_H
+
+struct tdesc_feature;
+struct tdesc_type;
+struct tdesc_type_builtin;
+struct tdesc_type_vector;
+struct tdesc_type_with_fields;
+struct tdesc_reg;
+struct target_desc;
+
+/* The interface to visit different elements of target description. */
+
+class tdesc_element_visitor
+{
+public:
+ virtual void visit_pre (const target_desc *e)
+ {}
+
+ virtual void visit_post (const target_desc *e)
+ {}
+
+ virtual void visit_pre (const tdesc_feature *e)
+ {}
+
+ virtual void visit_post (const tdesc_feature *e)
+ {}
+
+ virtual void visit (const tdesc_type_builtin *e)
+ {}
+
+ virtual void visit (const tdesc_type_vector *e)
+ {}
+
+ virtual void visit (const tdesc_type_with_fields *e)
+ {}
+
+ virtual void visit (const tdesc_reg *e)
+ {}
+};
+
+class tdesc_element
+{
+public:
+ virtual void accept (tdesc_element_visitor &v) const = 0;
+};
+
+/* An individual register from a target description. */
+
+struct tdesc_reg : tdesc_element
+{
+ tdesc_reg (struct tdesc_feature *feature, const std::string &name_,
+ int regnum, int save_restore_, const char *group_,
+ int bitsize_, const char *type_);
+
+ virtual ~tdesc_reg () = default;
+
+ DISABLE_COPY_AND_ASSIGN (tdesc_reg);
+
+ /* The name of this register. In standard features, it may be
+ recognized by the architecture support code, or it may be purely
+ for the user. */
+ std::string name;
+
+ /* The register number used by this target to refer to this
+ register. This is used for remote p/P packets and to determine
+ the ordering of registers in the remote g/G packets. */
+ long target_regnum;
+
+ /* If this flag is set, GDB should save and restore this register
+ around calls to an inferior function. */
+ int save_restore;
+
+ /* The name of the register group containing this register, or empty
+ if the group should be automatically determined from the
+ register's type. If this is "general", "float", or "vector", the
+ corresponding "info" command should display this register's
+ value. It can be an arbitrary string, but should be limited to
+ alphanumeric characters and internal hyphens. Currently other
+ strings are ignored (treated as empty). */
+ std::string group;
+
+ /* The size of the register, in bits. */
+ int bitsize;
+
+ /* The type of the register. This string corresponds to either
+ a named type from the target description or a predefined
+ type from GDB. */
+ std::string type;
+
+ /* The target-described type corresponding to TYPE, if found. */
+ struct tdesc_type *tdesc_type;
+
+ void accept (tdesc_element_visitor &v) const override
+ {
+ v.visit (this);
+ }
+
+ bool operator== (const tdesc_reg &other) const
+ {
+ return (name == other.name
+ && target_regnum == other.target_regnum
+ && save_restore == other.save_restore
+ && bitsize == other.bitsize
+ && group == other.group
+ && type == other.type);
+ }
+
+ bool operator!= (const tdesc_reg &other) const
+ {
+ return !(*this == other);
+ }
+};
+
+typedef std::unique_ptr<tdesc_reg> tdesc_reg_up;
+
+enum tdesc_type_kind
+{
+ /* Predefined types. */
+ TDESC_TYPE_BOOL,
+ TDESC_TYPE_INT8,
+ TDESC_TYPE_INT16,
+ TDESC_TYPE_INT32,
+ TDESC_TYPE_INT64,
+ TDESC_TYPE_INT128,
+ TDESC_TYPE_UINT8,
+ TDESC_TYPE_UINT16,
+ TDESC_TYPE_UINT32,
+ TDESC_TYPE_UINT64,
+ TDESC_TYPE_UINT128,
+ TDESC_TYPE_CODE_PTR,
+ TDESC_TYPE_DATA_PTR,
+ TDESC_TYPE_IEEE_HALF,
+ TDESC_TYPE_IEEE_SINGLE,
+ TDESC_TYPE_IEEE_DOUBLE,
+ TDESC_TYPE_ARM_FPA_EXT,
+ TDESC_TYPE_I387_EXT,
+
+ /* Types defined by a target feature. */
+ TDESC_TYPE_VECTOR,
+ TDESC_TYPE_STRUCT,
+ TDESC_TYPE_UNION,
+ TDESC_TYPE_FLAGS,
+ TDESC_TYPE_ENUM
+};
+
+struct tdesc_type : tdesc_element
+{
+ tdesc_type (const std::string &name_, enum tdesc_type_kind kind_)
+ : name (name_), kind (kind_)
+ {}
+
+ virtual ~tdesc_type () = default;
+
+ DISABLE_COPY_AND_ASSIGN (tdesc_type);
+
+ /* The name of this type. */
+ std::string name;
+
+ /* Identify the kind of this type. */
+ enum tdesc_type_kind kind;
+
+ bool operator== (const tdesc_type &other) const
+ {
+ return name == other.name && kind == other.kind;
+ }
+
+ bool operator!= (const tdesc_type &other) const
+ {
+ return !(*this == other);
+ }
+};
+
+typedef std::unique_ptr<tdesc_type> tdesc_type_up;
+
+struct tdesc_type_builtin : tdesc_type
+{
+ tdesc_type_builtin (const std::string &name, enum tdesc_type_kind kind)
+ : tdesc_type (name, kind)
+ {}
+
+ void accept (tdesc_element_visitor &v) const override
+ {
+ v.visit (this);
+ }
+};
+
+/* tdesc_type for vector types. */
+
+struct tdesc_type_vector : tdesc_type
+{
+ tdesc_type_vector (const std::string &name, tdesc_type *element_type_,
+ int count_)
+ : tdesc_type (name, TDESC_TYPE_VECTOR),
+ element_type (element_type_), count (count_)
+ {}
+
+ void accept (tdesc_element_visitor &v) const override
+ {
+ v.visit (this);
+ }
+
+ struct tdesc_type *element_type;
+ int count;
+};
+
+/* A named type from a target description. */
+
+struct tdesc_type_field
+{
+ tdesc_type_field (const std::string &name_, tdesc_type *type_,
+ int start_, int end_)
+ : name (name_), type (type_), start (start_), end (end_)
+ {}
+
+ std::string name;
+ struct tdesc_type *type;
+ /* For non-enum-values, either both are -1 (non-bitfield), or both are
+ not -1 (bitfield). For enum values, start is the value (which could be
+ -1), end is -1. */
+ int start, end;
+};
+
+/* tdesc_type for struct, union, flags, and enum types. */
+
+struct tdesc_type_with_fields : tdesc_type
+{
+ tdesc_type_with_fields (const std::string &name, tdesc_type_kind kind,
+ int size_ = 0)
+ : tdesc_type (name, kind), size (size_)
+ {}
+
+ void accept (tdesc_element_visitor &v) const override
+ {
+ v.visit (this);
+ }
+
+ std::vector<tdesc_type_field> fields;
+ int size;
+};
+
+/* A feature from a target description. Each feature is a collection
+ of other elements, e.g. registers and types. */
+
+struct tdesc_feature : tdesc_element
+{
+ tdesc_feature (const std::string &name_)
+ : name (name_)
+ {}
+
+ virtual ~tdesc_feature () = default;
+
+ DISABLE_COPY_AND_ASSIGN (tdesc_feature);
+
+ /* The name of this feature. It may be recognized by the architecture
+ support code. */
+ std::string name;
+
+ /* The registers associated with this feature. */
+ std::vector<tdesc_reg_up> registers;
+
+ /* The types associated with this feature. */
+ std::vector<tdesc_type_up> types;
+
+ void accept (tdesc_element_visitor &v) const override;
+
+ bool operator== (const tdesc_feature &other) const;
+
+ bool operator!= (const tdesc_feature &other) const
+ {
+ return !(*this == other);
+ }
+};
+
+typedef std::unique_ptr<tdesc_feature> tdesc_feature_up;
+
+/* Allocate a new target_desc. */
+target_desc *allocate_target_description (void);
+
+/* Set TARGET_DESC's architecture by NAME. */
+void set_tdesc_architecture (target_desc *target_desc,
+ const char *name);
+
+/* Return the architecture associated with this target description as a string,
+ or NULL if no architecture was specified. */
+const char *tdesc_architecture_name (const struct target_desc *target_desc);
+
+/* Set TARGET_DESC's osabi by NAME. */
+void set_tdesc_osabi (target_desc *target_desc, const char *name);
+
+/* Return the osabi associated with this target description as a string,
+ or NULL if no osabi was specified. */
+const char *tdesc_osabi_name (const struct target_desc *target_desc);
+
+/* Return the type associated with ID in the context of FEATURE, or
+ NULL if none. */
+struct tdesc_type *tdesc_named_type (const struct tdesc_feature *feature,
+ const char *id);
+
+/* Return the created feature named NAME in target description TDESC. */
+struct tdesc_feature *tdesc_create_feature (struct target_desc *tdesc,
+ const char *name);
+
+/* Return the created vector tdesc_type named NAME in FEATURE. */
+struct tdesc_type *tdesc_create_vector (struct tdesc_feature *feature,
+ const char *name,
+ struct tdesc_type *field_type,
+ int count);
+
+/* Return the created struct tdesc_type named NAME in FEATURE. */
+tdesc_type_with_fields *tdesc_create_struct (struct tdesc_feature *feature,
+ const char *name);
+
+/* Return the created union tdesc_type named NAME in FEATURE. */
+tdesc_type_with_fields *tdesc_create_union (struct tdesc_feature *feature,
+ const char *name);
+
+/* Return the created flags tdesc_type named NAME in FEATURE. */
+tdesc_type_with_fields *tdesc_create_flags (struct tdesc_feature *feature,
+ const char *name,
+ int size);
+
+/* Return the created enum tdesc_type named NAME in FEATURE. */
+tdesc_type_with_fields *tdesc_create_enum (struct tdesc_feature *feature,
+ const char *name,
+ int size);
+
+/* Add a new field to TYPE. FIELD_NAME is its name, and FIELD_TYPE is
+ its type. */
+void tdesc_add_field (tdesc_type_with_fields *type, const char *field_name,
+ struct tdesc_type *field_type);
+
+/* Add a new bitfield to TYPE, with range START to END. FIELD_NAME is its name,
+ and FIELD_TYPE is its type. */
+void tdesc_add_typed_bitfield (tdesc_type_with_fields *type,
+ const char *field_name,
+ int start, int end,
+ struct tdesc_type *field_type);
+
+/* Set the total length of TYPE. Structs which contain bitfields may
+ omit the reserved bits, so the end of the last field may not
+ suffice. */
+void tdesc_set_struct_size (tdesc_type_with_fields *type, int size);
+
+/* Add a new untyped bitfield to TYPE.
+ Untyped bitfields become either uint32 or uint64 depending on the size
+ of the underlying type. */
+void tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name,
+ int start, int end);
+
+/* A flag is just a typed(bool) single-bit bitfield.
+ This function is kept to minimize changes in generated files. */
+void tdesc_add_flag (tdesc_type_with_fields *type, int start,
+ const char *flag_name);
+
+/* Add field with VALUE and NAME to the enum TYPE. */
+void tdesc_add_enum_value (tdesc_type_with_fields *type, int value,
+ const char *name);
+
+/* Create a register in feature FEATURE. */
+void tdesc_create_reg (struct tdesc_feature *feature, const char *name,
+ int regnum, int save_restore, const char *group,
+ int bitsize, const char *type);
+
+/* Return the tdesc in string XML format. */
+
+const char *tdesc_get_features_xml (const target_desc *tdesc);
+
+/* Print target description as xml. */
+
+class print_xml_feature : public tdesc_element_visitor
+{
+public:
+ print_xml_feature (std::string *buffer_)
+ : m_buffer (buffer_)
+ {}
+
+ void visit_pre (const target_desc *e) override;
+ void visit_post (const target_desc *e) override;
+ void visit_pre (const tdesc_feature *e) override;
+ void visit_post (const tdesc_feature *e) override;
+ void visit (const tdesc_type_builtin *type) override;
+ void visit (const tdesc_type_vector *type) override;
+ void visit (const tdesc_type_with_fields *type) override;
+ void visit (const tdesc_reg *reg) override;
+
+private:
+ std::string *m_buffer;
+};
+
+#endif /* COMMON_TDESC_H */
diff --git a/gdb/gdbsupport/traits.h b/gdb/gdbsupport/traits.h
new file mode 100644
index 00000000000..de57c1903cd
--- /dev/null
+++ b/gdb/gdbsupport/traits.h
@@ -0,0 +1,109 @@
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_TRAITS_H
+#define COMMON_TRAITS_H
+
+#include <type_traits>
+
+/* GCC does not understand __has_feature. */
+#if !defined(__has_feature)
+# define __has_feature(x) 0
+#endif
+
+/* HAVE_IS_TRIVIALLY_COPYABLE is defined as 1 iff
+ std::is_trivially_copyable is available. GCC only implemented it
+ in GCC 5. */
+#if (__has_feature(is_trivially_copyable) \
+ || (defined __GNUC__ && __GNUC__ >= 5))
+# define HAVE_IS_TRIVIALLY_COPYABLE 1
+#endif
+
+/* HAVE_IS_TRIVIALLY_CONSTRUCTIBLE is defined as 1 iff
+ std::is_trivially_constructible is available. GCC only implemented it
+ in GCC 5. */
+#if (__has_feature(is_trivially_constructible) \
+ || (defined __GNUC__ && __GNUC__ >= 5))
+# define HAVE_IS_TRIVIALLY_CONSTRUCTIBLE 1
+#endif
+
+namespace gdb {
+
+/* Pre C++14-safe (CWG 1558) version of C++17's std::void_t. See
+ <http://en.cppreference.com/w/cpp/types/void_t>. */
+
+template<typename... Ts>
+struct make_void { typedef void type; };
+
+template<typename... Ts>
+using void_t = typename make_void<Ts...>::type;
+
+/* A few trait helpers, mainly stolen from libstdc++. Uppercase
+ because "and/or", etc. are reserved keywords. */
+
+template<typename Predicate>
+struct Not : public std::integral_constant<bool, !Predicate::value>
+{};
+
+template<typename...>
+struct Or;
+
+template<>
+struct Or<> : public std::false_type
+{};
+
+template<typename B1>
+struct Or<B1> : public B1
+{};
+
+template<typename B1, typename B2>
+struct Or<B1, B2>
+ : public std::conditional<B1::value, B1, B2>::type
+{};
+
+template<typename B1,typename B2,typename B3, typename... Bn>
+struct Or<B1, B2, B3, Bn...>
+ : public std::conditional<B1::value, B1, Or<B2, B3, Bn...>>::type
+{};
+
+template<typename...>
+struct And;
+
+template<>
+struct And<> : public std::true_type
+{};
+
+template<typename B1>
+struct And<B1> : public B1
+{};
+
+template<typename B1, typename B2>
+struct And<B1, B2>
+ : public std::conditional<B1::value, B2, B1>::type
+{};
+
+template<typename B1, typename B2, typename B3, typename... Bn>
+struct And<B1, B2, B3, Bn...>
+ : public std::conditional<B1::value, And<B2, B3, Bn...>, B1>::type
+{};
+
+/* Concepts-light-like helper to make SFINAE logic easier to read. */
+template<typename Condition>
+using Requires = typename std::enable_if<Condition::value, void>::type;
+}
+
+#endif /* COMMON_TRAITS_H */
diff --git a/gdb/gdbsupport/underlying.h b/gdb/gdbsupport/underlying.h
new file mode 100644
index 00000000000..af14a3627d5
--- /dev/null
+++ b/gdb/gdbsupport/underlying.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_UNDERLYING_H
+#define COMMON_UNDERLYING_H
+
+#include <type_traits>
+
+/* Convert an enum to its underlying value. */
+
+template<typename E>
+constexpr typename std::underlying_type<E>::type
+to_underlying (E val) noexcept
+{
+ return static_cast<typename std::underlying_type<E>::type> (val);
+}
+
+#endif
diff --git a/gdb/gdbsupport/valid-expr.h b/gdb/gdbsupport/valid-expr.h
new file mode 100644
index 00000000000..c622d3546e3
--- /dev/null
+++ b/gdb/gdbsupport/valid-expr.h
@@ -0,0 +1,108 @@
+/* Compile-time valid expression checker for GDB, the GNU debugger.
+
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Helper macros used to build compile-time unit tests that make sure
+ that invalid expressions that should not compile would not compile,
+ and that expressions that should compile do compile, and have the
+ right type. This is mainly used to verify that some utility's API
+ is really as safe as intended. */
+
+#ifndef COMMON_VALID_EXPR_H
+#define COMMON_VALID_EXPR_H
+
+#include "gdbsupport/preprocessor.h"
+#include "gdbsupport/traits.h"
+
+/* Macro that uses SFINAE magic to detect whether the EXPR expression
+ is either valid or ill-formed, at compile time, without actually
+ producing compile-time errors. I.e., check that bad uses of the
+ types (e.g., involving mismatching types) would be caught at
+ compile time. If the expression is valid, also check whether the
+ expression has the right type.
+
+ EXPR must be defined in terms of some of the template parameters,
+ so that template substitution failure discards the overload instead
+ of causing a real compile error. TYPES is thus the list of types
+ involved in the expression, and TYPENAMES is the same list, but
+ with each element prefixed by "typename". These are passed as
+ template parameter types to the templates within the macro.
+
+ VALID is a boolean that indicates whether the expression is
+ supposed to be valid or invalid.
+
+ EXPR_TYPE is the expected type of EXPR. Only meaningful iff VALID
+ is true. If VALID is false, then you must pass "void" as expected
+ type.
+
+ Each invocation of the macro is wrapped in its own namespace to
+ avoid ODR violations. The generated namespace only includes the
+ line number, so client code should wrap sets of calls in a
+ test-specific namespace too, to fully guarantee uniqueness between
+ the multiple clients in the codebase. */
+#define CHECK_VALID_EXPR_INT(TYPENAMES, TYPES, VALID, EXPR_TYPE, EXPR) \
+ namespace CONCAT (check_valid_expr, __LINE__) { \
+ \
+ template<typename, typename, typename = void> \
+ struct is_valid_expression \
+ : std::false_type {}; \
+ \
+ template <TYPENAMES> \
+ struct is_valid_expression<TYPES, gdb::void_t<decltype (EXPR)>> \
+ : std::true_type {}; \
+ \
+ static_assert (is_valid_expression<TYPES>::value == VALID, \
+ ""); \
+ \
+ template<TYPENAMES, typename = void> \
+ struct is_same_type \
+ : std::is_same<EXPR_TYPE, void> {}; \
+ \
+ template <TYPENAMES> \
+ struct is_same_type<TYPES, gdb::void_t<decltype (EXPR)>> \
+ : std::is_same<EXPR_TYPE, decltype (EXPR)> {}; \
+ \
+ static_assert (is_same_type<TYPES>::value, ""); \
+ } /* namespace */
+
+/* A few convenience macros that support expressions involving a
+ varying numbers of types. If you need more types, feel free to add
+ another variant. */
+
+#define CHECK_VALID_EXPR_1(T1, VALID, EXPR_TYPE, EXPR) \
+ CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1), \
+ ESC_PARENS (T1), \
+ VALID, EXPR_TYPE, EXPR)
+
+#define CHECK_VALID_EXPR_2(T1, T2, VALID, EXPR_TYPE, EXPR) \
+ CHECK_VALID_EXPR_INT (ESC_PARENS(typename T1, typename T2), \
+ ESC_PARENS (T1, T2), \
+ VALID, EXPR_TYPE, EXPR)
+
+#define CHECK_VALID_EXPR_3(T1, T2, T3, VALID, EXPR_TYPE, EXPR) \
+ CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1, typename T2, typename T3), \
+ ESC_PARENS (T1, T2, T3), \
+ VALID, EXPR_TYPE, EXPR)
+
+#define CHECK_VALID_EXPR_4(T1, T2, T3, T4, VALID, EXPR_TYPE, EXPR) \
+ CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1, typename T2, \
+ typename T3, typename T4), \
+ ESC_PARENS (T1, T2, T3, T4), \
+ VALID, EXPR_TYPE, EXPR)
+
+#endif /* COMMON_VALID_EXPR_H */
diff --git a/gdb/gdbsupport/vec.c b/gdb/gdbsupport/vec.c
new file mode 100644
index 00000000000..a8895449495
--- /dev/null
+++ b/gdb/gdbsupport/vec.c
@@ -0,0 +1,118 @@
+/* Vector API for GDB.
+ Copyright (C) 2004-2019 Free Software Foundation, Inc.
+ Contributed by Nathan Sidwell <nathan@codesourcery.com>
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "vec.h"
+
+struct vec_prefix
+{
+ unsigned num;
+ unsigned alloc;
+ void *vec[1];
+};
+
+/* Calculate the new ALLOC value, making sure that abs(RESERVE) slots
+ are free. If RESERVE < 0 grow exactly, otherwise grow
+ exponentially. */
+
+static inline unsigned
+calculate_allocation (const struct vec_prefix *pfx, int reserve)
+{
+ unsigned alloc = 0;
+ unsigned num = 0;
+
+ if (pfx)
+ {
+ alloc = pfx->alloc;
+ num = pfx->num;
+ }
+ else if (!reserve)
+ /* If there's no prefix, and we've not requested anything, then we
+ will create a NULL vector. */
+ return 0;
+
+ /* We must have run out of room. */
+ gdb_assert (alloc - num < (unsigned)(reserve < 0 ? -reserve : reserve));
+
+ if (reserve < 0)
+ /* Exact size. */
+ alloc = num + -reserve;
+ else
+ {
+ /* Exponential growth. */
+ if (!alloc)
+ alloc = 4;
+ else if (alloc < 16)
+ /* Double when small. */
+ alloc = alloc * 2;
+ else
+ /* Grow slower when large. */
+ alloc = (alloc * 3 / 2);
+
+ /* If this is still too small, set it to the right size. */
+ if (alloc < num + reserve)
+ alloc = num + reserve;
+ }
+ return alloc;
+}
+
+/* Ensure there are at least abs(RESERVE) free slots in VEC. If
+ RESERVE < 0 grow exactly, else grow exponentially. As a special
+ case, if VEC is NULL, and RESERVE is 0, no vector will be created. */
+
+void *
+vec_p_reserve (void *vec, int reserve)
+{
+ return vec_o_reserve (vec, reserve,
+ offsetof (struct vec_prefix, vec), sizeof (void *));
+}
+
+/* As vec_p_reserve, but for object vectors. The vector's trailing
+ array is at VEC_OFFSET offset and consists of ELT_SIZE sized
+ elements. */
+
+void *
+vec_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size)
+{
+ struct vec_prefix *pfx = (struct vec_prefix *) vec;
+ unsigned alloc = calculate_allocation (pfx, reserve);
+
+ if (!alloc)
+ return NULL;
+
+ vec = xrealloc (vec, vec_offset + alloc * elt_size);
+ ((struct vec_prefix *)vec)->alloc = alloc;
+ if (!pfx)
+ ((struct vec_prefix *)vec)->num = 0;
+
+ return vec;
+}
+
+#if 0
+/* Example uses. */
+DEF_VEC_I (int);
+typedef struct X
+{
+ int i;
+} obj_t;
+typedef obj_t *ptr_t;
+
+DEF_VEC_P (ptr_t);
+DEF_VEC_O (obj_t);
+#endif
diff --git a/gdb/gdbsupport/vec.h b/gdb/gdbsupport/vec.h
new file mode 100644
index 00000000000..8ac146d4903
--- /dev/null
+++ b/gdb/gdbsupport/vec.h
@@ -0,0 +1,1150 @@
+/* Vector API for GDB.
+ Copyright (C) 2004-2019 Free Software Foundation, Inc.
+ Contributed by Nathan Sidwell <nathan@codesourcery.com>
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_VEC_H
+#define COMMON_VEC_H
+
+#include "diagnostics.h"
+
+/* clang has a bug that makes it warn (-Wunused-function) about unused functions
+ that are the result of the DEF_VEC_* macro expansion. See:
+
+ https://bugs.llvm.org/show_bug.cgi?id=22712
+
+ We specifically ignore this warning for the vec functions when the compiler
+ is clang. */
+#ifdef __clang__
+# define DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
+ DIAGNOSTIC_IGNORE_UNUSED_FUNCTION
+#else
+# define DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION
+#endif
+
+/* The macros here implement a set of templated vector types and
+ associated interfaces. These templates are implemented with
+ macros, as we're not in C++ land. The interface functions are
+ typesafe and use static inline functions, sometimes backed by
+ out-of-line generic functions.
+
+ Because of the different behavior of structure objects, scalar
+ objects and of pointers, there are three flavors, one for each of
+ these variants. Both the structure object and pointer variants
+ pass pointers to objects around -- in the former case the pointers
+ are stored into the vector and in the latter case the pointers are
+ dereferenced and the objects copied into the vector. The scalar
+ object variant is suitable for int-like objects, and the vector
+ elements are returned by value.
+
+ There are both 'index' and 'iterate' accessors. The iterator
+ returns a boolean iteration condition and updates the iteration
+ variable passed by reference. Because the iterator will be
+ inlined, the address-of can be optimized away.
+
+ The vectors are implemented using the trailing array idiom, thus
+ they are not resizeable without changing the address of the vector
+ object itself. This means you cannot have variables or fields of
+ vector type -- always use a pointer to a vector. The one exception
+ is the final field of a structure, which could be a vector type.
+ You will have to use the embedded_size & embedded_init calls to
+ create such objects, and they will probably not be resizeable (so
+ don't use the 'safe' allocation variants). The trailing array
+ idiom is used (rather than a pointer to an array of data), because,
+ if we allow NULL to also represent an empty vector, empty vectors
+ occupy minimal space in the structure containing them.
+
+ Each operation that increases the number of active elements is
+ available in 'quick' and 'safe' variants. The former presumes that
+ there is sufficient allocated space for the operation to succeed
+ (it dies if there is not). The latter will reallocate the
+ vector, if needed. Reallocation causes an exponential increase in
+ vector size. If you know you will be adding N elements, it would
+ be more efficient to use the reserve operation before adding the
+ elements with the 'quick' operation. This will ensure there are at
+ least as many elements as you ask for, it will exponentially
+ increase if there are too few spare slots. If you want reserve a
+ specific number of slots, but do not want the exponential increase
+ (for instance, you know this is the last allocation), use a
+ negative number for reservation. You can also create a vector of a
+ specific size from the get go.
+
+ You should prefer the push and pop operations, as they append and
+ remove from the end of the vector. If you need to remove several
+ items in one go, use the truncate operation. The insert and remove
+ operations allow you to change elements in the middle of the
+ vector. There are two remove operations, one which preserves the
+ element ordering 'ordered_remove', and one which does not
+ 'unordered_remove'. The latter function copies the end element
+ into the removed slot, rather than invoke a memmove operation. The
+ 'lower_bound' function will determine where to place an item in the
+ array using insert that will maintain sorted order.
+
+ If you need to directly manipulate a vector, then the 'address'
+ accessor will return the address of the start of the vector. Also
+ the 'space' predicate will tell you whether there is spare capacity
+ in the vector. You will not normally need to use these two functions.
+
+ Vector types are defined using a DEF_VEC_{O,P,I}(TYPEDEF) macro.
+ Variables of vector type are declared using a VEC(TYPEDEF) macro.
+ The characters O, P and I indicate whether TYPEDEF is a pointer
+ (P), object (O) or integral (I) type. Be careful to pick the
+ correct one, as you'll get an awkward and inefficient API if you
+ use the wrong one. There is a check, which results in a
+ compile-time warning, for the P and I versions, but there is no
+ check for the O versions, as that is not possible in plain C.
+
+ An example of their use would be,
+
+ DEF_VEC_P(tree); // non-managed tree vector.
+
+ struct my_struct {
+ VEC(tree) *v; // A (pointer to) a vector of tree pointers.
+ };
+
+ struct my_struct *s;
+
+ if (VEC_length(tree, s->v)) { we have some contents }
+ VEC_safe_push(tree, s->v, decl); // append some decl onto the end
+ for (ix = 0; VEC_iterate(tree, s->v, ix, elt); ix++)
+ { do something with elt }
+
+*/
+
+/* Macros to invoke API calls. A single macro works for both pointer
+ and object vectors, but the argument and return types might well be
+ different. In each macro, T is the typedef of the vector elements.
+ Some of these macros pass the vector, V, by reference (by taking
+ its address), this is noted in the descriptions. */
+
+/* Length of vector
+ unsigned VEC_T_length(const VEC(T) *v);
+
+ Return the number of active elements in V. V can be NULL, in which
+ case zero is returned. */
+
+#define VEC_length(T,V) (VEC_OP(T,length)(V))
+
+
+/* Check if vector is empty
+ int VEC_T_empty(const VEC(T) *v);
+
+ Return nonzero if V is an empty vector (or V is NULL), zero otherwise. */
+
+#define VEC_empty(T,V) (VEC_length (T,V) == 0)
+
+
+/* Get the final element of the vector.
+ T VEC_T_last(VEC(T) *v); // Integer
+ T VEC_T_last(VEC(T) *v); // Pointer
+ T *VEC_T_last(VEC(T) *v); // Object
+
+ Return the final element. V must not be empty. */
+
+#define VEC_last(T,V) (VEC_OP(T,last)(V VEC_ASSERT_INFO))
+
+/* Index into vector
+ T VEC_T_index(VEC(T) *v, unsigned ix); // Integer
+ T VEC_T_index(VEC(T) *v, unsigned ix); // Pointer
+ T *VEC_T_index(VEC(T) *v, unsigned ix); // Object
+
+ Return the IX'th element. If IX must be in the domain of V. */
+
+#define VEC_index(T,V,I) (VEC_OP(T,index)(V,I VEC_ASSERT_INFO))
+
+/* Iterate over vector
+ int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Integer
+ int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Pointer
+ int VEC_T_iterate(VEC(T) *v, unsigned ix, T *&ptr); // Object
+
+ Return iteration condition and update PTR to point to the IX'th
+ element. At the end of iteration, sets PTR to NULL. Use this to
+ iterate over the elements of a vector as follows,
+
+ for (ix = 0; VEC_iterate(T,v,ix,ptr); ix++)
+ continue; */
+
+#define VEC_iterate(T,V,I,P) (VEC_OP(T,iterate)(V,I,&(P)))
+
+/* Allocate new vector.
+ VEC(T,A) *VEC_T_alloc(int reserve);
+
+ Allocate a new vector with space for RESERVE objects. If RESERVE
+ is zero, NO vector is created. */
+
+#define VEC_alloc(T,N) (VEC_OP(T,alloc)(N))
+
+/* Free a vector.
+ void VEC_T_free(VEC(T,A) *&);
+
+ Free a vector and set it to NULL. */
+
+#define VEC_free(T,V) (VEC_OP(T,free)(&V))
+
+/* A cleanup function for a vector.
+ void VEC_T_cleanup(void *);
+
+ Clean up a vector. */
+
+#define VEC_cleanup(T) (VEC_OP(T,cleanup))
+
+/* Use these to determine the required size and initialization of a
+ vector embedded within another structure (as the final member).
+
+ size_t VEC_T_embedded_size(int reserve);
+ void VEC_T_embedded_init(VEC(T) *v, int reserve);
+
+ These allow the caller to perform the memory allocation. */
+
+#define VEC_embedded_size(T,N) (VEC_OP(T,embedded_size)(N))
+#define VEC_embedded_init(T,O,N) (VEC_OP(T,embedded_init)(VEC_BASE(O),N))
+
+/* Copy a vector.
+ VEC(T,A) *VEC_T_copy(VEC(T) *);
+
+ Copy the live elements of a vector into a new vector. The new and
+ old vectors need not be allocated by the same mechanism. */
+
+#define VEC_copy(T,V) (VEC_OP(T,copy)(V))
+
+/* Merge two vectors.
+ VEC(T,A) *VEC_T_merge(VEC(T) *, VEC(T) *);
+
+ Copy the live elements of both vectors into a new vector. The new
+ and old vectors need not be allocated by the same mechanism. */
+#define VEC_merge(T,V1,V2) (VEC_OP(T,merge)(V1, V2))
+
+/* Determine if a vector has additional capacity.
+
+ int VEC_T_space (VEC(T) *v,int reserve)
+
+ If V has space for RESERVE additional entries, return nonzero. You
+ usually only need to use this if you are doing your own vector
+ reallocation, for instance on an embedded vector. This returns
+ nonzero in exactly the same circumstances that VEC_T_reserve
+ will. */
+
+#define VEC_space(T,V,R) (VEC_OP(T,space)(V,R VEC_ASSERT_INFO))
+
+/* Reserve space.
+ int VEC_T_reserve(VEC(T,A) *&v, int reserve);
+
+ Ensure that V has at least abs(RESERVE) slots available. The
+ signedness of RESERVE determines the reallocation behavior. A
+ negative value will not create additional headroom beyond that
+ requested. A positive value will create additional headroom. Note
+ this can cause V to be reallocated. Returns nonzero iff
+ reallocation actually occurred. */
+
+#define VEC_reserve(T,V,R) (VEC_OP(T,reserve)(&(V),R VEC_ASSERT_INFO))
+
+/* Push object with no reallocation
+ T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer
+ T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
+ T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object
+
+ Push a new element onto the end, returns a pointer to the slot
+ filled in. For object vectors, the new value can be NULL, in which
+ case NO initialization is performed. There must
+ be sufficient space in the vector. */
+
+#define VEC_quick_push(T,V,O) (VEC_OP(T,quick_push)(V,O VEC_ASSERT_INFO))
+
+/* Push object with reallocation
+ T *VEC_T_safe_push (VEC(T,A) *&v, T obj); // Integer
+ T *VEC_T_safe_push (VEC(T,A) *&v, T obj); // Pointer
+ T *VEC_T_safe_push (VEC(T,A) *&v, T *obj); // Object
+
+ Push a new element onto the end, returns a pointer to the slot
+ filled in. For object vectors, the new value can be NULL, in which
+ case NO initialization is performed. Reallocates V, if needed. */
+
+#define VEC_safe_push(T,V,O) (VEC_OP(T,safe_push)(&(V),O VEC_ASSERT_INFO))
+
+/* Pop element off end
+ T VEC_T_pop (VEC(T) *v); // Integer
+ T VEC_T_pop (VEC(T) *v); // Pointer
+ void VEC_T_pop (VEC(T) *v); // Object
+
+ Pop the last element off the end. Returns the element popped, for
+ pointer vectors. */
+
+#define VEC_pop(T,V) (VEC_OP(T,pop)(V VEC_ASSERT_INFO))
+
+/* Truncate to specific length
+ void VEC_T_truncate (VEC(T) *v, unsigned len);
+
+ Set the length as specified. The new length must be less than or
+ equal to the current length. This is an O(1) operation. */
+
+#define VEC_truncate(T,V,I) \
+ (VEC_OP(T,truncate)(V,I VEC_ASSERT_INFO))
+
+/* Grow to a specific length.
+ void VEC_T_safe_grow (VEC(T,A) *&v, int len);
+
+ Grow the vector to a specific length. The LEN must be as
+ long or longer than the current length. The new elements are
+ uninitialized. */
+
+#define VEC_safe_grow(T,V,I) \
+ (VEC_OP(T,safe_grow)(&(V),I VEC_ASSERT_INFO))
+
+/* Replace element
+ T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Integer
+ T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Pointer
+ T *VEC_T_replace (VEC(T) *v, unsigned ix, T *val); // Object
+
+ Replace the IXth element of V with a new value, VAL. For pointer
+ vectors returns the original value. For object vectors returns a
+ pointer to the new value. For object vectors the new value can be
+ NULL, in which case no overwriting of the slot is actually
+ performed. */
+
+#define VEC_replace(T,V,I,O) (VEC_OP(T,replace)(V,I,O VEC_ASSERT_INFO))
+
+/* Insert object with no reallocation
+ T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer
+ T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer
+ T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object
+
+ Insert an element, VAL, at the IXth position of V. Return a pointer
+ to the slot created. For vectors of object, the new value can be
+ NULL, in which case no initialization of the inserted slot takes
+ place. There must be sufficient space. */
+
+#define VEC_quick_insert(T,V,I,O) \
+ (VEC_OP(T,quick_insert)(V,I,O VEC_ASSERT_INFO))
+
+/* Insert object with reallocation
+ T *VEC_T_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Integer
+ T *VEC_T_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Pointer
+ T *VEC_T_safe_insert (VEC(T,A) *&v, unsigned ix, T *val); // Object
+
+ Insert an element, VAL, at the IXth position of V. Return a pointer
+ to the slot created. For vectors of object, the new value can be
+ NULL, in which case no initialization of the inserted slot takes
+ place. Reallocate V, if necessary. */
+
+#define VEC_safe_insert(T,V,I,O) \
+ (VEC_OP(T,safe_insert)(&(V),I,O VEC_ASSERT_INFO))
+
+/* Remove element retaining order
+ T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer
+ T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer
+ void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Object
+
+ Remove an element from the IXth position of V. Ordering of
+ remaining elements is preserved. For pointer vectors returns the
+ removed object. This is an O(N) operation due to a memmove. */
+
+#define VEC_ordered_remove(T,V,I) \
+ (VEC_OP(T,ordered_remove)(V,I VEC_ASSERT_INFO))
+
+/* Remove element destroying order
+ T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer
+ T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer
+ void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Object
+
+ Remove an element from the IXth position of V. Ordering of
+ remaining elements is destroyed. For pointer vectors returns the
+ removed object. This is an O(1) operation. */
+
+#define VEC_unordered_remove(T,V,I) \
+ (VEC_OP(T,unordered_remove)(V,I VEC_ASSERT_INFO))
+
+/* Remove a block of elements
+ void VEC_T_block_remove (VEC(T) *v, unsigned ix, unsigned len);
+
+ Remove LEN elements starting at the IXth. Ordering is retained.
+ This is an O(N) operation due to memmove. */
+
+#define VEC_block_remove(T,V,I,L) \
+ (VEC_OP(T,block_remove)(V,I,L VEC_ASSERT_INFO))
+
+/* Get the address of the array of elements
+ T *VEC_T_address (VEC(T) v)
+
+ If you need to directly manipulate the array (for instance, you
+ want to feed it to qsort), use this accessor. */
+
+#define VEC_address(T,V) (VEC_OP(T,address)(V))
+
+/* Find the first index in the vector not less than the object.
+ unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
+ int (*lessthan) (const T, const T)); // Integer
+ unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
+ int (*lessthan) (const T, const T)); // Pointer
+ unsigned VEC_T_lower_bound (VEC(T) *v, const T *val,
+ int (*lessthan) (const T*, const T*)); // Object
+
+ Find the first position in which VAL could be inserted without
+ changing the ordering of V. LESSTHAN is a function that returns
+ true if the first argument is strictly less than the second. */
+
+#define VEC_lower_bound(T,V,O,LT) \
+ (VEC_OP(T,lower_bound)(V,O,LT VEC_ASSERT_INFO))
+
+/* Reallocate an array of elements with prefix. */
+extern void *vec_p_reserve (void *, int);
+extern void *vec_o_reserve (void *, int, size_t, size_t);
+#define vec_free_(V) xfree (V)
+
+#define VEC_ASSERT_INFO ,__FILE__,__LINE__
+#define VEC_ASSERT_DECL ,const char *file_,unsigned line_
+#define VEC_ASSERT_PASS ,file_,line_
+#define vec_assert(expr, op) \
+ ((void)((expr) ? 0 : (gdb_assert_fail (op, file_, line_, \
+ FUNCTION_NAME), 0)))
+
+#define VEC(T) VEC_##T
+#define VEC_OP(T,OP) VEC_##T##_##OP
+
+#define VEC_T(T) \
+typedef struct VEC(T) \
+{ \
+ unsigned num; \
+ unsigned alloc; \
+ T vec[1]; \
+} VEC(T)
+
+/* Vector of integer-like object. */
+#define DEF_VEC_I(T) \
+DIAGNOSTIC_PUSH \
+DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
+static inline void VEC_OP (T,must_be_integral_type) (void) \
+{ \
+ (void)~(T)0; \
+} \
+ \
+VEC_T(T); \
+DEF_VEC_FUNC_P(T) \
+DEF_VEC_ALLOC_FUNC_I(T) \
+DIAGNOSTIC_POP \
+struct vec_swallow_trailing_semi
+
+/* Vector of pointer to object. */
+#define DEF_VEC_P(T) \
+DIAGNOSTIC_PUSH \
+DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
+static inline void VEC_OP (T,must_be_pointer_type) (void) \
+{ \
+ (void)((T)1 == (void *)1); \
+} \
+ \
+VEC_T(T); \
+DEF_VEC_FUNC_P(T) \
+DEF_VEC_ALLOC_FUNC_P(T) \
+DIAGNOSTIC_POP \
+struct vec_swallow_trailing_semi
+
+/* Vector of object. */
+#define DEF_VEC_O(T) \
+DIAGNOSTIC_PUSH \
+DIAGNOSTIC_IGNORE_UNUSED_VEC_FUNCTION \
+VEC_T(T); \
+DEF_VEC_FUNC_O(T) \
+DEF_VEC_ALLOC_FUNC_O(T) \
+DIAGNOSTIC_POP \
+struct vec_swallow_trailing_semi
+
+/* Avoid offsetof (or its usual C implementation) as it triggers
+ -Winvalid-offsetof warnings with enum_flags types with G++ <= 4.4,
+ even though those types are memcpyable. This requires allocating a
+ dummy local VEC in all routines that use this, but that has the
+ advantage that it only works if T is default constructible, which
+ is exactly a check we want, to keep C compatibility. */
+#define vec_offset(T, VPTR) ((size_t) ((char *) &(VPTR)->vec - (char *) VPTR))
+
+#define DEF_VEC_ALLOC_FUNC_I(T) \
+static inline VEC(T) *VEC_OP (T,alloc) \
+ (int alloc_) \
+{ \
+ VEC(T) dummy; \
+ \
+ /* We must request exact size allocation, hence the negation. */ \
+ return (VEC(T) *) vec_o_reserve (NULL, -alloc_, \
+ vec_offset (T, &dummy), sizeof (T)); \
+} \
+ \
+static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
+{ \
+ size_t len_ = vec_ ? vec_->num : 0; \
+ VEC (T) *new_vec_ = NULL; \
+ \
+ if (len_) \
+ { \
+ VEC(T) dummy; \
+ \
+ /* We must request exact size allocation, hence the negation. */ \
+ new_vec_ = (VEC (T) *) \
+ vec_o_reserve (NULL, -len_, vec_offset (T, &dummy), sizeof (T)); \
+ \
+ new_vec_->num = len_; \
+ memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
+ } \
+ return new_vec_; \
+} \
+ \
+static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
+{ \
+ if (vec1_ && vec2_) \
+ { \
+ VEC(T) dummy; \
+ size_t len_ = vec1_->num + vec2_->num; \
+ VEC (T) *new_vec_ = NULL; \
+ \
+ /* We must request exact size allocation, hence the negation. */ \
+ new_vec_ = (VEC (T) *) \
+ vec_o_reserve (NULL, -len_, vec_offset (T, &dummy), sizeof (T)); \
+ \
+ new_vec_->num = len_; \
+ memcpy (new_vec_->vec, vec1_->vec, sizeof (T) * vec1_->num); \
+ memcpy (new_vec_->vec + vec1_->num, vec2_->vec, \
+ sizeof (T) * vec2_->num); \
+ \
+ return new_vec_; \
+ } \
+ else \
+ return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
+} \
+ \
+static inline void VEC_OP (T,free) \
+ (VEC(T) **vec_) \
+{ \
+ if (*vec_) \
+ vec_free_ (*vec_); \
+ *vec_ = NULL; \
+} \
+ \
+static inline void VEC_OP (T,cleanup) \
+ (void *arg_) \
+{ \
+ VEC(T) **vec_ = (VEC(T) **) arg_; \
+ if (*vec_) \
+ vec_free_ (*vec_); \
+ *vec_ = NULL; \
+} \
+ \
+static inline int VEC_OP (T,reserve) \
+ (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
+{ \
+ VEC(T) dummy; \
+ int extend = !VEC_OP (T,space) \
+ (*vec_, alloc_ < 0 ? -alloc_ : alloc_ VEC_ASSERT_PASS); \
+ \
+ if (extend) \
+ *vec_ = (VEC(T) *) vec_o_reserve (*vec_, alloc_, \
+ vec_offset (T, &dummy), sizeof (T)); \
+ \
+ return extend; \
+} \
+ \
+static inline void VEC_OP (T,safe_grow) \
+ (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
+ "safe_grow"); \
+ VEC_OP (T,reserve) (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ \
+ VEC_ASSERT_PASS); \
+ (*vec_)->num = size_; \
+} \
+ \
+static inline T *VEC_OP (T,safe_push) \
+ (VEC(T) **vec_, const T obj_ VEC_ASSERT_DECL) \
+{ \
+ VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
+ \
+ return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
+} \
+ \
+static inline T *VEC_OP (T,safe_insert) \
+ (VEC(T) **vec_, unsigned ix_, const T obj_ VEC_ASSERT_DECL) \
+{ \
+ VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
+ \
+ return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
+}
+
+#define DEF_VEC_FUNC_P(T) \
+static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_) \
+{ \
+ return vec_ ? vec_->num : 0; \
+} \
+ \
+static inline T VEC_OP (T,last) \
+ (const VEC(T) *vec_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (vec_ && vec_->num, "last"); \
+ \
+ return vec_->vec[vec_->num - 1]; \
+} \
+ \
+static inline T VEC_OP (T,index) \
+ (const VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (vec_ && ix_ < vec_->num, "index"); \
+ \
+ return vec_->vec[ix_]; \
+} \
+ \
+static inline int VEC_OP (T,iterate) \
+ (const VEC(T) *vec_, unsigned ix_, T *ptr) \
+{ \
+ if (vec_ && ix_ < vec_->num) \
+ { \
+ *ptr = vec_->vec[ix_]; \
+ return 1; \
+ } \
+ else \
+ { \
+ *ptr = (T) 0; \
+ return 0; \
+ } \
+} \
+ \
+static inline size_t VEC_OP (T,embedded_size) \
+ (int alloc_) \
+{ \
+ VEC(T) dummy; \
+ \
+ return vec_offset (T, &dummy) + alloc_ * sizeof(T); \
+} \
+ \
+static inline void VEC_OP (T,embedded_init) \
+ (VEC(T) *vec_, int alloc_) \
+{ \
+ vec_->num = 0; \
+ vec_->alloc = alloc_; \
+} \
+ \
+static inline int VEC_OP (T,space) \
+ (VEC(T) *vec_, int alloc_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (alloc_ >= 0, "space"); \
+ return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_; \
+} \
+ \
+static inline T *VEC_OP (T,quick_push) \
+ (VEC(T) *vec_, T obj_ VEC_ASSERT_DECL) \
+{ \
+ T *slot_; \
+ \
+ vec_assert (vec_->num < vec_->alloc, "quick_push"); \
+ slot_ = &vec_->vec[vec_->num++]; \
+ *slot_ = obj_; \
+ \
+ return slot_; \
+} \
+ \
+static inline T VEC_OP (T,pop) (VEC(T) *vec_ VEC_ASSERT_DECL) \
+{ \
+ T obj_; \
+ \
+ vec_assert (vec_->num, "pop"); \
+ obj_ = vec_->vec[--vec_->num]; \
+ \
+ return obj_; \
+} \
+ \
+static inline void VEC_OP (T,truncate) \
+ (VEC(T) *vec_, unsigned size_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (vec_ ? vec_->num >= size_ : !size_, "truncate"); \
+ if (vec_) \
+ vec_->num = size_; \
+} \
+ \
+static inline T VEC_OP (T,replace) \
+ (VEC(T) *vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
+{ \
+ T old_obj_; \
+ \
+ vec_assert (ix_ < vec_->num, "replace"); \
+ old_obj_ = vec_->vec[ix_]; \
+ vec_->vec[ix_] = obj_; \
+ \
+ return old_obj_; \
+} \
+ \
+static inline T *VEC_OP (T,quick_insert) \
+ (VEC(T) *vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
+{ \
+ T *slot_; \
+ \
+ vec_assert (vec_->num < vec_->alloc && ix_ <= vec_->num, "quick_insert"); \
+ slot_ = &vec_->vec[ix_]; \
+ memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T)); \
+ *slot_ = obj_; \
+ \
+ return slot_; \
+} \
+ \
+static inline T VEC_OP (T,ordered_remove) \
+ (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
+{ \
+ T *slot_; \
+ T obj_; \
+ \
+ vec_assert (ix_ < vec_->num, "ordered_remove"); \
+ slot_ = &vec_->vec[ix_]; \
+ obj_ = *slot_; \
+ memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T)); \
+ \
+ return obj_; \
+} \
+ \
+static inline T VEC_OP (T,unordered_remove) \
+ (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
+{ \
+ T *slot_; \
+ T obj_; \
+ \
+ vec_assert (ix_ < vec_->num, "unordered_remove"); \
+ slot_ = &vec_->vec[ix_]; \
+ obj_ = *slot_; \
+ *slot_ = vec_->vec[--vec_->num]; \
+ \
+ return obj_; \
+} \
+ \
+static inline void VEC_OP (T,block_remove) \
+ (VEC(T) *vec_, unsigned ix_, unsigned len_ VEC_ASSERT_DECL) \
+{ \
+ T *slot_; \
+ \
+ vec_assert (ix_ + len_ <= vec_->num, "block_remove"); \
+ slot_ = &vec_->vec[ix_]; \
+ vec_->num -= len_; \
+ memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T)); \
+} \
+ \
+static inline T *VEC_OP (T,address) \
+ (VEC(T) *vec_) \
+{ \
+ return vec_ ? vec_->vec : 0; \
+} \
+ \
+static inline unsigned VEC_OP (T,lower_bound) \
+ (VEC(T) *vec_, const T obj_, \
+ int (*lessthan_)(const T, const T) VEC_ASSERT_DECL) \
+{ \
+ unsigned int len_ = VEC_OP (T, length) (vec_); \
+ unsigned int half_, middle_; \
+ unsigned int first_ = 0; \
+ while (len_ > 0) \
+ { \
+ T middle_elem_; \
+ half_ = len_ >> 1; \
+ middle_ = first_; \
+ middle_ += half_; \
+ middle_elem_ = VEC_OP (T,index) (vec_, middle_ VEC_ASSERT_PASS); \
+ if (lessthan_ (middle_elem_, obj_)) \
+ { \
+ first_ = middle_; \
+ ++first_; \
+ len_ = len_ - half_ - 1; \
+ } \
+ else \
+ len_ = half_; \
+ } \
+ return first_; \
+}
+
+#define DEF_VEC_ALLOC_FUNC_P(T) \
+static inline VEC(T) *VEC_OP (T,alloc) \
+ (int alloc_) \
+{ \
+ /* We must request exact size allocation, hence the negation. */ \
+ return (VEC(T) *) vec_p_reserve (NULL, -alloc_); \
+} \
+ \
+static inline void VEC_OP (T,free) \
+ (VEC(T) **vec_) \
+{ \
+ if (*vec_) \
+ vec_free_ (*vec_); \
+ *vec_ = NULL; \
+} \
+ \
+static inline void VEC_OP (T,cleanup) \
+ (void *arg_) \
+{ \
+ VEC(T) **vec_ = (VEC(T) **) arg_; \
+ if (*vec_) \
+ vec_free_ (*vec_); \
+ *vec_ = NULL; \
+} \
+ \
+static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
+{ \
+ size_t len_ = vec_ ? vec_->num : 0; \
+ VEC (T) *new_vec_ = NULL; \
+ \
+ if (len_) \
+ { \
+ /* We must request exact size allocation, hence the negation. */ \
+ new_vec_ = (VEC (T) *)(vec_p_reserve (NULL, -len_)); \
+ \
+ new_vec_->num = len_; \
+ memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
+ } \
+ return new_vec_; \
+} \
+ \
+static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
+{ \
+ if (vec1_ && vec2_) \
+ { \
+ size_t len_ = vec1_->num + vec2_->num; \
+ VEC (T) *new_vec_ = NULL; \
+ \
+ /* We must request exact size allocation, hence the negation. */ \
+ new_vec_ = (VEC (T) *)(vec_p_reserve (NULL, -len_)); \
+ \
+ new_vec_->num = len_; \
+ memcpy (new_vec_->vec, vec1_->vec, sizeof (T) * vec1_->num); \
+ memcpy (new_vec_->vec + vec1_->num, vec2_->vec, \
+ sizeof (T) * vec2_->num); \
+ \
+ return new_vec_; \
+ } \
+ else \
+ return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
+} \
+ \
+static inline int VEC_OP (T,reserve) \
+ (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
+{ \
+ int extend = !VEC_OP (T,space) \
+ (*vec_, alloc_ < 0 ? -alloc_ : alloc_ VEC_ASSERT_PASS); \
+ \
+ if (extend) \
+ *vec_ = (VEC(T) *) vec_p_reserve (*vec_, alloc_); \
+ \
+ return extend; \
+} \
+ \
+static inline void VEC_OP (T,safe_grow) \
+ (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
+ "safe_grow"); \
+ VEC_OP (T,reserve) \
+ (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ VEC_ASSERT_PASS); \
+ (*vec_)->num = size_; \
+} \
+ \
+static inline T *VEC_OP (T,safe_push) \
+ (VEC(T) **vec_, T obj_ VEC_ASSERT_DECL) \
+{ \
+ VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
+ \
+ return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
+} \
+ \
+static inline T *VEC_OP (T,safe_insert) \
+ (VEC(T) **vec_, unsigned ix_, T obj_ VEC_ASSERT_DECL) \
+{ \
+ VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
+ \
+ return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
+}
+
+#define DEF_VEC_FUNC_O(T) \
+static inline unsigned VEC_OP (T,length) (const VEC(T) *vec_) \
+{ \
+ return vec_ ? vec_->num : 0; \
+} \
+ \
+static inline T *VEC_OP (T,last) (VEC(T) *vec_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (vec_ && vec_->num, "last"); \
+ \
+ return &vec_->vec[vec_->num - 1]; \
+} \
+ \
+static inline T *VEC_OP (T,index) \
+ (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (vec_ && ix_ < vec_->num, "index"); \
+ \
+ return &vec_->vec[ix_]; \
+} \
+ \
+static inline int VEC_OP (T,iterate) \
+ (VEC(T) *vec_, unsigned ix_, T **ptr) \
+{ \
+ if (vec_ && ix_ < vec_->num) \
+ { \
+ *ptr = &vec_->vec[ix_]; \
+ return 1; \
+ } \
+ else \
+ { \
+ *ptr = 0; \
+ return 0; \
+ } \
+} \
+ \
+static inline size_t VEC_OP (T,embedded_size) \
+ (int alloc_) \
+{ \
+ VEC(T) dummy; \
+ \
+ return vec_offset (T, &dummy) + alloc_ * sizeof(T); \
+} \
+ \
+static inline void VEC_OP (T,embedded_init) \
+ (VEC(T) *vec_, int alloc_) \
+{ \
+ vec_->num = 0; \
+ vec_->alloc = alloc_; \
+} \
+ \
+static inline int VEC_OP (T,space) \
+ (VEC(T) *vec_, int alloc_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (alloc_ >= 0, "space"); \
+ return vec_ ? vec_->alloc - vec_->num >= (unsigned)alloc_ : !alloc_; \
+} \
+ \
+static inline T *VEC_OP (T,quick_push) \
+ (VEC(T) *vec_, const T *obj_ VEC_ASSERT_DECL) \
+{ \
+ T *slot_; \
+ \
+ vec_assert (vec_->num < vec_->alloc, "quick_push"); \
+ slot_ = &vec_->vec[vec_->num++]; \
+ if (obj_) \
+ *slot_ = *obj_; \
+ \
+ return slot_; \
+} \
+ \
+static inline void VEC_OP (T,pop) (VEC(T) *vec_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (vec_->num, "pop"); \
+ --vec_->num; \
+} \
+ \
+static inline void VEC_OP (T,truncate) \
+ (VEC(T) *vec_, unsigned size_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (vec_ ? vec_->num >= size_ : !size_, "truncate"); \
+ if (vec_) \
+ vec_->num = size_; \
+} \
+ \
+static inline T *VEC_OP (T,replace) \
+ (VEC(T) *vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
+{ \
+ T *slot_; \
+ \
+ vec_assert (ix_ < vec_->num, "replace"); \
+ slot_ = &vec_->vec[ix_]; \
+ if (obj_) \
+ *slot_ = *obj_; \
+ \
+ return slot_; \
+} \
+ \
+static inline T *VEC_OP (T,quick_insert) \
+ (VEC(T) *vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
+{ \
+ T *slot_; \
+ \
+ vec_assert (vec_->num < vec_->alloc && ix_ <= vec_->num, "quick_insert"); \
+ slot_ = &vec_->vec[ix_]; \
+ memmove (slot_ + 1, slot_, (vec_->num++ - ix_) * sizeof (T)); \
+ if (obj_) \
+ *slot_ = *obj_; \
+ \
+ return slot_; \
+} \
+ \
+static inline void VEC_OP (T,ordered_remove) \
+ (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
+{ \
+ T *slot_; \
+ \
+ vec_assert (ix_ < vec_->num, "ordered_remove"); \
+ slot_ = &vec_->vec[ix_]; \
+ memmove (slot_, slot_ + 1, (--vec_->num - ix_) * sizeof (T)); \
+} \
+ \
+static inline void VEC_OP (T,unordered_remove) \
+ (VEC(T) *vec_, unsigned ix_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (ix_ < vec_->num, "unordered_remove"); \
+ vec_->vec[ix_] = vec_->vec[--vec_->num]; \
+} \
+ \
+static inline void VEC_OP (T,block_remove) \
+ (VEC(T) *vec_, unsigned ix_, unsigned len_ VEC_ASSERT_DECL) \
+{ \
+ T *slot_; \
+ \
+ vec_assert (ix_ + len_ <= vec_->num, "block_remove"); \
+ slot_ = &vec_->vec[ix_]; \
+ vec_->num -= len_; \
+ memmove (slot_, slot_ + len_, (vec_->num - ix_) * sizeof (T)); \
+} \
+ \
+static inline T *VEC_OP (T,address) \
+ (VEC(T) *vec_) \
+{ \
+ return vec_ ? vec_->vec : 0; \
+} \
+ \
+static inline unsigned VEC_OP (T,lower_bound) \
+ (VEC(T) *vec_, const T *obj_, \
+ int (*lessthan_)(const T *, const T *) VEC_ASSERT_DECL) \
+{ \
+ unsigned int len_ = VEC_OP (T, length) (vec_); \
+ unsigned int half_, middle_; \
+ unsigned int first_ = 0; \
+ while (len_ > 0) \
+ { \
+ T *middle_elem_; \
+ half_ = len_ >> 1; \
+ middle_ = first_; \
+ middle_ += half_; \
+ middle_elem_ = VEC_OP (T,index) (vec_, middle_ VEC_ASSERT_PASS); \
+ if (lessthan_ (middle_elem_, obj_)) \
+ { \
+ first_ = middle_; \
+ ++first_; \
+ len_ = len_ - half_ - 1; \
+ } \
+ else \
+ len_ = half_; \
+ } \
+ return first_; \
+}
+
+#define DEF_VEC_ALLOC_FUNC_O(T) \
+static inline VEC(T) *VEC_OP (T,alloc) \
+ (int alloc_) \
+{ \
+ VEC(T) dummy; \
+ \
+ /* We must request exact size allocation, hence the negation. */ \
+ return (VEC(T) *) vec_o_reserve (NULL, -alloc_, \
+ vec_offset (T, &dummy), sizeof (T)); \
+} \
+ \
+static inline VEC(T) *VEC_OP (T,copy) (VEC(T) *vec_) \
+{ \
+ size_t len_ = vec_ ? vec_->num : 0; \
+ VEC (T) *new_vec_ = NULL; \
+ \
+ if (len_) \
+ { \
+ VEC(T) dummy; \
+ \
+ /* We must request exact size allocation, hence the negation. */ \
+ new_vec_ = (VEC (T) *) \
+ vec_o_reserve (NULL, -len_, vec_offset (T, &dummy), sizeof (T)); \
+ \
+ new_vec_->num = len_; \
+ memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); \
+ } \
+ return new_vec_; \
+} \
+ \
+static inline VEC(T) *VEC_OP (T,merge) (VEC(T) *vec1_, VEC(T) *vec2_) \
+{ \
+ if (vec1_ && vec2_) \
+ { \
+ VEC(T) dummy; \
+ size_t len_ = vec1_->num + vec2_->num; \
+ VEC (T) *new_vec_ = NULL; \
+ \
+ /* We must request exact size allocation, hence the negation. */ \
+ new_vec_ = (VEC (T) *) \
+ vec_o_reserve (NULL, -len_, vec_offset (T, &dummy), sizeof (T)); \
+ \
+ new_vec_->num = len_; \
+ memcpy (new_vec_->vec, vec1_->vec, sizeof (T) * vec1_->num); \
+ memcpy (new_vec_->vec + vec1_->num, vec2_->vec, \
+ sizeof (T) * vec2_->num); \
+ \
+ return new_vec_; \
+ } \
+ else \
+ return VEC_copy (T, vec1_ ? vec1_ : vec2_); \
+} \
+ \
+static inline void VEC_OP (T,free) \
+ (VEC(T) **vec_) \
+{ \
+ if (*vec_) \
+ vec_free_ (*vec_); \
+ *vec_ = NULL; \
+} \
+ \
+static inline void VEC_OP (T,cleanup) \
+ (void *arg_) \
+{ \
+ VEC(T) **vec_ = (VEC(T) **) arg_; \
+ if (*vec_) \
+ vec_free_ (*vec_); \
+ *vec_ = NULL; \
+} \
+ \
+static inline int VEC_OP (T,reserve) \
+ (VEC(T) **vec_, int alloc_ VEC_ASSERT_DECL) \
+{ \
+ VEC(T) dummy; \
+ int extend = !VEC_OP (T,space) (*vec_, alloc_ < 0 ? -alloc_ : alloc_ \
+ VEC_ASSERT_PASS); \
+ \
+ if (extend) \
+ *vec_ = (VEC(T) *) \
+ vec_o_reserve (*vec_, alloc_, vec_offset (T, &dummy), sizeof (T)); \
+ \
+ return extend; \
+} \
+ \
+static inline void VEC_OP (T,safe_grow) \
+ (VEC(T) **vec_, int size_ VEC_ASSERT_DECL) \
+{ \
+ vec_assert (size_ >= 0 && VEC_OP(T,length) (*vec_) <= (unsigned)size_, \
+ "safe_grow"); \
+ VEC_OP (T,reserve) \
+ (vec_, (int)(*vec_ ? (*vec_)->num : 0) - size_ VEC_ASSERT_PASS); \
+ (*vec_)->num = size_; \
+} \
+ \
+static inline T *VEC_OP (T,safe_push) \
+ (VEC(T) **vec_, const T *obj_ VEC_ASSERT_DECL) \
+{ \
+ VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
+ \
+ return VEC_OP (T,quick_push) (*vec_, obj_ VEC_ASSERT_PASS); \
+} \
+ \
+static inline T *VEC_OP (T,safe_insert) \
+ (VEC(T) **vec_, unsigned ix_, const T *obj_ VEC_ASSERT_DECL) \
+{ \
+ VEC_OP (T,reserve) (vec_, 1 VEC_ASSERT_PASS); \
+ \
+ return VEC_OP (T,quick_insert) (*vec_, ix_, obj_ VEC_ASSERT_PASS); \
+}
+
+#endif /* COMMON_VEC_H */
diff --git a/gdb/gdbsupport/version.h b/gdb/gdbsupport/version.h
new file mode 100644
index 00000000000..9e840e72b4d
--- /dev/null
+++ b/gdb/gdbsupport/version.h
@@ -0,0 +1,31 @@
+/* Version information for GDB.
+ Copyright (C) 1999-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_VERSION_H
+#define COMMON_VERSION_H
+
+/* Version number of GDB, as a string. */
+extern const char version[];
+
+/* Canonical host name as a string. */
+extern const char host_name[];
+
+/* Canonical target name as a string. */
+extern const char target_name[];
+
+#endif /* COMMON_VERSION_H */
diff --git a/gdb/gdbsupport/x86-xstate.h b/gdb/gdbsupport/x86-xstate.h
new file mode 100644
index 00000000000..4ce8f61e394
--- /dev/null
+++ b/gdb/gdbsupport/x86-xstate.h
@@ -0,0 +1,88 @@
+/* Common code for x86 XSAVE extended state.
+
+ Copyright (C) 2010-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_X86_XSTATE_H
+#define COMMON_X86_XSTATE_H
+
+/* The extended state feature bits. */
+#define X86_XSTATE_X87 (1ULL << 0)
+#define X86_XSTATE_SSE (1ULL << 1)
+#define X86_XSTATE_AVX (1ULL << 2)
+#define X86_XSTATE_BNDREGS (1ULL << 3)
+#define X86_XSTATE_BNDCFG (1ULL << 4)
+#define X86_XSTATE_MPX (X86_XSTATE_BNDREGS | X86_XSTATE_BNDCFG)
+
+/* AVX 512 adds three feature bits. All three must be enabled. */
+#define X86_XSTATE_K (1ULL << 5)
+#define X86_XSTATE_ZMM_H (1ULL << 6)
+#define X86_XSTATE_ZMM (1ULL << 7)
+#define X86_XSTATE_AVX512 (X86_XSTATE_K | X86_XSTATE_ZMM_H \
+ | X86_XSTATE_ZMM)
+
+#define X86_XSTATE_PKRU (1ULL << 9)
+
+/* Supported mask and size of the extended state. */
+#define X86_XSTATE_X87_MASK X86_XSTATE_X87
+#define X86_XSTATE_SSE_MASK (X86_XSTATE_X87 | X86_XSTATE_SSE)
+#define X86_XSTATE_AVX_MASK (X86_XSTATE_SSE_MASK | X86_XSTATE_AVX)
+#define X86_XSTATE_MPX_MASK (X86_XSTATE_SSE_MASK | X86_XSTATE_MPX)
+#define X86_XSTATE_AVX_MPX_MASK (X86_XSTATE_AVX_MASK | X86_XSTATE_MPX)
+#define X86_XSTATE_AVX_AVX512_MASK (X86_XSTATE_AVX_MASK | X86_XSTATE_AVX512)
+#define X86_XSTATE_AVX_MPX_AVX512_PKU_MASK (X86_XSTATE_AVX_MPX_MASK\
+ | X86_XSTATE_AVX512 | X86_XSTATE_PKRU)
+
+#define X86_XSTATE_ALL_MASK (X86_XSTATE_AVX_MPX_AVX512_PKU_MASK)
+
+
+#define X86_XSTATE_SSE_SIZE 576
+#define X86_XSTATE_AVX_SIZE 832
+#define X86_XSTATE_BNDREGS_SIZE 1024
+#define X86_XSTATE_BNDCFG_SIZE 1088
+#define X86_XSTATE_AVX512_SIZE 2688
+#define X86_XSTATE_PKRU_SIZE 2696
+#define X86_XSTATE_MAX_SIZE 2696
+
+
+/* In case one of the MPX XCR0 bits is set we consider we have MPX. */
+#define HAS_MPX(XCR0) (((XCR0) & X86_XSTATE_MPX) != 0)
+#define HAS_AVX(XCR0) (((XCR0) & X86_XSTATE_AVX) != 0)
+#define HAS_AVX512(XCR0) (((XCR0) & X86_XSTATE_AVX512) != 0)
+#define HAS_PKRU(XCR0) (((XCR0) & X86_XSTATE_PKRU) != 0)
+
+/* Get I386 XSAVE extended state size. */
+#define X86_XSTATE_SIZE(XCR0) \
+ (HAS_PKRU (XCR0) ? X86_XSTATE_PKRU_SIZE : \
+ (HAS_AVX512 (XCR0) ? X86_XSTATE_AVX512_SIZE : \
+ (HAS_MPX (XCR0) ? X86_XSTATE_BNDCFG_SIZE : \
+ (HAS_AVX (XCR0) ? X86_XSTATE_AVX_SIZE : X86_XSTATE_SSE_SIZE))))
+
+/* Initial value for fctrl register, as defined in the X86 manual, and
+ confirmed in the (Linux) kernel source. When the x87 floating point
+ feature is not enabled in an inferior we use this as the value of the
+ fcrtl register. */
+
+#define I387_FCTRL_INIT_VAL 0x037f
+
+/* Initial value for mxcsr register. When the avx and sse floating point
+ features are not enabled in an inferior we use this as the value of the
+ mxcsr register. */
+
+#define I387_MXCSR_INIT_VAL 0x1f80
+
+#endif /* COMMON_X86_XSTATE_H */
diff --git a/gdb/gdbsupport/xml-utils.c b/gdb/gdbsupport/xml-utils.c
new file mode 100644
index 00000000000..79f040e2b0f
--- /dev/null
+++ b/gdb/gdbsupport/xml-utils.c
@@ -0,0 +1,63 @@
+/* Shared helper routines for manipulating XML.
+
+ Copyright (C) 2006-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "common-defs.h"
+#include "xml-utils.h"
+
+/* See xml-utils.h. */
+
+std::string
+xml_escape_text (const char *text)
+{
+ std::string result;
+
+ xml_escape_text_append (&result, text);
+
+ return result;
+}
+
+/* See xml-utils.h. */
+
+void
+xml_escape_text_append (std::string *result, const char *text)
+{
+ /* Expand the result. */
+ for (int i = 0; text[i] != '\0'; i++)
+ switch (text[i])
+ {
+ case '\'':
+ *result += "&apos;";
+ break;
+ case '\"':
+ *result += "&quot;";
+ break;
+ case '&':
+ *result += "&amp;";
+ break;
+ case '<':
+ *result += "&lt;";
+ break;
+ case '>':
+ *result += "&gt;";
+ break;
+ default:
+ *result += text[i];
+ break;
+ }
+}
diff --git a/gdb/gdbsupport/xml-utils.h b/gdb/gdbsupport/xml-utils.h
new file mode 100644
index 00000000000..747e8c8a481
--- /dev/null
+++ b/gdb/gdbsupport/xml-utils.h
@@ -0,0 +1,33 @@
+/* Shared helper routines for manipulating XML.
+
+ Copyright (C) 2006-2019 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_XML_UTILS_H
+#define COMMON_XML_UTILS_H
+
+/* Return a string with special characters from TEXT replaced by entity
+ references. */
+
+extern std::string xml_escape_text (const char *text);
+
+/* Append TEXT to RESULT, with special characters replaced by entity
+ references. */
+
+extern void xml_escape_text_append (std::string *result, const char *text);
+
+#endif /* COMMON_XML_UTILS_H */