From ba67a7996c0a671c34186ae6827e761a7ab6b763 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Thu, 21 Sep 2006 13:07:53 +0000 Subject: [PATCH] - Fix crash on C++ symbol failing to be demangled (BZ 206813). - Fix attach to stopped process, supersede `gdb-6.3-attach-stop-20051011.patch'. - Fix TLS symbols resolving for objects with separate .debug file (-debuginfo). - Fix TLS symbols resolving for shared libraries with a relative pathname. - Support TLS symbols (+`errno' suggestion if no pthread is found) (BZ 185337). --- gdb-6.5-attach-stop.patch | 289 ++++++ ...337-resolve-tls-without-debuginfo-v2.patch | 825 ++++++++++++++++++ gdb-6.5-sharedlibrary-path.patch | 304 +++++++ gdb-6.5-tls-of-separate-debuginfo.patch | 24 + gdb.spec | 36 +- 5 files changed, 1473 insertions(+), 5 deletions(-) create mode 100644 gdb-6.5-attach-stop.patch create mode 100644 gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch create mode 100644 gdb-6.5-sharedlibrary-path.patch create mode 100644 gdb-6.5-tls-of-separate-debuginfo.patch diff --git a/gdb-6.5-attach-stop.patch b/gdb-6.5-attach-stop.patch new file mode 100644 index 0000000..bce0b4c --- /dev/null +++ b/gdb-6.5-attach-stop.patch @@ -0,0 +1,289 @@ +sleep 1h& pid=$!; kill -STOP $pid; gdb sleep $pid + -> +Attaching to program: /bin/sleep, process 20768 +../../gdb/linux-nat.c:1057: internal-error: linux_nat_attach: Assertion `pid == GET_PID (inferior_ptid) && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP' failed. + +Specific to Red Hat kernels, kernel.org kernels lockup on gdb "attach". + + +2006-09-17 Jan Kratochvil + + * gdb-6.5/gdb/linux-nat.c (linux_nat_attach): Handle already stopped + processes. + +2006-09-17 Jeff Johnston + Jan Kratochvil + + * gdb.base/attachstop.exp, gdb.base/attachstop.c: New files, + test attaching to already stopped processes. + + +Index: gdb-6.5/gdb/linux-nat.c +=================================================================== +RCS file: /cvs/src/src/gdb/linux-nat.c,v +retrieving revision 1.50 +diff -u -p -r1.50 linux-nat.c +--- gdb-6.5-orig/gdb/linux-nat.c 16 Sep 2006 09:48:12 -0000 1.50 ++++ gdb-6.5/gdb/linux-nat.c 17 Sep 2006 21:50:32 -0000 +@@ -1022,13 +1022,16 @@ linux_nat_attach (char *args, int from_t + lp->cloned = 1; + } + +- gdb_assert (pid == GET_PID (inferior_ptid) +- && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP); ++ /* Do not check `WSTOPSIG (status) == SIGSTOP' as the status may be ++ arbitrary - depending on the signal that stopped the processes. ++ If the process was running we get SIGSTOP, if it was already stopped ++ by SIGSTOP we get 0. The value gets used for `PTRACE_CONT'. */ ++ gdb_assert (pid == GET_PID (inferior_ptid) && WIFSTOPPED (status)); + + lp->stopped = 1; + +- /* Fake the SIGSTOP that core GDB expects. */ +- lp->status = W_STOPCODE (SIGSTOP); ++ /* Provide the stop status that core GDB expects. */ ++ lp->status = status; + lp->resumed = 1; + if (debug_linux_nat) + { +Index: gdb-6.5/gdb/testsuite/gdb.base/attachstop.c +=================================================================== +RCS file: gdb-6.5/gdb/testsuite/gdb.base/attachstop.c +diff -N gdb-6.5/gdb/testsuite/gdb.base/attachstop.c +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ gdb-6.5/gdb/testsuite/gdb.base/attachstop.c 17 Sep 2006 21:50:32 -0000 +@@ -0,0 +1,29 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2005 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. */ ++ ++/* This program is intended to be started outside of gdb, then ++ manually stopped via a signal. */ ++ ++#include ++ ++int main () ++{ ++ sleep (10000); /* Ridiculous time, but we will eventually kill it. */ ++ sleep (10000); /* Second sleep. */ ++ return 0; ++} +Index: gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp +=================================================================== +RCS file: gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp +diff -N gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp 17 Sep 2006 21:50:32 -0000 +@@ -0,0 +1,198 @@ ++# Copyright 2005-2006 ++ ++# 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. ++ ++# This test was created by modifying attach.exp. ++# This file was created by Jeff Johnston . ++# This file was updated by Jan Kratochvil . ++ ++if $tracelevel then { ++ strace $tracelevel ++} ++ ++set prms_id 0 ++set bug_id 0 ++ ++# This test only works on Linux ++if { ![istarget "*-*-linux-gnu*"] } { ++ return 0 ++} ++ ++set testfile "attachstop" ++set srcfile ${testfile}.c ++set binfile ${objdir}/${subdir}/${testfile} ++set escapedbinfile [string_to_regexp ${objdir}/${subdir}/${testfile}] ++ ++#execute_anywhere "rm -f ${binfile}" ++remote_exec build "rm -f ${binfile}" ++# For debugging this test ++# ++#log_user 1 ++ ++# build the test case ++# ++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { ++ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." ++} ++ ++if [get_compiler_info ${binfile}] { ++ return -1 ++} ++ ++# Start the program running and then wait for a bit, to be sure ++# that it can be attached to. ++ ++set testpid [eval exec $binfile &] ++exec sleep 2 ++ ++# Stop the program ++remote_exec build "kill -s STOP ${testpid}" ++ ++# Start with clean gdb ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binfile} ++ ++# Verify that we can attach to the process by first giving its ++# executable name via the file command, and using attach with the ++# process ID. ++ ++set test "set file, before attach1 to stopped process" ++gdb_test_multiple "file $binfile" "$test" { ++ -re "Load new symbol table from.*y or n. $" { ++ gdb_test "y" "Reading symbols from $escapedbinfile\.\.\.*done." \ ++ "$test (re-read)" ++ } ++ -re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $" { ++ pass "$test" ++ } ++} ++ ++set test "attach1 to stopped, after setting file" ++gdb_test_multiple "attach $testpid" "$test" { ++ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" { ++ pass "$test" ++ } ++} ++ ++gdb_test "bt" ".*sleep.*main.*" "attach1 to stopped bt" ++ ++# Exit and detach the process. ++ ++gdb_exit ++ ++set fileid [open /proc/${testpid}/status r]; ++gets $fileid line1; ++gets $fileid line2; ++close $fileid; ++ ++set test "attach1, exit leaves process stopped" ++if {[string match "*(stopped)*" $line2]} { ++ pass $test ++} else { ++ fail $test ++} ++ ++# At this point, the process should still be stopped ++ ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binfile} ++ ++# Verify that we can attach to the process just by giving the ++# process ID. ++ ++set test "attach2 to stopped, after setting file" ++gdb_test_multiple "attach $testpid" "$test" { ++ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" { ++ pass "$test" ++ } ++} ++ ++gdb_test "bt" ".*sleep.*main.*" "attach2 to stopped bt" ++gdb_breakpoint [gdb_get_line_number "Second sleep"] ++set test "attach2 continue" ++send_gdb "continue\n" ++gdb_expect { ++ -re "Continuing" ++ { pass "continue ($test)" } ++ timeout ++ { fail "continue ($test) (timeout)" } ++} ++ ++# For this to work we must be sure to consume the "Continuing." ++# message first, or GDB's signal handler may not be in place. ++after 1000 {send_gdb "\003"} ++set test "attach2 stop unbreakable interrupt" ++gdb_expect 4 { ++ -re "Program received signal SIGINT.*$gdb_prompt $" ++ { ++ fail "$test (broke into)" ++ } ++ -re "Breakpoint \[0-9\].*$srcfile.*$gdb_prompt $" ++ { ++ fail "$test (broke into)" ++ } ++ timeout ++ { ++ pass $test ++ } ++} ++ ++# Continue the program ++remote_exec build "kill -s CONT ${testpid}" ++ ++# Already sent before: after 1000 {send_gdb "\003"} ++set test "attach2 stop by interrupt" ++gdb_expect { ++ -re "Program received signal SIGINT.*$gdb_prompt $" ++ { ++ pass $test ++ } ++ -re "Breakpoint \[0-9\].*$srcfile.*$gdb_prompt $" ++ { ++ pass $test ++ } ++ timeout ++ { ++ fail "$test (timeout)" ++ } ++} ++ ++gdb_exit ++ ++# At this point, the process should be sleeping ++ ++set fileid2 [open /proc/${testpid}/status r]; ++gets $fileid2 line1; ++gets $fileid2 line2; ++close $fileid2; ++ ++set test "attach2, exit leaves process sleeping" ++if {[string match "*(sleeping)*" $line2]} { ++ pass $test ++} else { ++ fail $test ++} ++ ++# Make sure we don't leave a process around to confuse ++# the next test run (and prevent the compile by keeping ++# the text file busy), in case the "set should_exit" didn't ++# work. ++ ++remote_exec build "kill -9 ${testpid}" ++ ++return 0 diff --git a/gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch b/gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch new file mode 100644 index 0000000..05387ad --- /dev/null +++ b/gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch @@ -0,0 +1,825 @@ +https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=185337 + + +currently for trivia nonthreaded helloworld with no debug info up to -ggdb2 you +will get: + (gdb) p errno + Cannot access memory at address 0x8 + +* with -ggdb3 "errno" gets resolved as _macro_ and the resulting + "(*__errno_location ())" expression is always fine. + +* with -ggdb2 and less "errno" in fact does not exist anywhere as it was + compiled to "(*__errno_location ())" and the macro definition is not present. + Unfortunately gdb will find the TLS symbol and it will try to access it but + as the program has been compiled without -lpthread the TLS base register + (%gs on i386) is not setup and it will result in: + Cannot access memory at address 0x8 + +IMO the right way is to ignore TLS symbols for inferiors without activated +threading. Patch attached. + +Also attached suggestion patch how to deal with the most common "errno" symbol +for the most common under-ggdb3 compiled programs. + + +2006-08-25 Jan Kratochvil + + * dwarf2loc.c (dwarf_expr_tls_address): Code moved out to + `target_translate_tls_address'. + * target.c (target_translate_tls_address): Moved here. + Provided warnings for TLS `errno' on non-TLS targets. + * target.h (target_translate_tls_address): Moved here. + * eval.c (evaluate_subexp_standard): New `UNOP_MEMVAL_TLS'. + * expprint.c (print_subexp_standard): New `UNOP_MEMVAL_TLS'. + (op_name_standard): New `UNOP_MEMVAL_TLS'. + (dump_subexp_body_standard): New `UNOP_MEMVAL_TLS'. + * expression.h (enum exp_opcode): New `UNOP_MEMVAL_TLS'. + (union exp_element): New `objfile' type. + * parse.c (write_exp_elt_objfile): New `objfile' setter. + (write_exp_msymbol): Support new `UNOP_MEMVAL_TLS'. + (msym_text_tls_symbol_type, msym_data_tls_symbol_type, + msym_unknown_tls_symbol_type, build_parse): New TLS types. + (operator_length_standard): New `UNOP_MEMVAL_TLS'. + * parser-defs.h (write_exp_elt_objfile): New `objfile' setter. + * valops.c (value_at_lazy): Pass control to `value_at_lazy_tls'. + (value_at_lazy_tls): Provide TLS `struct objfile *' storage. + (value_fetch_lazy): Resolve TLS `struct objfile *' storage. + (value_assign): Resolve TLS `struct objfile *' storage. + * value.c (struct value, allocate_value, value_tls_objfile, + set_value_tls_objfile): Provide TLS `struct objfile *' storage. + * value.h (value_tls_objfile, set_value_tls_objfile, + value_at_lazy_tls): Provide TLS `struct objfile *' storage. + * Makefile.in: Updated dependencies. + +2006-08-25 Jan Kratochvil + + * gdb.threads/tls-nodebug.c: New file, test TLS symbols on gcc -s. + * gdb.threads/tls-nodebug.exp: New file, test TLS symbols on gcc -s. + + +Index: gdb-6.5/gdb/Makefile.in +=================================================================== +RCS file: /cvs/src/src/gdb/Makefile.in,v +retrieving revision 1.840 +diff -u -p -r1.840 gdb-6.5/gdb/Makefile.in +--- gdb-6.5.org/gdb/Makefile.in 22 Aug 2006 19:08:31 -0000 1.840 ++++ gdb-6.5/gdb/Makefile.in 25 Aug 2006 19:55:35 -0000 +@@ -1977,7 +1977,7 @@ exec.o: exec.c $(defs_h) $(frame_h) $(in + $(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) +@@ -2422,7 +2422,7 @@ osabi.o: osabi.c $(defs_h) $(gdb_assert_ + 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) +@@ -2750,7 +2750,8 @@ symtab.o: symtab.c $(defs_h) $(symtab_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) + thread.o: thread.c $(defs_h) $(symtab_h) $(frame_h) $(inferior_h) \ + $(environ_h) $(value_h) $(target_h) $(gdbthread_h) $(exceptions_h) \ + $(command_h) $(gdbcmd_h) $(regcache_h) $(gdb_h) $(gdb_string_h) \ +Index: gdb-6.5/gdb/dwarf2loc.c +=================================================================== +RCS file: /cvs/src/src/gdb/dwarf2loc.c,v +retrieving revision 1.33 +diff -u -p -r1.33 gdb-6.5/gdb/dwarf2loc.c +--- gdb-6.5.org/gdb/dwarf2loc.c 17 Dec 2005 22:33:59 -0000 1.33 ++++ gdb-6.5/gdb/dwarf2loc.c 25 Aug 2006 19:55:36 -0000 +@@ -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 +Index: gdb-6.5/gdb/eval.c +=================================================================== +RCS file: /cvs/src/src/gdb/eval.c,v +retrieving revision 1.63 +diff -u -p -r1.63 gdb-6.5/gdb/eval.c +--- gdb-6.5.org/gdb/eval.c 25 Jul 2006 04:24:50 -0000 1.63 ++++ gdb-6.5/gdb/eval.c 25 Aug 2006 19:55:38 -0000 +@@ -2019,6 +2019,18 @@ evaluate_subexp_standard (struct type *e + 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 ++ return value_at_lazy_tls (exp->elts[pc + 2].type, ++ value_as_address (arg1), ++ exp->elts[pc + 1].objfile); ++ + case UNOP_PREINCREMENT: + arg1 = evaluate_subexp (expect_type, exp, pos, noside); + if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) +Index: gdb-6.5/gdb/expprint.c +=================================================================== +RCS file: /cvs/src/src/gdb/expprint.c,v +retrieving revision 1.24 +diff -u -p -r1.24 gdb-6.5/gdb/expprint.c +--- gdb-6.5.org/gdb/expprint.c 7 Aug 2006 03:30:54 -0000 1.24 ++++ gdb-6.5/gdb/expprint.c 25 Aug 2006 19:55:39 -0000 +@@ -31,6 +31,7 @@ + #include "target.h" + #include "gdb_string.h" + #include "block.h" ++#include "objfiles.h" + + #ifdef HAVE_CTYPE_H + #include +@@ -414,6 +415,33 @@ print_subexp_standard (struct expression + fputs_filtered (")", stream); + return; + ++ case UNOP_MEMVAL_TLS: ++ (*pos) += 3; ++ if ((int) prec > (int) PREC_PREFIX) ++ fputs_filtered ("(", stream); ++ if (TYPE_CODE (exp->elts[pc + 2].type) == TYPE_CODE_FUNC && ++ exp->elts[pc + 4].opcode == OP_LONG) ++ { ++ /* We have a minimal symbol fn, probably. It's encoded ++ as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address). ++ Swallow the OP_LONG (including both its opcodes); ignore ++ its type; print the value in the type of the MEMVAL. */ ++ (*pos) += 4; ++ val = value_at_lazy (exp->elts[pc + 2].type, ++ (CORE_ADDR) exp->elts[pc + 6].longconst); ++ value_print (val, stream, 0, Val_no_prettyprint); ++ } ++ else ++ { ++ 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 +722,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 +1029,16 @@ dump_subexp_body_standard (struct expres + 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); +Index: gdb-6.5/gdb/expression.h +=================================================================== +RCS file: /cvs/src/src/gdb/expression.h,v +retrieving revision 1.18 +diff -u -p -r1.18 gdb-6.5/gdb/expression.h +--- gdb-6.5.org/gdb/expression.h 17 Dec 2005 22:33:59 -0000 1.18 ++++ gdb-6.5/gdb/expression.h 25 Aug 2006 19:55:40 -0000 +@@ -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 +Index: gdb-6.5/gdb/parse.c +=================================================================== +RCS file: /cvs/src/src/gdb/parse.c,v +retrieving revision 1.53 +diff -u -p -r1.53 gdb-6.5/gdb/parse.c +--- gdb-6.5.org/gdb/parse.c 6 Jul 2006 14:00:48 -0000 1.53 ++++ gdb-6.5/gdb/parse.c 25 Aug 2006 19:55:41 -0000 +@@ -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. */ +@@ -219,6 +220,15 @@ write_exp_elt_block (struct block *b) + } + + 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) + { + union exp_element tmp; +@@ -378,6 +388,9 @@ 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_text_tls_symbol_type; ++static struct type *msym_data_tls_symbol_type; ++static struct type *msym_unknown_tls_symbol_type; + + void + write_exp_msymbol (struct minimal_symbol *msymbol, +@@ -385,6 +398,8 @@ write_exp_msymbol (struct minimal_symbol + struct type *data_symbol_type) + { + CORE_ADDR addr; ++ int tls = SYMBOL_BFD_SECTION (msymbol)->flags & SEC_THREAD_LOCAL; ++ enum exp_opcode opcode = tls ? UNOP_MEMVAL_TLS : UNOP_MEMVAL; + + write_exp_elt_opcode (OP_LONG); + /* Let's make the type big enough to hold a 64-bit address. */ +@@ -397,27 +412,49 @@ write_exp_msymbol (struct minimal_symbol + + write_exp_elt_opcode (OP_LONG); + +- write_exp_elt_opcode (UNOP_MEMVAL); ++ write_exp_elt_opcode (opcode); ++ ++ if (opcode == UNOP_MEMVAL_TLS) ++ { ++ bfd *bfd = SYMBOL_BFD_SECTION (msymbol)->owner; ++ struct objfile *ofp; ++ ++ ALL_OBJFILES (ofp) ++ if (ofp->obfd == bfd) ++ break; ++ write_exp_elt_objfile (ofp); ++ } ++ + switch (msymbol->type) + { + case mst_text: + case mst_file_text: + case mst_solib_trampoline: +- write_exp_elt_type (msym_text_symbol_type); ++ if (tls) ++ write_exp_elt_type (msym_text_tls_symbol_type); ++ else ++ write_exp_elt_type (msym_text_symbol_type); + break; + + case mst_data: + case mst_file_data: + case mst_bss: + case mst_file_bss: +- write_exp_elt_type (msym_data_symbol_type); ++ if (tls) ++ write_exp_elt_type (msym_data_tls_symbol_type); ++ else ++ write_exp_elt_type (msym_data_symbol_type); + break; + + default: +- write_exp_elt_type (msym_unknown_symbol_type); ++ if (tls) ++ write_exp_elt_type (msym_unknown_tls_symbol_type); ++ else ++ write_exp_elt_type (msym_unknown_symbol_type); + break; + } +- write_exp_elt_opcode (UNOP_MEMVAL); ++ ++ write_exp_elt_opcode (opcode); + } + + /* Recognize tokens that start with '$'. These include: +@@ -904,6 +941,11 @@ operator_length_standard (struct express + args = 1; + break; + ++ case UNOP_MEMVAL_TLS: ++ oplen = 4; ++ args = 1; ++ break; ++ + case UNOP_ABS: + case UNOP_CAP: + case UNOP_CHR: +@@ -1341,6 +1383,17 @@ build_parse (void) + init_type (TYPE_CODE_INT, 1, 0, + "", + NULL); ++ ++ msym_text_tls_symbol_type = ++ init_type (TYPE_CODE_FUNC, 1, 0, "", NULL); ++ TYPE_TARGET_TYPE (msym_text_tls_symbol_type) = builtin_type_int; ++ msym_data_tls_symbol_type = ++ init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0, ++ "", NULL); ++ msym_unknown_tls_symbol_type = ++ init_type (TYPE_CODE_INT, 1, 0, ++ "", ++ NULL); + } + + /* This function avoids direct calls to fprintf +Index: gdb-6.5/gdb/parser-defs.h +=================================================================== +RCS file: /cvs/src/src/gdb/parser-defs.h,v +retrieving revision 1.20 +diff -u -p -r1.20 gdb-6.5/gdb/parser-defs.h +--- gdb-6.5.org/gdb/parser-defs.h 17 Dec 2005 22:34:01 -0000 1.20 ++++ gdb-6.5/gdb/parser-defs.h 25 Aug 2006 19:55:41 -0000 +@@ -131,6 +131,8 @@ extern void write_exp_bitstring (struct + + 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 *); + +--- gdb-6.5.org/gdb/target.c 16 Aug 2006 18:31:03 -0000 1.124 ++++ gdb-6.5/gdb/target.c 25 Aug 2006 19:55:43 -0000 +@@ -40,6 +40,7 @@ + #include "gdb_assert.h" + #include "gdbcore.h" + #include "observer.h" ++#include "exceptions.h" + + static void target_info (char *, int); + +@@ -755,6 +756,103 @@ 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 ++ { ++ struct minimal_symbol *msymbol; ++ ++ msymbol = lookup_minimal_symbol ("errno", NULL, NULL); ++ if (msymbol != NULL ++ && SYMBOL_VALUE_ADDRESS (msymbol) == offset ++ && SYMBOL_BFD_SECTION (msymbol)->owner == objfile->obfd) ++ error (_("TLS symbol `errno' not resolved for non-TLS program." ++ " You should use symbol \"(*__errno_location ())\" or" ++ " compile the program with `gcc -ggdb3' or `gcc -pthread'.")); ++ error (_("Cannot find thread-local variables on this target")); ++ } ++ ++ return addr; ++} ++ + #undef MIN + #define MIN(A, B) (((A) <= (B)) ? (A) : (B)) + +Index: gdb-6.5/gdb/target.h +=================================================================== +RCS file: /cvs/src/src/gdb/target.h,v +retrieving revision 1.87 +diff -u -p -r1.87 gdb-6.5/gdb/target.h +--- gdb-6.5.org/gdb/target.h 15 Aug 2006 18:46:25 -0000 1.87 ++++ gdb-6.5/gdb/target.h 25 Aug 2006 19:55:44 -0000 +@@ -1131,6 +1131,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). */ +Index: gdb-6.5/gdb/valops.c +=================================================================== +RCS file: /cvs/src/src/gdb/valops.c,v +retrieving revision 1.164 +diff -u -p -r1.164 gdb-6.5/gdb/valops.c +--- gdb-6.5.org/gdb/valops.c 13 Jul 2006 04:31:42 -0000 1.164 ++++ gdb-6.5/gdb/valops.c 25 Aug 2006 19:55:46 -0000 +@@ -501,7 +501,8 @@ value_at (struct type *type, CORE_ADDR a + /* Return a lazy value with type TYPE located at ADDR (cf. value_at). */ + + struct value * +-value_at_lazy (struct type *type, CORE_ADDR addr) ++value_at_lazy_tls (struct type *type, CORE_ADDR addr, ++ struct objfile *tls_objfile) + { + struct value *val; + +@@ -512,11 +513,19 @@ value_at_lazy (struct type *type, CORE_A + + VALUE_LVAL (val) = lval_memory; + VALUE_ADDRESS (val) = addr; ++ if (tls_objfile != NULL) ++ set_value_tls_objfile (val, tls_objfile); + set_value_lazy (val, 1); + + return val; + } + ++struct value * ++value_at_lazy (struct type *type, CORE_ADDR addr) ++{ ++ return value_at_lazy_tls (type, addr, NULL); ++} ++ + /* Called only from the value_contents and value_contents_all() + macros, if the current data for a variable needs to be loaded into + value_contents(VAL). Fetches the data from the user's process, and +@@ -538,7 +547,17 @@ value_fetch_lazy (struct value *val) + + struct type *type = value_type (val); + if (length) +- read_memory (addr, value_contents_all_raw (val), length); ++ { ++ struct objfile *tls_objfile = value_tls_objfile (val); ++ ++ if (tls_objfile != NULL) ++ { ++ /* `target_translate_tls_address' uses `inferior_ptid'. */ ++ addr = target_translate_tls_address (tls_objfile, addr); ++ } ++ ++ read_memory (addr, value_contents_all_raw (val), length); ++ } + + set_value_lazy (val, 0); + return 0; +@@ -596,6 +615,7 @@ value_assign (struct value *toval, struc + CORE_ADDR changed_addr; + int changed_len; + gdb_byte buffer[sizeof (LONGEST)]; ++ struct objfile *tls_objfile = value_tls_objfile (toval); + + if (value_bitsize (toval)) + { +@@ -624,6 +644,13 @@ value_assign (struct value *toval, struc + dest_buffer = value_contents (fromval); + } + ++ if (tls_objfile != NULL) ++ { ++ /* `target_translate_tls_address' uses `inferior_ptid'. */ ++ changed_addr = target_translate_tls_address (tls_objfile, ++ changed_addr); ++ } ++ + write_memory (changed_addr, dest_buffer, changed_len); + if (deprecated_memory_changed_hook) + deprecated_memory_changed_hook (changed_addr, changed_len); +Index: gdb-6.5/gdb/value.c +=================================================================== +RCS file: /cvs/src/src/gdb/value.c,v +retrieving revision 1.36 +diff -u -p -r1.36 gdb-6.5/gdb/value.c +--- gdb-6.5.org/gdb/value.c 31 Mar 2006 10:36:18 -0000 1.36 ++++ gdb-6.5/gdb/value.c 25 Aug 2006 19:55:47 -0000 +@@ -158,6 +158,9 @@ struct value + actually exist in the program. */ + char optimized_out; + ++ /* TLS owner. */ ++ struct objfile *tls_objfile; ++ + /* Actual contents of the value. For use of this value; setting it + uses the stuff above. Not valid if lazy is nonzero. Target + byte-order. We force it to be aligned properly for any possible +@@ -230,6 +233,7 @@ allocate_value (struct type *type) + VALUE_REGNUM (val) = -1; + val->lazy = 0; + val->optimized_out = 0; ++ val->tls_objfile = NULL; + val->embedded_offset = 0; + val->pointed_to_offset = 0; + val->modifiable = 1; +@@ -344,6 +348,18 @@ set_value_lazy (struct value *value, int + value->lazy = val; + } + ++struct objfile * ++value_tls_objfile (struct value *value) ++{ ++ return value->tls_objfile; ++} ++ ++void ++set_value_tls_objfile (struct value *value, struct objfile *tls_objfile) ++{ ++ value->tls_objfile = tls_objfile; ++} ++ + const gdb_byte * + value_contents (struct value *value) + { +Index: gdb-6.5/gdb/value.h +=================================================================== +RCS file: /cvs/src/src/gdb/value.h,v +retrieving revision 1.92 +diff -u -p -r1.92 gdb-6.5/gdb/value.h +--- gdb-6.5.org/gdb/value.h 13 Jul 2006 04:31:42 -0000 1.92 ++++ gdb-6.5/gdb/value.h 25 Aug 2006 19:55:48 -0000 +@@ -154,6 +154,10 @@ extern void set_value_embedded_offset (s + extern int value_lazy (struct value *); + extern void set_value_lazy (struct value *value, int val); + ++extern struct objfile *value_tls_objfile (struct value *value); ++extern void set_value_tls_objfile (struct value *value, ++ struct objfile *tls_objfile); ++ + /* value_contents() and value_contents_raw() both return the address + of the gdb buffer used to hold a copy of the contents of the lval. + value_contents() is used when the contents of the buffer are needed +@@ -277,6 +281,8 @@ extern struct value *value_from_double ( + extern struct value *value_from_string (char *string); + + extern struct value *value_at (struct type *type, CORE_ADDR addr); ++extern struct value *value_at_lazy_tls (struct type *type, CORE_ADDR addr, ++ struct objfile *tls_objfile); + extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr); + + extern struct value *value_from_register (struct type *type, int regnum, +Index: gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.c +=================================================================== +RCS file: gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.c +diff -N gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.c +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.c 25 Aug 2006 19:55:48 -0000 +@@ -0,0 +1,8 @@ ++/* Test accessing TLS based variable without any debug info compiled. */ ++ ++__thread int thread_local = 42; ++ ++int main(void) ++{ ++ return 0; ++} +Index: gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.exp +=================================================================== +RCS file: gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.exp +diff -N gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.exp +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ gdb-6.5/gdb/testsuite/gdb.threads/tls-nodebug.exp 25 Aug 2006 19:55:49 -0000 +@@ -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 $options] != "" } { ++ 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 diff --git a/gdb-6.5-sharedlibrary-path.patch b/gdb-6.5-sharedlibrary-path.patch new file mode 100644 index 0000000..fa8ce3d --- /dev/null +++ b/gdb-6.5-sharedlibrary-path.patch @@ -0,0 +1,304 @@ +If you provided some relative path to the shared library, such as with + export LD_LIBRARY_PATH=. +then gdb would fail to match the shared library name during the TLS lookup. + + +The testsuite needs `gdb-6.3-bz146810-solib_absolute_prefix_is_empty.patch'. +The testsuite needs `gdb-6.5-tls-of-separate-debuginfo.patch'. + + +2006-09-01 Jan Kratochvil + + * solib-svr4.c (svr4_fetch_objfile_link_map): Match even absolute + requested pathnames to the internal loaded relative pathnames. + + +Index: gdb-6.5/gdb/solib-svr4.c +=================================================================== +RCS file: /cvs/src/src/gdb/solib-svr4.c,v +retrieving revision 1.58 +diff -u -p -r1.58 gdb-6.5/gdb/solib-svr4.c +--- gdb-6.5.orig/gdb/solib-svr4.c 18 May 2006 20:38:56 -0000 1.58 ++++ gdb-6.5/gdb/solib-svr4.c 1 Sep 2006 18:47:10 -0000 +@@ -774,62 +774,81 @@ CORE_ADDR + svr4_fetch_objfile_link_map (struct objfile *objfile) + { + CORE_ADDR lm; ++ int resolve; + + if ((debug_base = locate_base ()) == 0) + return 0; /* failed somehow... */ + +- /* Position ourselves on the first link map. */ +- lm = solib_svr4_r_map (); +- while (lm) ++ for (resolve = 0; resolve <= 1; resolve++) + { +- /* Get info on the layout of the r_debug and link_map structures. */ +- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); +- int errcode; +- char *buffer; +- struct lm_info objfile_lm_info; +- struct cleanup *old_chain; +- CORE_ADDR name_address; +- gdb_byte *l_name_buf = xmalloc (lmo->l_name_size); +- old_chain = make_cleanup (xfree, l_name_buf); +- +- /* Set up the buffer to contain the portion of the link_map +- structure that gdb cares about. Note that this is not the +- whole link_map structure. */ +- objfile_lm_info.lm = xzalloc (lmo->link_map_size); +- make_cleanup (xfree, objfile_lm_info.lm); +- +- /* Read the link map into our internal structure. */ +- read_memory (lm, objfile_lm_info.lm, lmo->link_map_size); +- +- /* Read address of name from target memory to GDB. */ +- read_memory (lm + lmo->l_name_offset, l_name_buf, lmo->l_name_size); +- +- /* Extract this object's name. Assume that the address is +- unsigned. */ +- name_address = extract_unsigned_integer (l_name_buf, lmo->l_name_size); +- target_read_string (name_address, &buffer, +- SO_NAME_MAX_PATH_SIZE - 1, &errcode); +- make_cleanup (xfree, buffer); +- if (errcode != 0) +- warning (_("Can't read pathname for load map: %s."), +- safe_strerror (errcode)); +- else +- { +- /* Is this the linkmap for the file we want? */ +- /* If the file is not a shared library and has no name, +- we are sure it is the main executable, so we return that. */ +- if ((buffer && strcmp (buffer, objfile->name) == 0) +- || (!(objfile->flags & OBJF_SHARED) && (strcmp (buffer, "") == 0))) +- { +- do_cleanups (old_chain); +- return lm; +- } +- } +- /* Not the file we wanted, continue checking. Assume that the +- address is unsigned. */ +- lm = extract_unsigned_integer (objfile_lm_info.lm + lmo->l_next_offset, +- lmo->l_next_size); +- do_cleanups (old_chain); ++ /* Position ourselves on the first link map. */ ++ lm = solib_svr4_r_map (); ++ while (lm) ++ { ++ /* Get info on the layout of the r_debug and link_map structures. */ ++ struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); ++ int errcode; ++ char *buffer; ++ struct lm_info objfile_lm_info; ++ struct cleanup *old_chain; ++ CORE_ADDR name_address; ++ gdb_byte *l_name_buf = xmalloc (lmo->l_name_size); ++ old_chain = make_cleanup (xfree, l_name_buf); ++ ++ /* Set up the buffer to contain the portion of the link_map ++ structure that gdb cares about. Note that this is not the ++ whole link_map structure. */ ++ objfile_lm_info.lm = xzalloc (lmo->link_map_size); ++ make_cleanup (xfree, objfile_lm_info.lm); ++ ++ /* Read the link map into our internal structure. */ ++ read_memory (lm, objfile_lm_info.lm, lmo->link_map_size); ++ ++ /* Read address of name from target memory to GDB. */ ++ read_memory (lm + lmo->l_name_offset, l_name_buf, lmo->l_name_size); ++ ++ /* Extract this object's name. Assume that the address is ++ unsigned. */ ++ name_address = extract_unsigned_integer (l_name_buf, lmo->l_name_size); ++ target_read_string (name_address, &buffer, ++ SO_NAME_MAX_PATH_SIZE - 1, &errcode); ++ make_cleanup (xfree, buffer); ++ if (errcode != 0) ++ warning (_("Can't read pathname for load map: %s."), ++ safe_strerror (errcode)); ++ else ++ { ++ /* solib_svr4_r_map() may contain relative pathnames while ++ `objfile->name' is absolute. */ ++ if (resolve && buffer && buffer[0] != '/') ++ { ++ char *absolute; ++ int fd; ++ ++ fd = solib_open (buffer, &absolute); ++ if (fd != -1) ++ { ++ make_cleanup (xfree, absolute); ++ buffer = absolute; ++ close (fd); ++ } ++ } ++ /* Is this the linkmap for the file we want? */ ++ /* If the file is not a shared library and has no name, ++ we are sure it is the main executable, so we return that. */ ++ if ((buffer && strcmp (buffer, objfile->name) == 0) ++ || (!(objfile->flags & OBJF_SHARED) && (strcmp (buffer, "") == 0))) ++ { ++ do_cleanups (old_chain); ++ return lm; ++ } ++ } ++ /* Not the file we wanted, continue checking. Assume that the ++ address is unsigned. */ ++ lm = extract_unsigned_integer (objfile_lm_info.lm + lmo->l_next_offset, ++ lmo->l_next_size); ++ do_cleanups (old_chain); ++ } + } + return 0; + } +Index: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-main.c +=================================================================== +RCS file: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-main.c +diff -N gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-main.c +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-main.c 1 Sep 2006 18:47:14 -0000 +@@ -0,0 +1,25 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 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 */ ++ ++int main() ++{ ++ return 0; ++} +Index: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-shared.c +=================================================================== +RCS file: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-shared.c +diff -N gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-shared.c +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug-shared.c 1 Sep 2006 18:47:14 -0000 +@@ -0,0 +1,22 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 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 */ ++ ++__thread int var = 42; +Index: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug.exp +=================================================================== +RCS file: gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug.exp +diff -N gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug.exp +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ gdb-6.5/gdb/testsuite/gdb.threads/tls-sepdebug.exp 1 Sep 2006 18:47:14 -0000 +@@ -0,0 +1,81 @@ ++# Copyright 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. ++ ++if $tracelevel then { ++ strace $tracelevel ++} ++ ++set testfile tls-sepdebug ++set srcmainfile ${testfile}-main.c ++set srcsharedfile ${testfile}-shared.c ++ ++# DO NOT use ${objdir} obsolute reference here as we test relative directories ++# below and the absolute pathnames must not get encoded to the binaries. ++ ++set binmainfile ${testfile}-main ++set binsharedfile ${testfile}-shared.so ++set binshareddebugfile ${testfile}-shared.so.debug ++ ++if { [gdb_compile_shlib "${srcdir}/${subdir}/${srcsharedfile}" "${binsharedfile}" {debug}] != "" } { ++ untested "Couldn't compile test library" ++ return -1 ++} ++ ++# eu-strip(1) works fine but it is a part of `elfutils', not `binutils'. ++if 0 then { ++ remote_exec build "eu-strip -f ${binshareddebugfile} ${binsharedfile}" ++} else { ++ remote_exec build "objcopy --only-keep-debug ${binsharedfile} ${binshareddebugfile}" ++ remote_exec build "objcopy --strip-debug ${binsharedfile}" ++ remote_exec build "objcopy --add-gnu-debuglink=${binshareddebugfile} ${binsharedfile}" ++} ++ ++if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcmainfile}" "${binmainfile}" executable [list debug shlib=${binsharedfile}]] != "" } { ++ untested "Couldn't compile test program" ++ return -1 ++} ++ ++# Get things started. ++ ++# Test also the proper resolving of relative library names to absolute ones. ++# \$PWD is easy - it is the absolute way ++# ${subdir} would fail on "print var" ++ ++foreach ld_library_path { \$PWD ${subdir} } name { absolute relative } { ++ ++ gdb_exit ++ gdb_start ++ ###gdb_reinitialize_dir $srcdir/$subdir ++ ++ gdb_test "set env LD_LIBRARY_PATH=$ld_library_path" \ ++ "" \ ++ "set env LD_LIBRARY_PATH is $name" ++ ++ gdb_load ${binmainfile} ++ ++ # For C programs, "start" should stop in main(). ++ ++ gdb_test "start" \ ++ "main \\(\\) at .*${srcmainfile}.*" \ ++ "start" ++ ++ # Check for: Cannot find shared library `/usr/lib/debug/lib/libc-2.4.90.so.debug' in dynamic linker's load module list ++ # as happens with TLS variables and `separate_debug_objfile_backlink'. ++ ++ gdb_test "print var" \ ++ "\\\$1 = \[0-9\].*" \ ++ "print TLS variable from a shared library with $name-directory separate debug info file" ++} diff --git a/gdb-6.5-tls-of-separate-debuginfo.patch b/gdb-6.5-tls-of-separate-debuginfo.patch new file mode 100644 index 0000000..b838081 --- /dev/null +++ b/gdb-6.5-tls-of-separate-debuginfo.patch @@ -0,0 +1,24 @@ +Dependency on: gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch + + +2006-09-01 Jan Kratochvil + + * target.c (target_translate_tls_address): Fix for separate debuginfo. + + +diff -rup gdb-6.5.orig/gdb/target.c gdb-6.5/gdb/target.c +--- gdb-6.5.orig/gdb/target.c 2006-09-20 17:13:35.000000000 -0400 ++++ gdb-6.5/gdb/target.c 2006-09-20 17:15:53.000000000 -0400 +@@ -769,6 +769,12 @@ target_translate_tls_address (struct obj + ptid_t ptid = inferior_ptid; + volatile struct gdb_exception ex; + ++ /* Resolve: Cannot find shared library ++ `/usr/lib/debug/lib/lib....so.debug' in dynamic linker's load ++ module list */ ++ if (objfile->separate_debug_objfile_backlink != NULL) ++ objfile = objfile->separate_debug_objfile_backlink; ++ + TRY_CATCH (ex, RETURN_MASK_ALL) + { + CORE_ADDR lm_addr; diff --git a/gdb.spec b/gdb.spec index d502f5d..dd7eb06 100644 --- a/gdb.spec +++ b/gdb.spec @@ -11,7 +11,7 @@ Name: gdb Version: 6.5 # The release always contains a leading reserved number, start it at 0. -Release: 8%{?dist} +Release: 9%{?dist} License: GPL Group: Development/Debuggers @@ -186,10 +186,6 @@ Patch165: gdb-6.3-xfree-20050922.patch # Fix frame pointer for ia64 sigtramp frame Patch166: gdb-6.3-ia64-sigtramp-fp-20050926.patch -# Support gdb attaching to a stopped process -# Appears to be obsolete, not applied. -aoliva -Patch168: gdb-6.3-attach-stop-20051011.patch - # Fix ia64 gdb problem with user-specified SIGILL handling Patch169: gdb-6.3-ia64-sigill-20051115.patch @@ -253,6 +249,24 @@ Patch190: gdb-6.5-dwarf-stack-overflow.patch # Fix gdb printf command argument using "%p" (BZ 205551). Patch191: gdb-6.5-bz205551-printf-p.patch +# Fix crash on C++ symbol failing to be demangled (BZ 206813). +Patch192: gdb-6.5-bz206813-cplusplus-symbol-null.patch + +# Fix attach to stopped process, supersede `gdb-6.3-attach-stop-20051011.patch'. +Patch193: gdb-6.5-attach-stop.patch + +# Support TLS symbols (+`errno' suggestion if no pthread is found) (BZ 185337). +# FIXME: Still to be updated. +Patch194: gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch + +# Fix TLS symbols resolving for objects with separate .debug file (-debuginfo). +Patch195: gdb-6.5-tls-of-separate-debuginfo.patch + +# Fix TLS symbols resolving for shared libraries with a relative pathname. +# The testsuite needs `gdb-6.3-bz146810-solib_absolute_prefix_is_empty.patch'. +# The testsuite needs `gdb-6.5-tls-of-separate-debuginfo.patch'. +Patch196: gdb-6.5-sharedlibrary-path.patch + BuildRequires: ncurses-devel glibc-devel gcc make gzip texinfo dejagnu gettext BuildRequires: flex bison sharutils @@ -355,6 +369,11 @@ and printing their data. %patch189 -p1 %patch190 -p1 %patch191 -p1 +%patch192 -p1 +%patch193 -p1 +%patch194 -p1 +%patch195 -p1 +%patch196 -p1 # Change the version that gets printed at GDB startup, so it is RedHat # specific. @@ -515,6 +534,13 @@ fi # don't include the files in include, they are part of binutils %changelog +* Wed Sep 21 2006 Jan Kratochvil - 6.5-9 +- Fix crash on C++ symbol failing to be demangled (BZ 206813). +- Fix attach to stopped process, supersede `gdb-6.3-attach-stop-20051011.patch'. +- Fix TLS symbols resolving for objects with separate .debug file (-debuginfo). +- Fix TLS symbols resolving for shared libraries with a relative pathname. +- Support TLS symbols (+`errno' suggestion if no pthread is found) (BZ 185337). + * Mon Sep 11 2006 Jan Kratochvil - 6.5-8 - Fix gdb printf command argument using "%p" (BZ 205551).