@@ -44,6 +44,7 @@ libthread_db-routines = td_init td_log td_ta_new
td_ta_delete \
td_ta_set_event td_ta_event_getmsg \
td_ta_clear_event td_symbol_list \
td_thr_tlsbase td_thr_tls_get_addr \
+ td_ta_init_target_consts \
fetch-value
libthread_db-inhibit-o = $(filter-out .os,$(object-suffixes))
@@ -21,4 +21,7 @@ libthread_db {
GLIBC_2.3.3 {
td_thr_tlsbase;
}
+ GLIBC_2.26 {
+ td_ta_init_target_consts;
+ }
}
@@ -23,6 +23,8 @@
#define DB_STRUCT(type) \
DB_LOOKUP_NAME (SYM_SIZEOF_##type, _thread_db_sizeof_##type)
+#define DB_CONST(name) \
+ DB_LOOKUP_NAME (SYM_CONST_##name, _thread_db_const_##name)
#define DB_STRUCT_FIELD(type, field) \
DB_LOOKUP_NAME (SYM_##type##_FIELD_##field, _thread_db_##type##_##field)
#define DB_SYMBOL(name) \
@@ -36,6 +38,7 @@
# include "structs.def"
# undef DB_STRUCT
+# undef DB_CONST
# undef DB_FUNCTION
# undef DB_SYMBOL
# undef DB_VARIABLE
@@ -68,9 +68,15 @@ DESC (_thread_db_pthread_dtvp,
- (TLS_TCB_SIZE == 0 ? sizeof (tcbhead_t) : 0), union dtv *)
#endif
+/* Definition of this macro is neccessary for enabling cross core
debugging */
+#ifndef TLS_PRE_TCB_SIZE
+#define TLS_PRE_TCB_SIZE 0
+#endif
#define DB_STRUCT(type) \
const uint32_t _thread_db_sizeof_##type = sizeof (type);
+#define DB_CONST(name) \
+ const int32_t _thread_db_const_##name = name;
#define DB_STRUCT_FIELD(type, field) \
DESC (_thread_db_##type##_##field, \
offsetof (type, field), ((type *) 0)->field)
@@ -83,6 +89,7 @@ DESC (_thread_db_pthread_dtvp,
#define DB_FUNCTION(name) /* Nothing. */
#include "structs.def"
#undef DB_STRUCT
+#undef DB_CONST
#undef DB_STRUCT_FIELD
#undef DB_SYMBOL
#undef DB_FUNCTION
@@ -22,21 +22,28 @@
#include <stdint.h>
td_err_e
+_td_check_constant (td_thragent_t *ta, uint32_t *sizep, int sizep_name)
+{
+ 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_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_check_constant(ta,sizep, sizep_name);
return TD_OK;
}
@@ -44,6 +44,11 @@
# endif
#endif /* DB_RTLD_GLOBAL_FIELD */
+DB_CONST (TLS_PRE_TCB_SIZE)
+DB_CONST (TLS_TCB_AT_TP)
+DB_CONST (TLS_DTV_AT_TP)
+DB_CONST (NO_TLS_OFFSET)
+
DB_STRUCT (pthread)
DB_STRUCT_FIELD (pthread, list)
DB_STRUCT_FIELD (pthread, report_events)
nptl_db/td_ta_init_target_consts.c
new file mode 100644
@@ -0,0 +1,58 @@
+/* Initialization function of thread debugger support library.
+ Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+ 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
+td_ta_init_target_consts (td_thragent_t *ta)
+{
+ td_err_e err;
+
+ err = _td_check_constant (ta, DB_GET_CONST (&ta, TLS_TCB_AT_TP),
+ SYM_CONST_TLS_TCB_AT_TP);
+ if ( err != TD_OK)
+ return err;
+ err = _td_check_constant (ta, DB_GET_CONST (&ta, TLS_DTV_AT_TP),
+ SYM_CONST_TLS_DTV_AT_TP);
+ if ( err != TD_OK)
+ return err;
+
+ if (!(DB_GET_CONST (ta, TLS_TCB_AT_TP) ^ DB_GET_CONST (ta,
TLS_DTV_AT_TP)))
+ return TD_ERR;
+
+
+ if (DB_GET_CONST (ta, TLS_DTV_AT_TP))
+ {
+ err = _td_check_constant (ta, DB_GET_CONST (&ta, TLS_PRE_TCB_SIZE),
+ SYM_CONST_TLS_PRE_TCB_SIZE);
+ if ( err != TD_OK)
+ return err;
+ }
+ else
+ {
+ DB_GET_CONST (ta, TLS_PRE_TCB_SIZE) = 0;
+ }
+
+ err = _td_check_constant (ta, DB_GET_CONST (&ta, NO_TLS_OFFSET),
+ SYM_CONST_NO_TLS_OFFSET);
+ if ( err != TD_OK)
+ return err;
+
+ return TD_OK;
+}
\ No newline at end of file
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <version.h>
+#include <link.h>
#include "thread_dbP.h"
@@ -29,6 +30,21 @@
be exactly one so we don't spend much though on making it fast. */
LIST_HEAD (__td_agent_list);
+static void
+td_ta_init_consts (td_thragent_t *ta)
+{
+ DB_GET_CONST (ta, TLS_TCB_AT_TP) = TLS_TCB_AT_TP;
+ DB_GET_CONST (ta, TLS_DTV_AT_TP) = TLS_DTV_AT_TP;
+#if TLS_DTV_AT_TP
+ DB_GET_CONST (ta, TLS_PRE_TCB_SIZE) = TLS_PRE_TCB_SIZE;
+#elif TLS_TCB_AT_TP
+ DB_GET_CONST (ta, TLS_PRE_TCB_SIZE) = 0;
+#else
+# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+#endif
+ DB_GET_CONST (ta, NO_TLS_OFFSET) = NO_TLS_OFFSET;
+}
+
td_err_e
td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
@@ -60,5 +76,7 @@ td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
/* Now add the new agent descriptor to the list. */
list_add (&(*ta)->list, &__td_agent_list);
+ td_ta_init_consts (*ta);
+
return TD_OK;
}
@@ -202,19 +202,17 @@ td_thr_tlsbase (const td_thrhandle_t *th,
if (err != TD_OK)
return err;
ptrdiff_t tlsoff = (uintptr_t)temp;
+ int8_t no_tls_offset = DB_GET_CONST (th->th_ta_p, NO_TLS_OFFSET);
+ int8_t forced_dynamic_tls_offset = no_tls_offset - 1;
- if (tlsoff != FORCED_DYNAMIC_TLS_OFFSET
- && tlsoff != NO_TLS_OFFSET)
+ if (tlsoff != forced_dynamic_tls_offset
+ && tlsoff != no_tls_offset)
{
psaddr_t tp = pd;
+ int8_t variant_sign = ((DB_GET_CONST(th->th_ta_p, TLS_TCB_AT_TP)) ?
(-1) : (1));
+ uint32_t tls_pre_tcb_size = DB_GET_CONST (th->th_ta_p,
TLS_PRE_TCB_SIZE);
-#if TLS_TCB_AT_TP
- dtvptr = tp - tlsoff;
-#elif TLS_DTV_AT_TP
- dtvptr = tp + tlsoff + TLS_PRE_TCB_SIZE;
-#else
-# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
-#endif
+ dtvptr = tp + variant_sign * tlsoff + tls_pre_tcb_size;
*base = dtvptr;
return TD_OK;
@@ -409,6 +409,10 @@ extern td_err_e td_thr_tlsbase (const
td_thrhandle_t *__th,
unsigned long int __modid,
psaddr_t *__base);
+/* Set thread_db constants for fetching tls. This should only be called
when
+ fetching tls from cross target core file. */
+extern td_err_e td_ta_init_target_consts (td_thragent_t *ta);
+
/* Get address of thread local variable. */
extern td_err_e td_thr_tls_get_addr (const td_thrhandle_t *__th,
psaddr_t __map_address, size_t __offset,
@@ -36,12 +36,14 @@
enum
{
# define DB_STRUCT(type) SYM_SIZEOF_##type,
+# define DB_CONST(name) SYM_CONST_##name,
# 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_CONST
# undef DB_STRUCT_FIELD
# undef DB_SYMBOL
# undef DB_FUNCTION
@@ -88,6 +90,8 @@ struct td_thragent
/* Cached values read from the inferior. */
# define DB_STRUCT(type) \
uint32_t ta_sizeof_##type;
+# define DB_CONST(name) \
+ uint32_t ta_const_##name;
# define DB_STRUCT_FIELD(type, field) \
db_desc_t ta_field_##type##_##field;
# define DB_SYMBOL(name) \
@@ -99,6 +103,7 @@ struct td_thragent
db_desc_t ta_var_##name;
# include "structs.def"
# undef DB_STRUCT
+# undef DB_CONST
# undef DB_STRUCT_FIELD
# undef DB_FUNCTION
# undef DB_SYMBOL
@@ -229,6 +234,9 @@ extern td_err_e _td_fetch_value_local (td_thragent_t
*ta,
: _td_store_value ((ta), (ta)->ta_var_##name, SYM_DESC_##name, \
(psaddr_t) 0 + (idx), (ta)->ta_addr_##name, (value)))
+
+#define DB_GET_CONST(ta, name) ta->ta_const_##name
+
/* Helper functions for those. */
extern td_err_e _td_store_value (td_thragent_t *ta,