forked from djolertrk/gdb_tls
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TLS access support in multiarch Linux GNU GDB
TLS variable was not propagating from core dump file to GDB and this patch implements that behavior for multiarch GDB. This approach includes linux-thread-db.c to be compiled for multiarch GDB, where appropriate functions for getting TLS addresses are used. If the program being debugged is built for host architecture, we keep the old way of calculating TLS. For target architectures modified libthread_db functions (td_ta_new(), td_thr_tls_get_addr(), td_thr_tlsbase()) are used, which can work with any version of glibc. Also, additional functions are copied from glibc in order to satisfy missing dependencies. Similar to native debugging, host libthread_db.so should be loaded into multiarch GDB. It should be the same version of the library which is used for getting core dump file. This is needed in order to initialize necessary thread data in libthread_db.so. * 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.
- Loading branch information
Showing
20 changed files
with
1,361 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
|
||
------------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#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 "../../../bfd/bfd.h" | ||
#include "nptl_db/tls.h" | ||
|
||
static td_err_e | ||
init_target_dep_constants() | ||
{ | ||
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; | ||
tcb_alignment = 0; //set to zero because not in use for TLS_PRE_TCB_SIZE | ||
break; | ||
case bfd_arch_i386: | ||
tls_tcb_at_tp = 1; | ||
tls_dtv_at_tp = 0; | ||
forced_dynamic_tls_offset = -1; | ||
no_tls_offset = 0; | ||
tcb_alignment = 0; //set to zero because not in use for TLS_PRE_TCB_SIZE | ||
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; | ||
tcb_alignment = 0; //set to zero because not in use for TLS_PRE_TCB_SIZE | ||
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#include "native_check.h" | ||
#include <string.h> | ||
#include <stdio.h> | ||
#include "../config.h" | ||
#include "../../../bfd/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) | ||
return 0; //zero if it's host | ||
else | ||
return 1; | ||
} | ||
return -1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
unsigned get_host_mach(char *name_of_arch); | ||
int native_check(unsigned bfd_arch); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
Oops, something went wrong.