diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index fdc2a40..5bb0821 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,42 @@
+2017-05-18  Djordje Todorovic  <djordje.todorovic@rt-rk.com>
+
+	* Makefile.in(INTERNAL_CCFLAGS): Add CFLAGS for glibc-dep/.
+	(CCOMPILE): Force glibc-dep/ to be compiled with gcc.
+	* gdb/config/glibc.mh(GLIBCFILES): Define object files that
+	will be generated in order to read TLS with GDB Multiarch.
+	[DCROSS_GDB]: Define if it's GDB Multiarch.
+	* gdb/configure.ac(cross_makefile_frag): Add GLIBCFILES in
+	order to generate Makefile for cross platforms to read TLS.
+	* gdb/configure: Regenerate.
+	* gdb/gdb_proc_service.h: Add necessary code in order to
+	compile glibc-dep/ with GCC.
+	* gdb/gdbarch.c: Likewise.
+	* gdb/glibc-dep/README.txt: Brief explanation of glibc-dep/.
+	* gdb/glibc-dep/gdb_td_ta_new.c(init_target_dep_constants): New
+	function.
+	(gdb_td_ta_new): Get current version of GLIBC from coredump file.
+	* gdb/glibc-dep/native-check.c(get_host_mach): New function.
+	(native_check): Check if it is native architecture when using
+	GDB Multiarch.
+	* gdb/glibc-dep/db-symbols.h: Take necessary code from GLIBC
+	in order to annul differences between GLIBC versions for reading
+	TLS.
+	* gdb/glibc-dep/nptl_db/fetch-value.c: Likewise.
+	* gdb/glibc-dep/nptl_db/structs.def: Likewise.
+	* gdb/glibc-dep/nptl_db/td_symbol_list.c: Likewise.
+	* gdb/glibc-dep/nptl_db/td_ta_map_lwp2thr.c: Likewise.
+	* gdb/glibc-dep/nptl_db/td_thr_tls_get_addr.c: Likewise.
+	* gdb/glibc-dep/nptl_db/td_thr_tlsbase.c: Likewise. Modify in
+	order to work with different versions of GLIBC.
+	* gdb/glibc-dep/nptl_db/thread_dbP.h: Likewise.
+	* gdb/glibc-dep/nptl_db/tls.h: Likewise.
+	* gdb/gregset.h: Remove deprecated gregset_t but use
+	elf_gregset_t.
+	* gdb/linux-thread-db.c: (try_thread_db_load_1): Set up TLS
+	functions from glibc-dep/.
+	* gdb/nat/gdb_thread_db.h: (gdb_td_ta_new, gdb_td_thr_tlsbase)
+	(gdb_td_thr_tls_get_addr, native_check): Declare TLS functions.
+
  2017-05-17  Yao Qi  <yao.qi@linaro.org>

  	* cli/cli-decode.c (add_alias_cmd): New function.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 452f146..fb46538 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -117,6 +117,9 @@ depcomp = $(SHELL) $(srcdir)/../depcomp
  COMPILE.pre = $(CXX) $(CXX_DIALECT)
  COMPILE.post = -c -o $@
  COMPILE = $(COMPILE.pre) $(INTERNAL_CFLAGS) $(COMPILE.post)
+INTERNAL_CCFLAGS_TMP = $(filter-out -Wpointer-arith, $(INTERNAL_CFLAGS))
+INTERNAL_CCFLAGS = $(filter-out -Werror, $(INTERNAL_CCFLAGS_TMP))
+CCOMPILE = $(CC) $(INTERNAL_CCFLAGS) $(COMPILE.post)
  POSTCOMPILE = @true

  # Directory containing source files.
@@ -920,6 +923,10 @@ HAVE_NATIVE_GCORE_HOST = @HAVE_NATIVE_GCORE_HOST@

  # End of native-target dependent variables.

+# Cross fragment
+@cross_makefile_frag@
+# End of cross fragment
+
  FLAGS_TO_PASS = \
  	"prefix=$(prefix)" \
  	"exec_prefix=$(exec_prefix)" \
@@ -1616,7 +1623,7 @@ INFOFILES = gdb.info*
  # Makefile.in

  DEPFILES = $(TARGET_OBS) $(SER_HARDWIRE) $(NATDEPFILES) \
-	   $(REMOTE_OBS) $(SIM_OBS)
+	   $(REMOTE_OBS) $(SIM_OBS) $(GLIBCFILES)

  SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES) $(CONFIG_SRCS)
  # Don't include YYFILES (*.c) because we already include *.y in SFILES,
@@ -1945,6 +1952,14 @@ all: gdb$(EXEEXT) $(CONFIG_ALL)
  	$(COMPILE) $<
  	$(POSTCOMPILE)

+%.o: $(srcdir)/glibc-dep/%.c
+	$(CCOMPILE) $<
+	$(POSTCOMPILE)
+
+%.o: ${srcdir}/glibc-dep/nptl_db/%.c
+	$(CCOMPILE) $<
+	$(POSTCOMPILE)
+
  # Specify an explicit rule for gdb/common/agent.c, to avoid a clash with the
  # object file generate by gdb/agent.c.
  common-agent.o: $(srcdir)/common/agent.c
diff --git a/gdb/config/glibc.mh b/gdb/config/glibc.mh
new file mode 100644
index 0000000..0687442
--- /dev/null
+++ b/gdb/config/glibc.mh
@@ -0,0 +1,6 @@
+# GLIBC fragment comes in here
+GLIBCFILES = td_symbol_list.o \
+	fetch-value.o gdb_td_ta_new.o \
+	td_thr_tlsbase.o td_thr_tls_get_addr.o \
+	td_ta_map_lwp2thr.o native_check.o
+INTERNAL_CFLAGS += -DCROSS_GDB
diff --git a/gdb/configure b/gdb/configure
index 8df81ac..5766a24 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -806,7 +806,8 @@ PACKAGE_TARNAME
  PACKAGE_NAME
  PATH_SEPARATOR
  SHELL'
-ac_subst_files='nat_makefile_frag'
+ac_subst_files='nat_makefile_frag
+cross_makefile_frag'
  ac_user_opts='
  enable_option_checking
  enable_maintainer_mode
@@ -16738,6 +16739,13 @@ if test "${gdb_native}" = "yes"; then
    nativefile=$NAT_FILE
  fi

+if test "${gdb_native}" = "no" || test "${enable_targets}" != ""; then
+  cross_makefile_frag=${srcdir}/config/glibc.mh
+else
+  cross_makefile_frag=/dev/null
+fi
+
+



diff --git a/gdb/configure.ac b/gdb/configure.ac
index fd11cf0..b732223 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -2206,6 +2206,12 @@ if test "${gdb_native}" = "yes"; then
    nativefile=$NAT_FILE
  fi

+if test "${gdb_native}" = "no" || test "${enable_targets}" != ""; then
+  cross_makefile_frag=${srcdir}/config/glibc.mh
+else
+  cross_makefile_frag=/dev/null
+fi
+
  AC_SUBST(NAT_FILE)
  AC_SUBST(NATDEPFILES)
  AC_SUBST(NAT_CDEPS)
@@ -2215,6 +2221,7 @@ AC_SUBST(XM_CLIBS)
  AC_SUBST(NAT_GENERATED_FILES)
  AC_SUBST(HAVE_NATIVE_GCORE_HOST)
  AC_SUBST_FILE(nat_makefile_frag)
