2006-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
Daniel Jacobowitz <dan@codesourcery.com> * Makefile.in (expprint.o, parse.o, target.o): Update. * dwarf2loc.c (dwarf_expr_tls_address): Move body to target_translate_tls_address. Call it. * eval.c (evaluate_subexp_standard): Handle UNOP_MEMVAL_TLS. * expprint.c (print_subexp_standard): Likewise. (op_name_standard, dump_subexp_body_standard): Likewise. * expression.h (enum exp_opcode): Add UNOP_MEMVAL_TLS. (union exp_element): Add objfile. * parse.c (write_exp_elt_objfile): New function. (msym_tls_symbol_type): New. (write_exp_msymbol): Handle TLS. (operator_length_standard): Handle UNOP_MEMVAL_TLS. (build_parse): Initialize msym_tls_symbol_type. * parser-defs.h (write_exp_elt_objfile): New prototype. * target.c (target_translate_tls_address): New. * target.h (target_translate_tls_address): Add prototype. 2006-10-09 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.threads/tls-nodebug.c, gdb.threads/tls-nodebug.exp: New test.
This commit is contained in:
parent
a48251ed04
commit
9e35dae425
@ -1,3 +1,23 @@
|
||||
2006-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* Makefile.in (expprint.o, parse.o, target.o): Update.
|
||||
* dwarf2loc.c (dwarf_expr_tls_address): Move body to
|
||||
target_translate_tls_address. Call it.
|
||||
* eval.c (evaluate_subexp_standard): Handle UNOP_MEMVAL_TLS.
|
||||
* expprint.c (print_subexp_standard): Likewise.
|
||||
(op_name_standard, dump_subexp_body_standard): Likewise.
|
||||
* expression.h (enum exp_opcode): Add UNOP_MEMVAL_TLS.
|
||||
(union exp_element): Add objfile.
|
||||
* parse.c (write_exp_elt_objfile): New function.
|
||||
(msym_tls_symbol_type): New.
|
||||
(write_exp_msymbol): Handle TLS.
|
||||
(operator_length_standard): Handle UNOP_MEMVAL_TLS.
|
||||
(build_parse): Initialize msym_tls_symbol_type.
|
||||
* parser-defs.h (write_exp_elt_objfile): New prototype.
|
||||
* target.c (target_translate_tls_address): New.
|
||||
* target.h (target_translate_tls_address): Add prototype.
|
||||
|
||||
2006-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* solib.c (solib_open): Handle an empty solib_absolute_prefix like a
|
||||
|
@ -1982,7 +1982,7 @@ exec.o: exec.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) $(gdbcmd_h) \
|
||||
$(xcoffsolib_h) $(observer_h)
|
||||
expprint.o: expprint.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
|
||||
$(value_h) $(language_h) $(parser_defs_h) $(user_regs_h) $(target_h) \
|
||||
$(gdb_string_h) $(block_h)
|
||||
$(gdb_string_h) $(block_h) $(objfiles_h)
|
||||
fbsd-nat.o: fbsd-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) $(regcache_h) \
|
||||
$(regset_h) $(gdb_assert_h) $(gdb_string_h) $(elf_bfd_h) \
|
||||
$(fbsd_nat_h)
|
||||
@ -2429,7 +2429,7 @@ osabi.o: osabi.c $(defs_h) $(gdb_assert_h) $(gdb_string_h) $(osabi_h) \
|
||||
parse.o: parse.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
|
||||
$(frame_h) $(expression_h) $(value_h) $(command_h) $(language_h) \
|
||||
$(f_lang_h) $(parser_defs_h) $(gdbcmd_h) $(symfile_h) $(inferior_h) \
|
||||
$(doublest_h) $(gdb_assert_h) $(block_h) $(source_h)
|
||||
$(doublest_h) $(gdb_assert_h) $(block_h) $(source_h) $(objfiles_h)
|
||||
p-exp.o: p-exp.c $(defs_h) $(gdb_string_h) $(expression_h) $(value_h) \
|
||||
$(parser_defs_h) $(language_h) $(p_lang_h) $(bfd_h) $(symfile_h) \
|
||||
$(objfiles_h) $(block_h)
|
||||
@ -2757,7 +2757,8 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
|
||||
$(gdb_stat_h) $(cp_abi_h) $(observer_h)
|
||||
target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
|
||||
$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
|
||||
$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h)
|
||||
$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
|
||||
$(exceptions_h)
|
||||
target-memory.o: target-memory.c $(defs_h) $(vec_h) $(target_h) \
|
||||
$(memory_map_h) $(gdb_assert_h)
|
||||
thread.o: thread.c $(defs_h) $(symtab_h) $(frame_h) $(inferior_h) \
|
||||
|
@ -189,86 +189,8 @@ static CORE_ADDR
|
||||
dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
|
||||
{
|
||||
struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
|
||||
volatile CORE_ADDR addr = 0;
|
||||
|
||||
if (target_get_thread_local_address_p ()
|
||||
&& gdbarch_fetch_tls_load_module_address_p (current_gdbarch))
|
||||
{
|
||||
ptid_t ptid = inferior_ptid;
|
||||
struct objfile *objfile = debaton->objfile;
|
||||
volatile struct gdb_exception ex;
|
||||
|
||||
TRY_CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
CORE_ADDR lm_addr;
|
||||
|
||||
/* Fetch the load module address for this objfile. */
|
||||
lm_addr = gdbarch_fetch_tls_load_module_address (current_gdbarch,
|
||||
objfile);
|
||||
/* If it's 0, throw the appropriate exception. */
|
||||
if (lm_addr == 0)
|
||||
throw_error (TLS_LOAD_MODULE_NOT_FOUND_ERROR,
|
||||
_("TLS load module not found"));
|
||||
|
||||
addr = target_get_thread_local_address (ptid, lm_addr, offset);
|
||||
}
|
||||
/* If an error occurred, print TLS related messages here. Otherwise,
|
||||
throw the error to some higher catcher. */
|
||||
if (ex.reason < 0)
|
||||
{
|
||||
int objfile_is_library = (objfile->flags & OBJF_SHARED);
|
||||
|
||||
switch (ex.error)
|
||||
{
|
||||
case TLS_NO_LIBRARY_SUPPORT_ERROR:
|
||||
error (_("Cannot find thread-local variables in this thread library."));
|
||||
break;
|
||||
case TLS_LOAD_MODULE_NOT_FOUND_ERROR:
|
||||
if (objfile_is_library)
|
||||
error (_("Cannot find shared library `%s' in dynamic"
|
||||
" linker's load module list"), objfile->name);
|
||||
else
|
||||
error (_("Cannot find executable file `%s' in dynamic"
|
||||
" linker's load module list"), objfile->name);
|
||||
break;
|
||||
case TLS_NOT_ALLOCATED_YET_ERROR:
|
||||
if (objfile_is_library)
|
||||
error (_("The inferior has not yet allocated storage for"
|
||||
" thread-local variables in\n"
|
||||
"the shared library `%s'\n"
|
||||
"for %s"),
|
||||
objfile->name, target_pid_to_str (ptid));
|
||||
else
|
||||
error (_("The inferior has not yet allocated storage for"
|
||||
" thread-local variables in\n"
|
||||
"the executable `%s'\n"
|
||||
"for %s"),
|
||||
objfile->name, target_pid_to_str (ptid));
|
||||
break;
|
||||
case TLS_GENERIC_ERROR:
|
||||
if (objfile_is_library)
|
||||
error (_("Cannot find thread-local storage for %s, "
|
||||
"shared library %s:\n%s"),
|
||||
target_pid_to_str (ptid),
|
||||
objfile->name, ex.message);
|
||||
else
|
||||
error (_("Cannot find thread-local storage for %s, "
|
||||
"executable file %s:\n%s"),
|
||||
target_pid_to_str (ptid),
|
||||
objfile->name, ex.message);
|
||||
break;
|
||||
default:
|
||||
throw_exception (ex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* It wouldn't be wrong here to try a gdbarch method, too; finding
|
||||
TLS is an ABI-specific thing. But we don't do that yet. */
|
||||
else
|
||||
error (_("Cannot find thread-local variables on this target"));
|
||||
|
||||
return addr;
|
||||
return target_translate_tls_address (debaton->objfile, offset);
|
||||
}
|
||||
|
||||
/* Evaluate a location description, starting at DATA and with length
|
||||
|
15
gdb/eval.c
15
gdb/eval.c
@ -2019,6 +2019,21 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||
return value_at_lazy (exp->elts[pc + 1].type,
|
||||
value_as_address (arg1));
|
||||
|
||||
case UNOP_MEMVAL_TLS:
|
||||
(*pos) += 3;
|
||||
arg1 = evaluate_subexp (expect_type, exp, pos, noside);
|
||||
if (noside == EVAL_SKIP)
|
||||
goto nosideret;
|
||||
if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
return value_zero (exp->elts[pc + 2].type, lval_memory);
|
||||
else
|
||||
{
|
||||
CORE_ADDR tls_addr;
|
||||
tls_addr = target_translate_tls_address (exp->elts[pc + 1].objfile,
|
||||
value_as_address (arg1));
|
||||
return value_at_lazy (exp->elts[pc + 2].type, tls_addr);
|
||||
}
|
||||
|
||||
case UNOP_PREINCREMENT:
|
||||
arg1 = evaluate_subexp (expect_type, exp, pos, noside);
|
||||
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "target.h"
|
||||
#include "gdb_string.h"
|
||||
#include "block.h"
|
||||
#include "objfiles.h"
|
||||
|
||||
#ifdef HAVE_CTYPE_H
|
||||
#include <ctype.h>
|
||||
@ -414,6 +415,18 @@ print_subexp_standard (struct expression *exp, int *pos,
|
||||
fputs_filtered (")", stream);
|
||||
return;
|
||||
|
||||
case UNOP_MEMVAL_TLS:
|
||||
(*pos) += 3;
|
||||
if ((int) prec > (int) PREC_PREFIX)
|
||||
fputs_filtered ("(", stream);
|
||||
fputs_filtered ("{", stream);
|
||||
type_print (exp->elts[pc + 2].type, "", stream, 0);
|
||||
fputs_filtered ("} ", stream);
|
||||
print_subexp (exp, pos, stream, PREC_PREFIX);
|
||||
if ((int) prec > (int) PREC_PREFIX)
|
||||
fputs_filtered (")", stream);
|
||||
return;
|
||||
|
||||
case BINOP_ASSIGN_MODIFY:
|
||||
opcode = exp->elts[pc + 1].opcode;
|
||||
(*pos) += 2;
|
||||
@ -694,6 +707,8 @@ op_name_standard (enum exp_opcode opcode)
|
||||
return "UNOP_CAST";
|
||||
case UNOP_MEMVAL:
|
||||
return "UNOP_MEMVAL";
|
||||
case UNOP_MEMVAL_TLS:
|
||||
return "UNOP_MEMVAL_TLS";
|
||||
case UNOP_NEG:
|
||||
return "UNOP_NEG";
|
||||
case UNOP_LOGICAL_NOT:
|
||||
@ -999,6 +1014,16 @@ dump_subexp_body_standard (struct expression *exp,
|
||||
fprintf_filtered (stream, ")");
|
||||
elt = dump_subexp (exp, stream, elt + 2);
|
||||
break;
|
||||
case UNOP_MEMVAL_TLS:
|
||||
fprintf_filtered (stream, "TLS type @");
|
||||
gdb_print_host_address (exp->elts[elt + 1].type, stream);
|
||||
fprintf_filtered (stream, " (__thread /* \"%s\" */ ",
|
||||
(exp->elts[elt].objfile == NULL ? "(null)"
|
||||
: exp->elts[elt].objfile->name));
|
||||
type_print (exp->elts[elt + 1].type, NULL, stream, 0);
|
||||
fprintf_filtered (stream, ")");
|
||||
elt = dump_subexp (exp, stream, elt + 3);
|
||||
break;
|
||||
case OP_TYPE:
|
||||
fprintf_filtered (stream, "Type @");
|
||||
gdb_print_host_address (exp->elts[elt].type, stream);
|
||||
|
@ -234,6 +234,13 @@ enum exp_opcode
|
||||
following subexpression. */
|
||||
UNOP_MEMVAL,
|
||||
|
||||
/* UNOP_MEMVAL_TLS is followed by a `struct objfile' pointer in the next
|
||||
exp_element and a type pointer in the following exp_element.
|
||||
With another UNOP_MEMVAL_TLS at the end, this makes four exp_elements.
|
||||
It casts the contents of the word offsetted by the value of the
|
||||
following subexpression from the TLS specified by `struct objfile'. */
|
||||
UNOP_MEMVAL_TLS,
|
||||
|
||||
/* UNOP_... operate on one value from a following subexpression
|
||||
and replace it with a result. They take no immediate arguments. */
|
||||
|
||||
@ -360,6 +367,7 @@ union exp_element
|
||||
struct type *type;
|
||||
struct internalvar *internalvar;
|
||||
struct block *block;
|
||||
struct objfile *objfile;
|
||||
};
|
||||
|
||||
struct expression
|
||||
|
36
gdb/parse.c
36
gdb/parse.c
@ -53,6 +53,7 @@
|
||||
#include "gdb_assert.h"
|
||||
#include "block.h"
|
||||
#include "source.h"
|
||||
#include "objfiles.h"
|
||||
|
||||
/* Standard set of definitions for printing, dumping, prefixifying,
|
||||
* and evaluating expressions. */
|
||||
@ -218,6 +219,15 @@ write_exp_elt_block (struct block *b)
|
||||
write_exp_elt (tmp);
|
||||
}
|
||||
|
||||
void
|
||||
write_exp_elt_objfile (struct objfile *objfile)
|
||||
{
|
||||
union exp_element tmp;
|
||||
memset (&tmp, 0, sizeof (union exp_element));
|
||||
tmp.objfile = objfile;
|
||||
write_exp_elt (tmp);
|
||||
}
|
||||
|
||||
void
|
||||
write_exp_elt_longcst (LONGEST expelt)
|
||||
{
|
||||
@ -378,6 +388,7 @@ write_exp_bitstring (struct stoken str)
|
||||
static struct type *msym_text_symbol_type;
|
||||
static struct type *msym_data_symbol_type;
|
||||
static struct type *msym_unknown_symbol_type;
|
||||
static struct type *msym_tls_symbol_type;
|
||||
|
||||
void
|
||||
write_exp_msymbol (struct minimal_symbol *msymbol,
|
||||
@ -397,6 +408,22 @@ write_exp_msymbol (struct minimal_symbol *msymbol,
|
||||
|
||||
write_exp_elt_opcode (OP_LONG);
|
||||
|
||||
if (SYMBOL_BFD_SECTION (msymbol)->flags & SEC_THREAD_LOCAL)
|
||||
{
|
||||
bfd *bfd = SYMBOL_BFD_SECTION (msymbol)->owner;
|
||||
struct objfile *ofp;
|
||||
|
||||
ALL_OBJFILES (ofp)
|
||||
if (ofp->obfd == bfd)
|
||||
break;
|
||||
|
||||
write_exp_elt_opcode (UNOP_MEMVAL_TLS);
|
||||
write_exp_elt_objfile (ofp);
|
||||
write_exp_elt_type (msym_tls_symbol_type);
|
||||
write_exp_elt_opcode (UNOP_MEMVAL_TLS);
|
||||
return;
|
||||
}
|
||||
|
||||
write_exp_elt_opcode (UNOP_MEMVAL);
|
||||
switch (msymbol->type)
|
||||
{
|
||||
@ -904,6 +931,11 @@ operator_length_standard (struct expression *expr, int endpos,
|
||||
args = 1;
|
||||
break;
|
||||
|
||||
case UNOP_MEMVAL_TLS:
|
||||
oplen = 4;
|
||||
args = 1;
|
||||
break;
|
||||
|
||||
case UNOP_ABS:
|
||||
case UNOP_CAP:
|
||||
case UNOP_CHR:
|
||||
@ -1341,6 +1373,10 @@ build_parse (void)
|
||||
init_type (TYPE_CODE_INT, 1, 0,
|
||||
"<variable (not text or data), no debug info>",
|
||||
NULL);
|
||||
|
||||
msym_tls_symbol_type =
|
||||
init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0,
|
||||
"<thread local variable, no debug info>", NULL);
|
||||
}
|
||||
|
||||
/* This function avoids direct calls to fprintf
|
||||
|
@ -131,6 +131,8 @@ extern void write_exp_bitstring (struct stoken);
|
||||
|
||||
extern void write_exp_elt_block (struct block *);
|
||||
|
||||
extern void write_exp_elt_objfile (struct objfile *objfile);
|
||||
|
||||
extern void write_exp_msymbol (struct minimal_symbol *,
|
||||
struct type *, struct type *);
|
||||
|
||||
|
87
gdb/target.c
87
gdb/target.c
@ -39,6 +39,7 @@
|
||||
#include "regcache.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "gdbcore.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
static void target_info (char *, int);
|
||||
|
||||
@ -758,6 +759,92 @@ pop_target (void)
|
||||
internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
|
||||
}
|
||||
|
||||
/* Using the objfile specified in BATON, find the address for the
|
||||
current thread's thread-local storage with offset OFFSET. */
|
||||
CORE_ADDR
|
||||
target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
|
||||
{
|
||||
volatile CORE_ADDR addr = 0;
|
||||
|
||||
if (target_get_thread_local_address_p ()
|
||||
&& gdbarch_fetch_tls_load_module_address_p (current_gdbarch))
|
||||
{
|
||||
ptid_t ptid = inferior_ptid;
|
||||
volatile struct gdb_exception ex;
|
||||
|
||||
TRY_CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
CORE_ADDR lm_addr;
|
||||
|
||||
/* Fetch the load module address for this objfile. */
|
||||
lm_addr = gdbarch_fetch_tls_load_module_address (current_gdbarch,
|
||||
objfile);
|
||||
/* If it's 0, throw the appropriate exception. */
|
||||
if (lm_addr == 0)
|
||||
throw_error (TLS_LOAD_MODULE_NOT_FOUND_ERROR,
|
||||
_("TLS load module not found"));
|
||||
|
||||
addr = target_get_thread_local_address (ptid, lm_addr, offset);
|
||||
}
|
||||
/* If an error occurred, print TLS related messages here. Otherwise,
|
||||
throw the error to some higher catcher. */
|
||||
if (ex.reason < 0)
|
||||
{
|
||||
int objfile_is_library = (objfile->flags & OBJF_SHARED);
|
||||
|
||||
switch (ex.error)
|
||||
{
|
||||
case TLS_NO_LIBRARY_SUPPORT_ERROR:
|
||||
error (_("Cannot find thread-local variables in this thread library."));
|
||||
break;
|
||||
case TLS_LOAD_MODULE_NOT_FOUND_ERROR:
|
||||
if (objfile_is_library)
|
||||
error (_("Cannot find shared library `%s' in dynamic"
|
||||
" linker's load module list"), objfile->name);
|
||||
else
|
||||
error (_("Cannot find executable file `%s' in dynamic"
|
||||
" linker's load module list"), objfile->name);
|
||||
break;
|
||||
case TLS_NOT_ALLOCATED_YET_ERROR:
|
||||
if (objfile_is_library)
|
||||
error (_("The inferior has not yet allocated storage for"
|
||||
" thread-local variables in\n"
|
||||
"the shared library `%s'\n"
|
||||
"for %s"),
|
||||
objfile->name, target_pid_to_str (ptid));
|
||||
else
|
||||
error (_("The inferior has not yet allocated storage for"
|
||||
" thread-local variables in\n"
|
||||
"the executable `%s'\n"
|
||||
"for %s"),
|
||||
objfile->name, target_pid_to_str (ptid));
|
||||
break;
|
||||
case TLS_GENERIC_ERROR:
|
||||
if (objfile_is_library)
|
||||
error (_("Cannot find thread-local storage for %s, "
|
||||
"shared library %s:\n%s"),
|
||||
target_pid_to_str (ptid),
|
||||
objfile->name, ex.message);
|
||||
else
|
||||
error (_("Cannot find thread-local storage for %s, "
|
||||
"executable file %s:\n%s"),
|
||||
target_pid_to_str (ptid),
|
||||
objfile->name, ex.message);
|
||||
break;
|
||||
default:
|
||||
throw_exception (ex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* It wouldn't be wrong here to try a gdbarch method, too; finding
|
||||
TLS is an ABI-specific thing. But we don't do that yet. */
|
||||
else
|
||||
error (_("Cannot find thread-local variables on this target"));
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
#undef MIN
|
||||
#define MIN(A, B) (((A) <= (B)) ? (A) : (B))
|
||||
|
||||
|
@ -1227,6 +1227,9 @@ extern void target_preopen (int);
|
||||
|
||||
extern void pop_target (void);
|
||||
|
||||
extern CORE_ADDR target_translate_tls_address (struct objfile *objfile,
|
||||
CORE_ADDR offset);
|
||||
|
||||
/* Struct section_table maps address ranges to file sections. It is
|
||||
mostly used with BFD files, but can be used without (e.g. for handling
|
||||
raw disks, or files not in formats handled by BFD). */
|
||||
|
@ -1,3 +1,7 @@
|
||||
2006-10-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* gdb.threads/tls-nodebug.c, gdb.threads/tls-nodebug.exp: New test.
|
||||
|
||||
2006-10-09 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
PR c++/2116
|
||||
|
10
gdb/testsuite/gdb.threads/tls-nodebug.c
Normal file
10
gdb/testsuite/gdb.threads/tls-nodebug.c
Normal file
@ -0,0 +1,10 @@
|
||||
/* Test accessing TLS based variable without any debug info compiled. */
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
__thread int thread_local = 42;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
52
gdb/testsuite/gdb.threads/tls-nodebug.exp
Normal file
52
gdb/testsuite/gdb.threads/tls-nodebug.exp
Normal file
@ -0,0 +1,52 @@
|
||||
# tls.exp -- Expect script to test thread-local storage without debuginfo
|
||||
# Copyright (C) 2006 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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# bug-gdb@prep.ai.mit.edu
|
||||
|
||||
set testfile tls-nodebug
|
||||
set srcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
|
||||
if [istarget "*-*-linux"] then {
|
||||
set target_cflags "-D_MIT_POSIX_THREADS"
|
||||
} else {
|
||||
set target_cflags ""
|
||||
}
|
||||
|
||||
if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable []] != "" } {
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
|
||||
gdb_load ${binfile}
|
||||
if ![runto_main] then {
|
||||
fail "Can't run to main"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Formerly: Cannot access memory at address 0x0
|
||||
gdb_test "p thread_local" "= 42" "thread local storage"
|
||||
|
||||
# Done!
|
||||
#
|
||||
gdb_exit
|
||||
|
||||
return 0
|
Loading…
x
Reference in New Issue
Block a user