aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2007-05-07 11:49:05 +0000
committerDaniel Jacobowitz <drow@false.org>2007-05-07 11:49:05 +0000
commitb18be20d0aadff1e7c5b4d161177481aa61b9fc4 (patch)
treeb3807e7e3e98d6155edff77c65a25c93542aee32
parentdda9b909e68c77cae3ad23e67b8acd5809652997 (diff)
downloadbinutils-b18be20d0aadff1e7c5b4d161177481aa61b9fc4.zip
binutils-b18be20d0aadff1e7c5b4d161177481aa61b9fc4.tar.gz
binutils-b18be20d0aadff1e7c5b4d161177481aa61b9fc4.tar.bz2
* Makefile.in (c-lang.o, gnu-v3-abi.o): Update.
* NEWS: Mention improved C++ thunk support. * c-lang.c (cplus_language_defn): Mention cplus_skip_trampoline. * cp-abi.c (cplus_skip_trampoline): New. * cp-abi.h (cplus_skip_trampoline): New prototype. (struct cp_abi_ops): Add skip_trampoline member. * gnu-v3-abi.c (gnuv3_skip_trampoline): New. (init_gnuv3_ops): Set skip_trampoline. * gdb.cp/virtfunc.exp (proc do_tests): Test stepping through a thunk.
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/Makefile.in5
-rw-r--r--gdb/NEWS2
-rw-r--r--gdb/c-lang.c3
-rw-r--r--gdb/cp-abi.c8
-rw-r--r--gdb/cp-abi.h6
-rw-r--r--gdb/gnu-v3-abi.c43
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.cp/virtfunc.exp4
9 files changed, 83 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 815d1da..d059e46 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2007-05-07 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * Makefile.in (c-lang.o, gnu-v3-abi.o): Update.
+ * NEWS: Mention improved C++ thunk support.
+ * c-lang.c (cplus_language_defn): Mention cplus_skip_trampoline.
+ * cp-abi.c (cplus_skip_trampoline): New.
+ * cp-abi.h (cplus_skip_trampoline): New prototype.
+ (struct cp_abi_ops): Add skip_trampoline member.
+ * gnu-v3-abi.c (gnuv3_skip_trampoline): New.
+ (init_gnuv3_ops): Set skip_trampoline.
+
2007-05-06 Daniel Jacobowitz <dan@codesourcery.com>
* rs6000-tdep.c (struct frame_extra_info): Delete.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 1486a98..07da75d 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1862,7 +1862,7 @@ charset.o: charset.c $(defs_h) $(charset_h) $(gdbcmd_h) $(gdb_assert_h) \
c-lang.o: c-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
$(parser_defs_h) $(language_h) $(c_lang_h) $(valprint_h) \
$(macroscope_h) $(gdb_assert_h) $(charset_h) $(gdb_string_h) \
- $(demangle_h) $(cp_support_h)
+ $(demangle_h) $(cp_abi_h) $(cp_support_h)
cli-out.o: cli-out.c $(defs_h) $(ui_out_h) $(cli_out_h) $(gdb_string_h) \
$(gdb_assert_h)
coff-pe-read.o: coff-pe-read.c $(coff_pe_read_h) $(bfd_h) $(defs_h) \
@@ -2043,7 +2043,8 @@ gnu-v2-abi.o: gnu-v2-abi.c $(defs_h) $(gdb_string_h) $(symtab_h) \
$(gdbtypes_h) $(value_h) $(demangle_h) $(cp_abi_h) $(cp_support_h) \
$(gnu_v2_abi_h)
gnu-v3-abi.o: gnu-v3-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(cp_support_h) \
- $(demangle_h) $(valprint_h) $(gdb_assert_h) $(gdb_string_h)
+ $(demangle_h) $(objfiles_h) $(valprint_h) \
+ $(gdb_assert_h) $(gdb_string_h)
go32-nat.o: go32-nat.c $(defs_h) $(inferior_h) $(gdb_wait_h) $(gdbcore_h) \
$(command_h) $(gdbcmd_h) $(floatformat_h) $(buildsym_h) \
$(i387_tdep_h) $(i386_tdep_h) $(value_h) $(regcache_h) \
diff --git a/gdb/NEWS b/gdb/NEWS
index 14ffee1..9ce7e66 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -29,6 +29,8 @@ iWMMXt coprocessor.
ARM Windows CE (mingw32ce) debugging, and GDB Windows CE support
has been rewritten to use the standard GDB remote protocol.
+* GDB can now step into C++ functions which are called through thunks.
+
* New commands
set mem inaccessible-by-default
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index af42188..52b2a36 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -33,6 +33,7 @@
#include "charset.h"
#include "gdb_string.h"
#include "demangle.h"
+#include "cp-abi.h"
#include "cp-support.h"
extern void _initialize_c_language (void);
@@ -642,7 +643,7 @@ const struct language_defn cplus_language_defn =
c_print_type, /* Print a type using appropriate syntax */
c_val_print, /* Print a value using appropriate syntax */
c_value_print, /* Print a top-level value */
- NULL, /* Language specific skip_trampoline */
+ cplus_skip_trampoline, /* Language specific skip_trampoline */
value_of_this, /* value_of_this */
cp_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
cp_lookup_transparent_type, /* lookup_transparent_type */
diff --git a/gdb/cp-abi.c b/gdb/cp-abi.c
index 23b5f9a..7bc1552 100644
--- a/gdb/cp-abi.c
+++ b/gdb/cp-abi.c
@@ -121,6 +121,14 @@ cplus_make_method_ptr (gdb_byte *contents, CORE_ADDR value, int is_virtual)
(*current_cp_abi.make_method_ptr) (contents, value, is_virtual);
}
+CORE_ADDR
+cplus_skip_trampoline (CORE_ADDR stop_pc)
+{
+ if (current_cp_abi.skip_trampoline == NULL)
+ return 0;
+ return (*current_cp_abi.skip_trampoline) (stop_pc);
+}
+
struct value *
cplus_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
{
diff --git a/gdb/cp-abi.h b/gdb/cp-abi.h
index 4ddc121..91d89b3 100644
--- a/gdb/cp-abi.h
+++ b/gdb/cp-abi.h
@@ -170,6 +170,11 @@ struct value *cplus_method_ptr_to_value (struct value **this_p,
void cplus_make_method_ptr (gdb_byte *CONTENTS, CORE_ADDR address,
int is_virtual);
+/* Determine if we are currently in a C++ thunk. If so, get the address
+ of the routine we are thunking to and continue to there instead. */
+
+CORE_ADDR cplus_skip_trampoline (CORE_ADDR stop_pc);
+
struct cp_abi_ops
{
const char *shortname;
@@ -192,6 +197,7 @@ struct cp_abi_ops
int (*method_ptr_size) (void);
void (*make_method_ptr) (gdb_byte *, CORE_ADDR, int);
struct value * (*method_ptr_to_value) (struct value **, struct value *);
+ CORE_ADDR (*skip_trampoline) (CORE_ADDR);
};
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index 54feb77..d3c278c 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -26,6 +26,7 @@
#include "cp-abi.h"
#include "cp-support.h"
#include "demangle.h"
+#include "objfiles.h"
#include "valprint.h"
#include "gdb_assert.h"
@@ -673,6 +674,47 @@ gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
return value_from_pointer (lookup_pointer_type (method_type), ptr_value);
}
+/* Determine if we are currently in a C++ thunk. If so, get the address
+ of the routine we are thunking to and continue to there instead. */
+
+static CORE_ADDR
+gnuv3_skip_trampoline (CORE_ADDR stop_pc)
+{
+ CORE_ADDR real_stop_pc, method_stop_pc;
+ struct minimal_symbol *thunk_sym, *fn_sym;
+ struct obj_section *section;
+ char *thunk_name, *fn_name;
+
+ real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc);
+ if (real_stop_pc == 0)
+ real_stop_pc = stop_pc;
+
+ /* Find the linker symbol for this potential thunk. */
+ thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc);
+ section = find_pc_section (real_stop_pc);
+ if (thunk_sym == NULL || section == NULL)
+ return 0;
+
+ /* The symbol's demangled name should be something like "virtual
+ thunk to FUNCTION", where FUNCTION is the name of the function
+ being thunked to. */
+ thunk_name = SYMBOL_DEMANGLED_NAME (thunk_sym);
+ if (thunk_name == NULL || strstr (thunk_name, " thunk to ") == NULL)
+ return 0;
+
+ fn_name = strstr (thunk_name, " thunk to ") + strlen (" thunk to ");
+ fn_sym = lookup_minimal_symbol (fn_name, NULL, section->objfile);
+ if (fn_sym == NULL)
+ return 0;
+
+ method_stop_pc = SYMBOL_VALUE_ADDRESS (fn_sym);
+ real_stop_pc = SKIP_TRAMPOLINE_CODE (method_stop_pc);
+ if (real_stop_pc == 0)
+ real_stop_pc = method_stop_pc;
+
+ return real_stop_pc;
+}
+
static void
init_gnuv3_ops (void)
{
@@ -694,6 +736,7 @@ init_gnuv3_ops (void)
gnu_v3_abi_ops.method_ptr_size = gnuv3_method_ptr_size;
gnu_v3_abi_ops.make_method_ptr = gnuv3_make_method_ptr;
gnu_v3_abi_ops.method_ptr_to_value = gnuv3_method_ptr_to_value;
+ gnu_v3_abi_ops.skip_trampoline = gnuv3_skip_trampoline;
}
extern initialize_file_ftype _initialize_gnu_v3_abi; /* -Wmissing-prototypes */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 9add701..ac1e20a 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2007-05-07 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * gdb.cp/virtfunc.exp (proc do_tests): Test stepping through a thunk.
+
2007-05-06 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.fortran/complex.exp, gdb.fortran/complex.f: New files.
diff --git a/gdb/testsuite/gdb.cp/virtfunc.exp b/gdb/testsuite/gdb.cp/virtfunc.exp
index 6f7a6e9..4b1472e 100644
--- a/gdb/testsuite/gdb.cp/virtfunc.exp
+++ b/gdb/testsuite/gdb.cp/virtfunc.exp
@@ -254,6 +254,10 @@ proc do_tests {} {
gdb_breakpoint test_calls
gdb_test "continue" ".*Breakpoint .* test_calls.*" ""
test_virtual_calls
+
+ gdb_test "next" ".*pAa->f.*" "next to pAa->f call"
+ gdb_test "next" ".*pDe->vg.*" "next to pDe->vg call"
+ gdb_test "step" ".*E::vg.*" "step through thunk into E::vg"
}
do_tests