+AC_SUBST_FILE(cross_makefile_frag)

  if test x"${gdb_osabi}" != x ; then
      AC_DEFINE_UNQUOTED(GDB_OSABI_DEFAULT, $gdb_osabi,
diff --git a/gdb/gdb_proc_service.h b/gdb/gdb_proc_service.h
index 734fcb2..5db14f4 100644
--- a/gdb/gdb_proc_service.h
+++ b/gdb/gdb_proc_service.h
@@ -62,7 +62,9 @@ EXTERN_C_POP
  #include <sys/procfs.h>
  #endif

+#ifdef __cplusplus
  EXTERN_C_PUSH
+#endif

  /* Functions in this interface return one of these status codes.  */
  typedef enum
@@ -159,7 +161,9 @@ extern ps_err_e ps_lsetxregs (struct ps_prochandle *ph, lwpid_t lwpid,
  /* Log a message (sends to gdb_stderr).  */
  extern void ps_plog (const char *fmt, ...);

+#ifdef __cplusplus
  EXTERN_C_POP
+#endif

  #endif /* HAVE_PROC_SERVICE_H */

@@ -175,11 +179,20 @@ typedef gdb_fpregset_t gdb_prfpregset_t;
  typedef prfpregset_t gdb_prfpregset_t;
  #endif

+/* The macro is called because gdb_proc_service.h is included from
+   glibc-dep/nptl_db/thread_dbP.h which is used when compiling
+   glibc-dep files with gcc and the structure below has c++ class
+   ptid as field. When this header is included from
+   glibc-dep/nptl_db/thread_dbP.h there is only need for functions
+   definitions and struct ps_prochandle forward declaration.
+*/
+#ifndef _THREAD_DBP_H
  /* GDB specific structure that identifies the target process.  */
  struct ps_prochandle
  {
    /* The LWP we use for memory reads.  */
    ptid_t ptid;
  };
+#endif

  #endif /* gdb_proc_service.h */
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 9c827ac..9732a18 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -1497,7 +1497,7 @@ gdbarch_tdep (struct gdbarch *gdbarch)
  }


-const struct bfd_arch_info *
+EXTERN_C const struct bfd_arch_info *
  gdbarch_bfd_arch_info (struct gdbarch *gdbarch)
  {
    gdb_assert (gdbarch != NULL);
@@ -5465,7 +5465,7 @@ set_target_gdbarch (struct gdbarch *new_gdbarch)

  /* Return the current inferior's arch.  */

-struct gdbarch *
+EXTERN_C struct gdbarch *
  target_gdbarch (void)
  {
    return current_inferior ()->gdbarch;
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 15a8141..d587c02 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -83,7 +83,7 @@ struct ui_out;
     gdbarch.  */

  /* This is a convenience wrapper for 'current_inferior ()->gdbarch'.  */
-extern struct gdbarch *target_gdbarch (void);
+EXTERN_C struct gdbarch *target_gdbarch (void);

  /* Callback type for the 'iterate_over_objfiles_in_search_order'
     gdbarch  method.  */
@@ -103,8 +103,8 @@ typedef void (iterate_over_regset_sections_cb)


  /* The following are pre-initialized by GDBARCH.  */
+EXTERN_C const struct bfd_arch_info * gdbarch_bfd_arch_info (struct gdbarch *gdbarch);

-extern const struct bfd_arch_info * gdbarch_bfd_arch_info (struct gdbarch *gdbarch);
  /* set_gdbarch_bfd_arch_info() - not applicable - pre-initialized.  */

  extern enum bfd_endian gdbarch_byte_order (struct gdbarch *gdbarch);
diff --git a/gdb/glibc-dep/README.txt b/gdb/glibc-dep/README.txt
new file mode 100644
index 0000000..917d0d0
--- /dev/null
+++ b/gdb/glibc-dep/README.txt
@@ -0,0 +1,42 @@
+Files and functions taken from GLIBC source code (${glibc_src}/nptl_db/) necessary for getting
+TLS variables (from coredump file) when cross GDB using GLIBC version 2.22 and higher are stored into
+${gdb_src}/glibc-dep/nptl_db directory.
+
+gdb_td_ta_new() is stored into ${gdb_src}/glibc-dep/ because functionality of function (td_ta_new())
+from GLIBC source has changed in order to get current version of GLIBC from coredump file.
+
+gdb_td_thr_tlsbase is function taken from nptl_db/td_thr_tlsbase.c,
+which has modified in GLIBC 2.22 and higher, so all dependent files had to be included into GDB source.
+
+------------------------
+
+${gdb_src}/glibc-dep/nptl_db
+
+* thread_dbP.h
+Taken needed definitions and macros.
+
+* db-symbols.h
+Unmodified.
+
+* fetch-value.c
+Taken needed functions.
+
+* structs.def
+Unmodified.
+
+* td_symbol_list.c
+Taken necessary definitions and modified td_lookup function.
+
+* td_ta_map_lwp2thr.c
+Taken only __td_ta_lookup_th_unique function unmodified.
+
+* td_thr_tlsbase.c
+gdb_td_thr_tlsbase(), modified in order to work with all GLIBC versions.
+${gdb_src}/gdb/config/${arch}/tls.h depending on architecture got different
+values of TLS_TCB_AT_TP and TLS_DTV_AT_TP macros taken
+from ${glibc_src}/sysdeps/${arch}/nptl/tls.h.
+
+* td_thr_tls_get_addr.c
+Unmodified.
+
+-------------------------
\ No newline at end of file
diff --git a/gdb/glibc-dep/gdb_td_ta_new.c b/gdb/glibc-dep/gdb_td_ta_new.c
new file mode 100644
index 0000000..4c6d3a8
--- /dev/null
+++ b/gdb/glibc-dep/gdb_td_ta_new.c
@@ -0,0 +1,97 @@
+/* Copyright (C) 2000-2017 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 <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <version.h>
+
+#include "nptl_db/thread_dbP.h"
+#include "nat/gdb_thread_db.h"
+#include "nptl_db/tls.h"
+#include "bfd.h"
+
+struct gdbarch;
+extern const struct bfd_arch_info *gdbarch_bfd_arch_info (struct gdbarch *gdbarch);
+extern struct gdbarch *target_gdbarch (void);
+
+static td_err_e
+init_target_dep_constants ()
+{
+  const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (target_gdbarch ());
+  unsigned arch = bfdarch->arch;
+  switch (arch)
+    {
+       case bfd_arch_mips:
+         tls_tcb_at_tp = 0;
+         tls_dtv_at_tp = 1;
+         forced_dynamic_tls_offset = -2;
+         no_tls_offset = -1;
+         tcb_alignment = 16;
+         break;
+       case bfd_arch_arm:
+         tls_tcb_at_tp = 0;
+         tls_dtv_at_tp = 1;
+         forced_dynamic_tls_offset = -2;
+         no_tls_offset = -1;
+         /* Set to zero because not in use for TLS_PRE_TCB_SIZE. */
+         tcb_alignment = 0;
+         break;
+       case bfd_arch_i386:
+         tls_tcb_at_tp = 1;
+         tls_dtv_at_tp = 0;
+         forced_dynamic_tls_offset = -1;
+         no_tls_offset = 0;
+         /* Set to zero because not in use for TLS_PRE_TCB_SIZE. */
+         tcb_alignment = 0;
+         break;
+       case bfd_arch_powerpc:
+         tls_tcb_at_tp = 0;
+         tls_dtv_at_tp = 1;
+         forced_dynamic_tls_offset = -2;
+         no_tls_offset = -1;
+         tcb_alignment = 48;
+         break;
+       case bfd_arch_aarch64:
+         tls_tcb_at_tp = 0;
+         tls_dtv_at_tp = 1;
+         forced_dynamic_tls_offset = -1;
+         no_tls_offset = 0;
+         /* Set to zero because not in use for TLS_PRE_TCB_SIZE. */
+         tcb_alignment = 0;
+         break;
+       default:
+         return TD_ERR;
+    }
+  return TD_OK;
+}
+
+
+td_err_e
+gdb_td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
+{
+  psaddr_t versaddr;
+
+  /* Check whether the versions match. */
+  if (td_lookup (ps, SYM_nptl_version, &versaddr) != PS_OK)
+    return TD_NOLIBTHREAD;
+  if (ps_pdread (ps, versaddr, versbuf, sizeof (versbuf)) != PS_OK)
+    return TD_ERR;
+  if (init_target_dep_constants () != TD_OK)
+    return TD_ERR;
+  return TD_OK;
+}
diff --git a/gdb/glibc-dep/native_check.c b/gdb/glibc-dep/native_check.c
new file mode 100644
index 0000000..732db10
--- /dev/null
+++ b/gdb/glibc-dep/native_check.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 2000-2017 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 "native_check.h"
+#include <string.h>
+#include <stdio.h>
+#include "../config.h"
+#include "bfd.h"
+#include <sys/utsname.h>
+
+unsigned get_host_mach (char *name_of_arch)
+{
+  unsigned result;
+
+  if (strstr (name_of_arch, "x86_64") != NULL)
+    result = bfd_arch_i386;
+  else if (strstr (name_of_arch, "i386") != NULL)
+    result = bfd_arch_i386;
+  else if (strstr (name_of_arch, "mips") != NULL)
+    result = bfd_arch_mips;
+  else if (strstr (name_of_arch, "arm") != NULL)
+    result = bfd_arch_arm;
+  else if (strstr (name_of_arch, "powerpc") != NULL)
+    result = bfd_arch_powerpc;
+  else if (strstr (name_of_arch, "aarch64") != NULL)
+    result = bfd_arch_aarch64;
+  else
+    result = -1;
+
+  return result;
+}
+
+int native_check (unsigned bfd_arch)
+{
+  struct utsname buf;
+  if (uname (&buf) == 0)
+    {
+      unsigned host_mach = get_host_mach (buf.machine);
+
+      if (host_mach == bfd_arch)
+        {
+          /* zero if it's host */
+          return 0;
+        }
+      else
+        {
+          return 1;
+        }
+    }
+  return -1;
+}
\ No newline at end of file
diff --git a/gdb/glibc-dep/native_check.h b/gdb/glibc-dep/native_check.h
new file mode 100644
index 0000000..2ed7554
--- /dev/null
+++ b/gdb/glibc-dep/native_check.h
@@ -0,0 +1,19 @@
+/* Copyright (C) 2000-2017 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/>.  */
+
+unsigned get_host_mach (char *name_of_arch);
+int native_check (unsigned bfd_arch);
\ No newline at end of file
diff --git a/gdb/glibc-dep/nptl_db/db-symbols.h b/gdb/glibc-dep/nptl_db/db-symbols.h
new file mode 100644
index 0000000..37c285a
--- /dev/null
+++ b/gdb/glibc-dep/nptl_db/db-symbols.h
@@ -0,0 +1,51 @@
+/* List of symbols in libpthread examined by libthread_db.
+   Copyright (C) 2009-2016 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/>.  */
+
+#define DOT(x)  x   /* No prefix.  */
+
+#define STRINGIFY(name)   STRINGIFY_1(name)
+#define STRINGIFY_1(name) #name
+
+#define DB_STRUCT(type) \
+  DB_LOOKUP_NAME (SYM_SIZEOF_##type, _thread_db_sizeof_##type)
+#define DB_STRUCT_FIELD(type, field) \
+  DB_LOOKUP_NAME (SYM_##type##_FIELD_##field, _thread_db_##type##_##field)
+#define DB_SYMBOL(name) \
+  DB_LOOKUP_NAME (SYM_##name, name)
+#define DB_FUNCTION(name) \
+  DB_LOOKUP_NAME (SYM_##name, DOT (name))
+#define DB_VARIABLE(name) \
+  DB_LOOKUP_NAME (SYM_##name, name) \
+  DB_LOOKUP_NAME (SYM_DESC_##name, _thread_db_##name)
+
+# include "structs.def"
+
+# undef DB_STRUCT
+# undef DB_FUNCTION
+# undef DB_SYMBOL
+# undef DB_VARIABLE
+# undef DOT
+
+DB_LOOKUP_NAME_TH_UNIQUE (SYM_TH_UNIQUE_REGISTER64, _thread_db_register64)
+DB_LOOKUP_NAME_TH_UNIQUE (SYM_TH_UNIQUE_REGISTER32, _thread_db_register32)
+DB_LOOKUP_NAME_TH_UNIQUE (SYM_TH_UNIQUE_CONST_THREAD_AREA,
+        _thread_db_const_thread_area)
+DB_LOOKUP_NAME_TH_UNIQUE (SYM_TH_UNIQUE_REGISTER32_THREAD_AREA,
+        _thread_db_register32_thread_area)
+DB_LOOKUP_NAME_TH_UNIQUE (SYM_TH_UNIQUE_REGISTER64_THREAD_AREA,
+        _thread_db_register64_thread_area)
diff --git a/gdb/glibc-dep/nptl_db/fetch-value.c b/gdb/glibc-dep/nptl_db/fetch-value.c
new file mode 100644
index 0000000..07ae14d
--- /dev/null
+++ b/gdb/glibc-dep/nptl_db/fetch-value.c
@@ -0,0 +1,191 @@
+/* Helper routines for libthread_db.
+   Copyright (C) 2003-2016 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/>.  */
+
+#include "thread_dbP.h"
+#include <byteswap.h>
+#include <assert.h>
+#include <stdint.h>
+
+
+td_err_e
+_td_check_sizeof (td_thragent_t *ta, uint32_t *sizep, int sizep_name)
+{
+  if (*sizep == 0)
+    {
+      psaddr_t descptr;
+      ps_err_e err = td_lookup (ta->ph, sizep_name, &descptr);
+      if (err == PS_NOSYM)
+	return TD_NOCAPAB;
+      if (err == PS_OK)
+	err = ps_pdread (ta->ph, descptr, sizep, sizeof *sizep);
+      if (err != PS_OK)
+	return TD_ERR;
+      if (*sizep & 0xff000000U)
+	*sizep = bswap_32 (*sizep);
+    }
+  return TD_OK;
+}
+
+td_err_e
+_td_locate_field (td_thragent_t *ta,
+		  db_desc_t desc, int descriptor_name,
+		  psaddr_t idx, psaddr_t *address)
+{
+  uint32_t elemsize;
+
+  if (DB_DESC_SIZE (desc) == 0)
+    {
+      /* Read the information about this field from the inferior.  */
+      psaddr_t descptr;
+      ps_err_e err = td_lookup (ta->ph, descriptor_name, &descptr);
+      if (err == PS_NOSYM)
+	return TD_NOCAPAB;
+      if (err == PS_OK)
+	err = ps_pdread (ta->ph, descptr, desc, DB_SIZEOF_DESC);
+      if (err != PS_OK)
+	return TD_ERR;
+      if (DB_DESC_SIZE (desc) == 0)
+	return TD_DBERR;
+      if (DB_DESC_SIZE (desc) & 0xff000000U)
+	{
+	  /* Byte-swap these words, though we leave the size word
+	     in native order as the handy way to distinguish.  */
+	  DB_DESC_OFFSET (desc) = bswap_32 (DB_DESC_OFFSET (desc));
+	  DB_DESC_NELEM (desc) = bswap_32 (DB_DESC_NELEM (desc));
+	}
+    }
+
+  if (idx != 0 && DB_DESC_NELEM (desc) != 0
+      && idx - (psaddr_t) 0 > DB_DESC_NELEM (desc))
+    /* This is an internal indicator to callers with nonzero IDX
+       that the IDX value is too big.  */
+    return TD_NOAPLIC;
+
+  elemsize = DB_DESC_SIZE (desc);
+  if (elemsize & 0xff000000U)
+    elemsize = bswap_32 (elemsize);
+
+  *address += (int32_t) DB_DESC_OFFSET (desc);
+  *address += (elemsize / 8 * (idx - (psaddr_t) 0));
+  return TD_OK;
+}
+
+td_err_e
+_td_fetch_value (td_thragent_t *ta,
+		 db_desc_t desc, int descriptor_name,
+		 psaddr_t idx, psaddr_t address,
+		 psaddr_t *result)
+{
+  ps_err_e err;
+  td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
+  if (terr != TD_OK)
+    return terr;
+
+  if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
+    {
+      uint8_t value;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 32)
+    {
+      uint32_t value;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 64)
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (32))
+    {
+      uint32_t value;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      value = bswap_32 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (64))
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      value = bswap_64 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else
+    return TD_DBERR;
+
+  return err == PS_OK ? TD_OK : TD_ERR;
+}
+
+td_err_e
+_td_fetch_value_local (td_thragent_t *ta,
+		       db_desc_t desc, int descriptor_name, psaddr_t idx,
+		       void *address,
+		       psaddr_t *result)
+{
+  td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
+  if (terr != TD_OK)
+    return terr;
+
+  if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
+    {
+      uint8_t value;
+      memcpy (&value, address, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 32)
+    {
+      uint32_t value;
+      memcpy (&value, address, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 64)
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      memcpy (&value, address, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (32))
+    {
+      uint32_t value;
+      memcpy (&value, address, sizeof value);
+      value = bswap_32 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (64))
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      memcpy (&value, address, sizeof value);
+      value = bswap_64 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else
+    return TD_DBERR;
+
+  return TD_OK;
+}
diff --git a/gdb/glibc-dep/nptl_db/structs.def b/gdb/glibc-dep/nptl_db/structs.def
new file mode 100644
index 0000000..5c218a9
--- /dev/null
+++ b/gdb/glibc-dep/nptl_db/structs.def
@@ -0,0 +1,112 @@
+/* List of types and symbols in libpthread examined by libthread_db.
+   Copyright (C) 2003-2016 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/>.  */
+
+#ifndef DB_STRUCT_ARRAY_FIELD
+# define DB_STRUCT_ARRAY_FIELD(type, field) DB_STRUCT_FIELD (type, field)
+# define DB_ARRAY_VARIABLE(name) DB_VARIABLE (name)
+# define STRUCTS_DEF_DEFAULTS 1
+#endif
+
+#ifndef DB_RTLD_VARIABLE
+# define DB_RTLD_VARIABLE(name) DB_VARIABLE (name)
+#endif
+
+#ifndef DB_MAIN_VARIABLE
+# define DB_MAIN_VARIABLE(name) DB_VARIABLE (name)
+#endif
+
+#ifndef DB_RTLD_GLOBAL_FIELD
+#define DB_RTLD_GLOBAL_FIELD(field)     \
+  DB_STRUCT_FIELD (rtld_global, _##field) \
+  DB_MAIN_VARIABLE (_##field)
+#endif /* DB_RTLD_GLOBAL_FIELD */
+
+DB_STRUCT (pthread)
+DB_STRUCT_FIELD (pthread, list)
+DB_STRUCT_FIELD (pthread, report_events)
+DB_STRUCT_FIELD (pthread, tid)
+DB_STRUCT_FIELD (pthread, pid)
+DB_STRUCT_FIELD (pthread, start_routine)
+DB_STRUCT_FIELD (pthread, cancelhandling)
+DB_STRUCT_FIELD (pthread, schedpolicy)
+DB_STRUCT_FIELD (pthread, schedparam_sched_priority)
+DB_STRUCT_FIELD (pthread, specific)
+DB_STRUCT_FIELD (pthread, eventbuf)
+DB_STRUCT_FIELD (pthread, eventbuf_eventmask)
+DB_STRUCT_ARRAY_FIELD (pthread, eventbuf_eventmask_event_bits)
+DB_STRUCT_FIELD (pthread, nextevent)
+
+DB_STRUCT (list_t)
+DB_STRUCT_FIELD (list_t, next)
+DB_STRUCT_FIELD (list_t, prev)
+
+DB_STRUCT (td_thr_events_t)
+DB_STRUCT_ARRAY_FIELD (td_thr_events_t, event_bits)
+
+DB_STRUCT (td_eventbuf_t)
+DB_STRUCT_FIELD (td_eventbuf_t, eventnum)
+DB_STRUCT_FIELD (td_eventbuf_t, eventdata)
+
+DB_SYMBOL (stack_used)
+DB_SYMBOL (__stack_user)
+DB_SYMBOL (nptl_version)
+DB_FUNCTION (__nptl_create_event)
+DB_FUNCTION (__nptl_death_event)
+DB_SYMBOL (__nptl_threads_events)
+DB_VARIABLE (__nptl_nthreads)
+DB_VARIABLE (__nptl_last_event)
+DB_VARIABLE (__nptl_initial_report_events)
+
+DB_ARRAY_VARIABLE (__pthread_keys)
+DB_STRUCT (pthread_key_struct)
+DB_STRUCT_FIELD (pthread_key_struct, seq)
+DB_STRUCT_FIELD (pthread_key_struct, destr)
+
+DB_STRUCT (pthread_key_data)
+DB_STRUCT_FIELD (pthread_key_data, seq)
+DB_STRUCT_FIELD (pthread_key_data, data)
+DB_STRUCT (pthread_key_data_level2)
+DB_STRUCT_ARRAY_FIELD (pthread_key_data_level2, data)
+
+DB_STRUCT_FIELD (link_map, l_tls_modid)
+DB_STRUCT_FIELD (link_map, l_tls_offset)
+
+DB_STRUCT_ARRAY_FIELD (dtv, dtv)
+#define pointer_val pointer.val /* Field of anonymous struct in dtv_t.  */
+DB_STRUCT_FIELD (dtv_t, pointer_val)
+DB_STRUCT_FIELD (dtv_t, counter)
+DB_STRUCT_FIELD (pthread, dtvp)
+
+DB_STRUCT (rtld_global)
+DB_RTLD_VARIABLE (_rtld_global)
+DB_RTLD_GLOBAL_FIELD (dl_tls_dtv_slotinfo_list)
+
+DB_STRUCT (dtv_slotinfo_list)
+DB_STRUCT_FIELD (dtv_slotinfo_list, len)
+DB_STRUCT_FIELD (dtv_slotinfo_list, next)
+DB_STRUCT_ARRAY_FIELD (dtv_slotinfo_list, slotinfo)
+
+DB_STRUCT (dtv_slotinfo)
+DB_STRUCT_FIELD (dtv_slotinfo, gen)
+DB_STRUCT_FIELD (dtv_slotinfo, map)
+
+#ifdef STRUCTS_DEF_DEFAULTS
+# undef DB_STRUCT_ARRAY_FIELD
+# undef DB_ARRAY_VARIABLE
+# undef STRUCTS_DEF_DEFAULTS
+#endif
diff --git a/gdb/glibc-dep/nptl_db/td_symbol_list.c b/gdb/glibc-dep/nptl_db/td_symbol_list.c
new file mode 100644
index 0000000..bd61caa
--- /dev/null
+++ b/gdb/glibc-dep/nptl_db/td_symbol_list.c
@@ -0,0 +1,45 @@
+/* Return list of symbols the library can request.
+   Copyright (C) 2001,2002,2003,2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   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/>.  */
+
+#include <assert.h>
+#include <gnu/lib-names.h>
+#include "thread_dbP.h"
+
+
+static const char *symbol_list_arr[] =
+{
+# define DB_LOOKUP_NAME(idx, name)		[idx] = STRINGIFY (name),
+# define DB_LOOKUP_NAME_TH_UNIQUE(idx, name)	[idx] = STRINGIFY (name),
+# include "db-symbols.h"
+# undef	DB_LOOKUP_NAME
+# undef	DB_LOOKUP_NAME_TH_UNIQUE
+
+  [SYM_NUM_MESSAGES] = NULL
+};
+
+ps_err_e
+td_mod_lookup (struct ps_prochandle *ps, const char *mod,
+         int idx, psaddr_t *sym_addr)
+{
+  ps_err_e result;
+  assert (idx >= 0 && idx < SYM_NUM_MESSAGES);
+  result = ps_pglobal_lookup (ps, mod, symbol_list_arr[idx], sym_addr);
+
+  return result;
+}
\ No newline at end of file
diff --git a/gdb/glibc-dep/nptl_db/td_ta_map_lwp2thr.c b/gdb/glibc-dep/nptl_db/td_ta_map_lwp2thr.c
new file mode 100644
index 0000000..60f9574
--- /dev/null
+++ b/gdb/glibc-dep/nptl_db/td_ta_map_lwp2thr.c
@@ -0,0 +1,167 @@
+/* Which thread is running on an LWP?
+   Copyright (C) 2003-2016 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/>.  */
+
+#include "thread_dbP.h"
+#include <byteswap.h>
+
+
+td_err_e
+__td_ta_lookup_th_unique (const td_thragent_t *ta_arg,
+        lwpid_t lwpid, td_thrhandle_t *th)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  ps_err_e err;
+  td_err_e terr;
+  prgregset_t regs;
+  psaddr_t addr;
+
+  if (ta->ta_howto == ta_howto_unknown)
+    {
+      /* We need to read in from the inferior the instructions what to do.  */
+      psaddr_t howto;
+
+      err = td_lookup (ta->ph, SYM_TH_UNIQUE_CONST_THREAD_AREA, &howto);
+      if (err == PS_OK)
+  {
+    err = ps_pdread (ta->ph, howto,
+         &ta->ta_howto_data.const_thread_area,
+         sizeof ta->ta_howto_data.const_thread_area);
+    if (err != PS_OK)
+      return TD_ERR;
+    ta->ta_howto = ta_howto_const_thread_area;
+    if (ta->ta_howto_data.const_thread_area & 0xff000000U)
+      ta->ta_howto_data.const_thread_area
+        = bswap_32 (ta->ta_howto_data.const_thread_area);
+  }
+      else
+  {
+    switch (sizeof (regs[0]))
+      {
+      case 8:
+        err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER64, &howto);
+        if (err == PS_OK)
+    ta->ta_howto = ta_howto_reg;
+        else if (err == PS_NOSYM)
+    {
+      err = td_lookup (ta->ph,
+           SYM_TH_UNIQUE_REGISTER64_THREAD_AREA,
+           &howto);
+      if (err == PS_OK)
+        ta->ta_howto = ta_howto_reg_thread_area;
+    }
+        break;
+
+      case 4:
+        err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER32, &howto);
+        if (err == PS_OK)
+    ta->ta_howto = ta_howto_reg;
+        else if (err == PS_NOSYM)
+    {
+      err = td_lookup (ta->ph,
+           SYM_TH_UNIQUE_REGISTER32_THREAD_AREA,
+           &howto);
+      if (err == PS_OK)
+        ta->ta_howto = ta_howto_reg_thread_area;
+    }
+        break;
+
+      default:
+        abort ();
+        return TD_DBERR;
+      }
+
+    if (err != PS_OK)
+      return TD_DBERR;
+
+    /* For either of these methods we read in the same descriptor.  */
+    err = ps_pdread (ta->ph, howto,
+         ta->ta_howto_data.reg, DB_SIZEOF_DESC);
+    if (err != PS_OK)
+      return TD_ERR;
+    if (DB_DESC_SIZE (ta->ta_howto_data.reg) == 0)
+      return TD_DBERR;
+    if (DB_DESC_SIZE (ta->ta_howto_data.reg) & 0xff000000U)
+      {
+        /* Byte-swap these words, though we leave the size word
+     in native order as the handy way to distinguish.  */
+        DB_DESC_OFFSET (ta->ta_howto_data.reg)
+    = bswap_32 (DB_DESC_OFFSET (ta->ta_howto_data.reg));
+        DB_DESC_NELEM (ta->ta_howto_data.reg)
+    = bswap_32 (DB_DESC_NELEM (ta->ta_howto_data.reg));
+      }
+  }
+    }
+
+  switch (ta->ta_howto)
+    {
+    default:
+      return TD_DBERR;
+
+    case ta_howto_reg:
+      /* On most machines, we are just looking at a register.  */
+      if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
+  return TD_ERR;
+      terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg, -1,
+            0, regs, &addr);
+      if (terr != TD_OK)
+  return terr;
+
+      /* In this descriptor the nelem word is overloaded as the bias.  */
+      addr += (int32_t) DB_DESC_NELEM (ta->ta_howto_data.reg);
+      th->th_unique = addr;
+      break;
+
+    case ta_howto_const_thread_area:
+      /* Some hosts don't have this call and this case won't be used.  */
+# pragma weak ps_get_thread_area
+      if (&ps_get_thread_area == NULL)
+  return TD_NOCAPAB;
+
+      /* A la x86-64, there is a magic index for get_thread_area.  */
+      if (ps_get_thread_area (ta->ph, lwpid,
+            ta->ta_howto_data.const_thread_area,
+            &th->th_unique) != PS_OK)
+  return TD_ERR;  /* XXX Other error value?  */
+      break;
+
+    case ta_howto_reg_thread_area:
+      if (&ps_get_thread_area == NULL)
+  return TD_NOCAPAB;
+
+      /* A la i386, a register holds the index for get_thread_area.  */
+      if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
+  return TD_ERR;
+      terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg_thread_area,
+            -1, 0, regs, &addr);
+      if (terr != TD_OK)
+  return terr;
+      /* In this descriptor the nelem word is overloaded as scale factor.  */
+      if (ps_get_thread_area
+    (ta->ph, lwpid,
+     ((addr - (psaddr_t) 0)
+      >> DB_DESC_NELEM (ta->ta_howto_data.reg_thread_area)),
+     &th->th_unique) != PS_OK)
+  return TD_ERR;  /* XXX Other error value?  */
+      break;
+    }
+
+  /* Found it.  Now complete the `td_thrhandle_t' object.  */
+  th->th_ta_p = ta;
+
+  return TD_OK;
+}
\ No newline at end of file
diff --git a/gdb/glibc-dep/nptl_db/td_thr_tls_get_addr.c b/gdb/glibc-dep/nptl_db/td_thr_tls_get_addr.c
new file mode 100644
index 0000000..f1630a1
--- /dev/null
+++ b/gdb/glibc-dep/nptl_db/td_thr_tls_get_addr.c
@@ -0,0 +1,42 @@
+/* Get address of thread local variable.
+   Copyright (C) 2002-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 2002.
+
+   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/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+gdb_td_thr_tls_get_addr (const td_thrhandle_t *th,
+         psaddr_t map_address, size_t offset, psaddr_t *address)
+{
+  td_err_e err;
+  psaddr_t modid;
+
+  /* Get the TLS module ID from the `struct link_map' in the inferior.  */
+  err = DB_GET_FIELD (modid, th->th_ta_p, map_address, link_map,
+          l_tls_modid, 0);
+  if (err == TD_NOCAPAB)
+    return TD_NOAPLIC;
+  if (err == TD_OK)
+    {
+      err = gdb_td_thr_tlsbase (th, (uintptr_t) modid, address);
+      if (err == TD_OK)
+  *address += offset;
+    }
+  return err;
+}
diff --git a/gdb/glibc-dep/nptl_db/td_thr_tlsbase.c b/gdb/glibc-dep/nptl_db/td_thr_tlsbase.c
new file mode 100644
index 0000000..04e1af7
--- /dev/null
+++ b/gdb/glibc-dep/nptl_db/td_thr_tlsbase.c
@@ -0,0 +1,249 @@
+/* Locate TLS data for a thread.
+   Copyright (C) 2003-2016 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/>.  */
+
+#include "thread_dbP.h"
+#include "nat/gdb_thread_db.h"
+#include "tls.h"
+
+/* Get the DTV slotinfo list head entry from the dynamic loader state
+   into *LISTHEAD.  */
+static td_err_e
+dtv_slotinfo_list (td_thragent_t *ta,
+       psaddr_t *listhead)
+{
+  td_err_e err;
+  psaddr_t head;
+
+  if (ta->ta_addr__rtld_global == 0
+      && td_mod_lookup (ta->ph, LD_SO, SYM__rtld_global,
+      &ta->ta_addr__rtld_global) != PS_OK)
+    ta->ta_addr__rtld_global = (void*)-1;
+
+  if (ta->ta_addr__rtld_global != (void*)-1)
+    {
+      err = DB_GET_FIELD (head, ta, ta->ta_addr__rtld_global,
+        rtld_global, _dl_tls_dtv_slotinfo_list, 0);
+      if (err != TD_OK)
+  return err;
+    }
+  else
+    {
+      if (ta->ta_addr__dl_tls_dtv_slotinfo_list == 0
+    && td_mod_lookup (ta->ph, NULL, SYM__dl_tls_dtv_slotinfo_list,
+          &ta->ta_addr__dl_tls_dtv_slotinfo_list) != PS_OK)
+  return TD_ERR;
+
+      err = _td_fetch_value (ta, ta->ta_var__dl_tls_dtv_slotinfo_list,
+           SYM_DESC__dl_tls_dtv_slotinfo_list,
+           0, ta->ta_addr__dl_tls_dtv_slotinfo_list, &head);
+      if (err != TD_OK)
+  return err;
+    }
+
+  *listhead = head;
+  return TD_OK;
+}
+
+/* Get the address of the DTV slotinfo entry for MODID into
+   *DTVSLOTINFO.  */
+static td_err_e
+dtv_slotinfo (td_thragent_t *ta,
+        unsigned long int modid,
+        psaddr_t *dtvslotinfo)
+{
+  td_err_e err;
+  psaddr_t slot, temp;
+  size_t slbase = 0;
+
+  err = dtv_slotinfo_list (ta, &slot);
+  if (err != TD_OK)
+    return err;
+
+  while (slot)
+    {
+      /* Get the number of entries in this list entry's array.  */
+      err = DB_GET_FIELD (temp, ta, slot, dtv_slotinfo_list, len, 0);
+      if (err != TD_OK)
+  return err;
+      size_t len = (uintptr_t)temp;
+
+      /* Did we find the list entry for modid?  */
+      if (modid < slbase + len)
+  break;
+
+      /* We didn't, so get the next list entry.  */
+      slbase += len;
+      err = DB_GET_FIELD (temp, ta, slot, dtv_slotinfo_list,
+        next, 0);
+      if (err != TD_OK)
+  return err;
+      slot = temp;
+    }
+
+  /* We reached the end of the list and found nothing.  */
+  if (!slot)
+    return TD_ERR;
+
+  /* Take the slotinfo for modid from the list entry.  */
+  err = DB_GET_FIELD_ADDRESS (temp, ta, slot, dtv_slotinfo_list,
+            slotinfo, modid - slbase);
+  if (err != TD_OK)
+    return err;
+  slot = temp;
+
+  *dtvslotinfo = slot;
+  return TD_OK;
+}
+
+/* Return in *BASE the base address of the TLS block for MODID within
+   TH.
+
+   It should return success and yield the correct pointer in any
+   circumstance where the TLS block for the module and thread
+   requested has already been initialized.
+
+   It should fail with TD_TLSDEFER only when the thread could not
+   possibly have observed any values in that TLS block.  That way, the
+   debugger can fall back to showing initial values from the PT_TLS
+   segment (and refusing attempts to mutate) for the TD_TLSDEFER case,
+   and never fail to make the values the program will actually see
+   available to the user of the debugger.  */
+td_err_e
+gdb_td_thr_tlsbase (const td_thrhandle_t *th,
+    unsigned long int modid,
+    psaddr_t *base)
+{
+  td_err_e err;
+  psaddr_t dtv, dtvslot, dtvptr, temp;
+  psaddr_t map;
+  size_t modgen;
+
+  if (modid < 1)
+    return TD_NOTLS;
+
+  psaddr_t pd = th->th_unique;
+  if (pd == 0)
+    {
+      /* This is the fake handle for the main thread before libpthread
+   initialization.  We are using 0 for its th_unique because we can't
+   trust that its thread register has been initialized.  But we need
+   a real pointer to have any TLS access work.  In case of dlopen'd
+   libpthread, initialization might not be for quite some time.  So
+   try looking up the thread register now.  Worst case, it's nonzero
+   uninitialized garbage and we get bogus results for TLS access
+   attempted too early.  Tough.  */
+
+      td_thrhandle_t main_th;
+      err = __td_ta_lookup_th_unique (th->th_ta_p, ps_getpid (th->th_ta_p->ph),
+              &main_th);
+      if (err == 0)
+  pd = main_th.th_unique;
+      if (pd == 0)
+  return TD_TLSDEFER;
+    }
+
+  if (strcmp (versbuf,"2.22") >= 0)
+    {
+      err = dtv_slotinfo (th->th_ta_p, modid, &temp);
+      if (err != TD_OK)
+        return err;
+
+      psaddr_t slot;
+      err = DB_GET_STRUCT (slot, th->th_ta_p, temp, dtv_slotinfo);
+      if (err != TD_OK)
+        return err;
+
+      /* Take the link_map from the slotinfo.  */
+      err = DB_GET_FIELD_LOCAL (map, th->th_ta_p, slot, dtv_slotinfo, map, 0);
+      if (err != TD_OK)
+        return err;
+      if (!map)
+        return TD_ERR;
+
+      /* Ok, the modid is good, now find out what DTV generation it
+         requires.  */
+      err = DB_GET_FIELD_LOCAL (temp, th->th_ta_p, slot, dtv_slotinfo, gen, 0);
+      if (err != TD_OK)
+        return err;
+      modgen = (uintptr_t)temp;
+    }
+
+  /* Get the DTV pointer from the thread descriptor.  */
+  err = DB_GET_FIELD (dtv, th->th_ta_p, pd, pthread, dtvp, 0);
+  if (err != TD_OK)
+    return err;
+
+  if (strcmp (versbuf,"2.22") >= 0)
+    {
+      psaddr_t dtvgenloc;
+      /* Get the DTV generation count at dtv[0].counter.  */
+      err = DB_GET_FIELD_ADDRESS (dtvgenloc, th->th_ta_p, dtv, dtv, dtv, 0);
+      if (err != TD_OK)
+        return err;
+      err = DB_GET_FIELD (temp, th->th_ta_p, dtvgenloc, dtv_t, counter, 0);
+      if (err != TD_OK)
+        return err;
+      size_t dtvgen = (uintptr_t)temp;
+
+      /* Is the DTV current enough?  */
+      if (dtvgen < modgen)
+        {
+        try_static_tls:
+          /* If the module uses Static TLS, we're still good.  */
+          err = DB_GET_FIELD (temp, th->th_ta_p, map, link_map, l_tls_offset, 0);
+          if (err != TD_OK)
+      return err;
+          ptrdiff_t tlsoff = (uintptr_t)temp;
+
+          if (tlsoff != FORCED_DYNAMIC_TLS_OFFSET
+        && tlsoff != NO_TLS_OFFSET)
+      {
+        psaddr_t tp = pd;
+
+        if (TLS_TCB_AT_TP == 1)
+            dtvptr = tp - tlsoff;
+        else if (TLS_DTV_AT_TP == 1)
+            dtvptr = tp + tlsoff + TLS_PRE_TCB_SIZE;
+        else
+          return TD_ERR;
+
+        *base = dtvptr;
+        return TD_OK;
+      }
+
+          return TD_TLSDEFER;
+        }
+    }
+  /* Find the corresponding entry in the DTV.  */
+  err = DB_GET_FIELD_ADDRESS (dtvslot, th->th_ta_p, dtv, dtv, dtv, modid);
+  if (err != TD_OK)
+    return err;
+
+  /* Extract the TLS block address from that DTV slot.  */
+  err = DB_GET_FIELD (dtvptr, th->th_ta_p, dtvslot, dtv_t, pointer_val, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* It could be that the memory for this module is not allocated for
+     the given thread.  */
+  if ((uintptr_t) dtvptr & 1)
+    goto try_static_tls;
+
+  *base = dtvptr;
+  return TD_OK;
+}
diff --git a/gdb/glibc-dep/nptl_db/thread_dbP.h b/gdb/glibc-dep/nptl_db/thread_dbP.h
new file mode 100644
index 0000000..b7a934d
--- /dev/null
+++ b/gdb/glibc-dep/nptl_db/thread_dbP.h
@@ -0,0 +1,206 @@
+/* Private header for thread debug library
+   Copyright (C) 2003, 2004, 2007, 2011 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/>.  */
+
+#ifndef _THREAD_DBP_H
+#define _THREAD_DBP_H 1
+
+#ifndef HAVE_SYS_PROCFS_H
+#define HAVE_SYS_PROCFS_H
+#endif
+#ifndef HAVE_LWPID_T
+#define HAVE_LWPID_T
+#endif
+#ifndef HAVE_PSADDR_T
+#define HAVE_PSADDR_T
+#endif
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <alloca.h>
+#include <assert.h>
+#include "../config.h"
+#include "gdb_proc_service.h"
+#include <gnu/lib-names.h>
+#ifdef HAVE_THREAD_DB_H
+#include <thread_db.h>
+#else
+#include "nat/glibc_thread_db.h"
+#endif
+
+# define attribute_hidden __attribute__ ((visibility ("hidden")))
+
+char versbuf[5];
+
+/* Indeces for the symbol names.  */
+enum
+  {
+# define DB_STRUCT(type)		SYM_SIZEOF_##type,
+# define DB_STRUCT_FIELD(type, field)	SYM_##type##_FIELD_##field,
+# define DB_SYMBOL(name)		SYM_##name,
+# define DB_FUNCTION(name)		SYM_##name,
+# define DB_VARIABLE(name)		SYM_##name, SYM_DESC_##name,
+# include "structs.def"
+# undef DB_STRUCT
+# undef DB_STRUCT_FIELD
+# undef DB_SYMBOL
+# undef DB_FUNCTION
+# undef DB_VARIABLE
+
+    SYM_TH_UNIQUE_CONST_THREAD_AREA,
+    SYM_TH_UNIQUE_REGISTER64,
+    SYM_TH_UNIQUE_REGISTER32,
+    SYM_TH_UNIQUE_REGISTER64_THREAD_AREA,
+    SYM_TH_UNIQUE_REGISTER32_THREAD_AREA,
+
+    SYM_NUM_MESSAGES
+  };
+
+#define DB_DESC_SIZE(desc)	((desc)[0])
+#define DB_DESC_NELEM(desc)	((desc)[1])
+#define DB_DESC_OFFSET(desc)	((desc)[2])
+#define DB_SIZEOF_DESC		(3 * sizeof (uint32_t))
+#define DB_DEFINE_DESC(name, size, nelem, offset) \
+  const uint32_t name[3] = { (size), (nelem), (offset) }
+typedef uint32_t db_desc_t[3];
+
+typedef struct list_head
+{
+  struct list_head *next;
+  struct list_head *prev;
+} list_t;
+
+/* Handle for a process.  This type is opaque.  */
+struct td_thragent
+{
+  /* Chain on the list of all agent structures.  */
+  list_t list;
+
+  /* Delivered by the debugger and we have to pass it back in the
+     proc callbacks.  */
+  struct ps_prochandle *ph;
+
+  /* Cached values read from the inferior.  */
+# define DB_STRUCT(type) \
+  uint32_t ta_sizeof_##type;
+# define DB_STRUCT_FIELD(type, field) \
+  db_desc_t ta_field_##type##_##field;
+# define DB_SYMBOL(name) \
+  psaddr_t ta_addr_##name;
+# define DB_FUNCTION(name) \
+  psaddr_t ta_addr_##name;
+# define DB_VARIABLE(name) \
+  psaddr_t ta_addr_##name; \
+  db_desc_t ta_var_##name;
+# include "structs.def"
+# undef DB_STRUCT
+# undef DB_STRUCT_FIELD
+# undef DB_FUNCTION
+# undef DB_SYMBOL
+# undef DB_VARIABLE
+
+  /* The method of locating a thread's th_unique value.  */
+  enum
+    {
+      ta_howto_unknown,
+      ta_howto_reg,
+      ta_howto_reg_thread_area,
+      ta_howto_const_thread_area
+    } ta_howto;
+  union
+  {
+    uint32_t const_thread_area;	/* Constant argument to ps_get_thread_area.  */
+    /* These are as if the descriptor of the field in prregset_t,
+       but DB_DESC_NELEM is overloaded as follows: */
+    db_desc_t reg;		/* Signed bias applied to register value.  */
+    db_desc_t reg_thread_area;	/* Bits to scale down register value.  */
+  } ta_howto_data;
+};
+
+/* Internal wrappers around ps_pglobal_lookup.  */
+extern ps_err_e td_mod_lookup (struct ps_prochandle *ps, const char *modname,
+             int idx, psaddr_t *sym_addr) attribute_hidden;
+#define td_lookup(ps, idx, sym_addr) \
+  td_mod_lookup ((ps), LIBPTHREAD_SO, (idx), (sym_addr))
+
+/* Store in psaddr_t VAR the address of inferior's symbol NAME.  */
+#define DB_GET_SYMBOL(var, ta, name)					      \
+  (((ta)->ta_addr_##name == 0						      \
+    && td_lookup ((ta)->ph, SYM_##name, &(ta)->ta_addr_##name) != PS_OK)      \
+   ? TD_ERR : ((var) = (ta)->ta_addr_##name, TD_OK))
+
+/* Store in psaddr_t VAR the value of ((TYPE) PTR)->FIELD[IDX] in the inferior.
+   A target field smaller than psaddr_t is zero-extended.  */
+#define DB_GET_FIELD(var, ta, ptr, type, field, idx) \
+  _td_fetch_value ((ta), (ta)->ta_field_##type##_##field, \
+		   SYM_##type##_FIELD_##field, \
+		   (psaddr_t) 0 + (idx), (ptr), &(var))
+
+#define DB_GET_FIELD_ADDRESS(var, ta, ptr, type, field, idx) \
+  ((var) = (ptr), _td_locate_field ((ta), (ta)->ta_field_##type##_##field, \
+				    SYM_##type##_FIELD_##field, \
+				    (psaddr_t) 0 + (idx), &(var)))
+
+extern td_err_e _td_locate_field (td_thragent_t *ta,
+				  db_desc_t desc, int descriptor_name,
+				  psaddr_t idx,
+				  psaddr_t *address) attribute_hidden;
+
+
+/* Like DB_GET_FIELD, but PTR is a local pointer to a structure that
+   has already been copied in from the inferior.  */
+#define DB_GET_FIELD_LOCAL(var, ta, ptr, type, field, idx) \
+  _td_fetch_value_local ((ta), (ta)->ta_field_##type##_##field, \
+		         SYM_##type##_FIELD_##field, \
+			 (psaddr_t) 0 + (idx), (ptr), &(var))
+
+/* Helper functions for those.  */
+extern td_err_e _td_fetch_value (td_thragent_t *ta,
+				 db_desc_t field, int descriptor_name,
+				 psaddr_t idx, psaddr_t address,
+				 psaddr_t *result) attribute_hidden;
+extern td_err_e _td_fetch_value_local (td_thragent_t *ta,
+				       db_desc_t field,
+				       int descriptor_name,
+				       psaddr_t idx, void *address,
+				       psaddr_t *result) attribute_hidden;
+
+/* Helper functions for those.  */
+#define DB_GET_STRUCT(var, ta, ptr, type)				      \
+  ({ td_err_e _err = TD_OK;						      \
+     if ((ta)->ta_sizeof_##type == 0)					      \
+       _err = _td_check_sizeof ((ta), &(ta)->ta_sizeof_##type,		      \
+				      SYM_SIZEOF_##type);		      \
+     if (_err == TD_OK)							      \
+       _err = ps_pdread ((ta)->ph, (ptr),				      \
+			 (var) = alloca ((ta)->ta_sizeof_##type),	      \
+			 (ta)->ta_sizeof_##type)			      \
+	 == PS_OK ? TD_OK : TD_ERR;					      \
+     else								      \
+       (var) = NULL; 							      \
+     _err;								      \
+  })
+
+extern td_err_e _td_check_sizeof (td_thragent_t *ta, uint32_t *sizep,
+				  int sizep_name) attribute_hidden;
+
+extern td_err_e __td_ta_lookup_th_unique (const td_thragent_t *ta,
+					  lwpid_t lwpid, td_thrhandle_t *th);
+
+#endif /* thread_dbP.h */
diff --git a/gdb/glibc-dep/nptl_db/tls.h b/gdb/glibc-dep/nptl_db/tls.h
new file mode 100644
index 0000000..abe2923
--- /dev/null
+++ b/gdb/glibc-dep/nptl_db/tls.h
@@ -0,0 +1,37 @@
+/* Private header for thread debug library
+   Copyright (C) 2003, 2004, 2007, 2011 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/>.  */
+
+#ifndef __TLS_H__
+#define __TLS_H__
+
+unsigned tls_tcb_at_tp;
+unsigned tls_dtv_at_tp;
+int forced_dynamic_tls_offset;
+int no_tls_offset;
+unsigned tcb_alignment;
+
+#define TLS_DTV_AT_TP tls_dtv_at_tp
+#define TLS_TCB_AT_TP tls_tcb_at_tp
+#define TCB_ALIGNMENT tcb_alignment
+
+#define TLS_PRE_TCB_SIZE th->th_ta_p->ta_sizeof_pthread + TCB_ALIGNMENT
+
+#define NO_TLS_OFFSET no_tls_offset
+#define FORCED_DYNAMIC_TLS_OFFSET forced_dynamic_tls_offset
+
+#endif
\ No newline at end of file
diff --git a/gdb/gregset.h b/gdb/gregset.h
index 3101edc..03b6792 100644
--- a/gdb/gregset.h
+++ b/gdb/gregset.h
@@ -24,11 +24,11 @@
  #endif

  #ifndef GDB_GREGSET_T
-#define GDB_GREGSET_T gregset_t
+#define GDB_GREGSET_T elf_gregset_t
  #endif

  #ifndef GDB_FPREGSET_T
-#define GDB_FPREGSET_T fpregset_t
+#define GDB_FPREGSET_T elf_fpregset_t
  #endif

  typedef GDB_GREGSET_T gdb_gregset_t;
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index 86254f8..b622ddb 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -19,8 +19,10 @@

  #include "defs.h"
  #include <dlfcn.h>
+EXTERN_C_PUSH
  #include "gdb_proc_service.h"
  #include "nat/gdb_thread_db.h"
+EXTERN_C_POP
  #include "gdb_vecs.h"
  #include "bfd.h"
  #include "command.h"
@@ -46,6 +48,7 @@
  #include <ctype.h>
  #include "nat/linux-namespaces.h"
  #include <algorithm>
+#include "bfd.h"

  /* GNU/Linux libthread_db support.

@@ -536,6 +539,18 @@ try_thread_db_load_1 (struct thread_db_info *info)
    info->proc_handle.ptid = inferior_ptid;

    /* Now attempt to open a connection to the thread library.  */
+#ifdef CROSS_GDB
+  const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (target_gdbarch ());
+  unsigned arch = bfdarch->arch;
+
+  /* If it's host we want to keep old way of counting tls address. */
+  if (native_check (arch) != 0)
+    {
+       /* gdb_td_ta_new has similar behavior as td_ta_new, so if any
+          occurs same error will be catched in td_ta_new */
+       gdb_td_ta_new (&info->proc_handle, &info->thread_agent);
+    }
+#endif
    err = info->td_ta_new_p (&info->proc_handle, &info->thread_agent);
    if (err != TD_OK)
      {
@@ -564,8 +579,22 @@ try_thread_db_load_1 (struct thread_db_info *info)
    CHK (TDB_VERBOSE_DLSYM (info, td_thr_get_info));

    /* These are not essential.  */
+#ifdef CROSS_GDB
+  if (native_check (arch) != 0)
+    {
+      info->td_thr_tls_get_addr_p = gdb_td_thr_tls_get_addr;
+      info->td_thr_tlsbase_p = gdb_td_thr_tlsbase;
+    }
+  else
+    {
+      /* If it's host we want to keep old way of counting tls address. */
+      TDB_DLSYM (info, td_thr_tls_get_addr);
+      TDB_DLSYM (info, td_thr_tlsbase);
+    }
+#else
    TDB_DLSYM (info, td_thr_tls_get_addr);
    TDB_DLSYM (info, td_thr_tlsbase);
+#endif

    /* It's best to avoid td_ta_thr_iter if possible.  That walks data
       structures in the inferior's address space that may be corrupted,
diff --git a/gdb/nat/gdb_thread_db.h b/gdb/nat/gdb_thread_db.h
index a577d49..a8fe2df 100644
--- a/gdb/nat/gdb_thread_db.h
+++ b/gdb/nat/gdb_thread_db.h
@@ -28,6 +28,10 @@
  #define LIBTHREAD_DB_SO "libthread_db.so.1"
  #endif

+#ifndef LD_SO
+#define LD_SO "ld.so.1"
+#endif
+
  #ifndef LIBTHREAD_DB_SEARCH_PATH
  /* $sdir appears before $pdir for some minimal security protection:
     we trust the system libthread_db.so a bit more than some random
@@ -72,4 +76,15 @@ typedef td_err_e (td_thr_tlsbase_ftype) (const td_thrhandle_t *th,
  typedef const char ** (td_symbol_list_ftype) (void);
  typedef td_err_e (td_ta_delete_ftype) (td_thragent_t *);

+
+extern td_err_e gdb_td_ta_new (struct ps_prochandle *__ps, td_thragent_t **__ta);
+
+extern td_err_e gdb_td_thr_tlsbase (const td_thrhandle_t *th,
+         unsigned long int modid,
+         psaddr_t *base);
+extern td_err_e gdb_td_thr_tls_get_addr (const td_thrhandle_t *th,
+         psaddr_t map_address, size_t offset, psaddr_t *address);
+
+extern int native_check (unsigned bfd_arch);
+
  #endif /* GDB_THREAD_DB_H */
