diff options
author | Daniel Jacobowitz <drow@false.org> | 2007-05-07 11:49:05 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2007-05-07 11:49:05 +0000 |
commit | b18be20d0aadff1e7c5b4d161177481aa61b9fc4 (patch) | |
tree | b3807e7e3e98d6155edff77c65a25c93542aee32 /gdb/gnu-v3-abi.c | |
parent | dda9b909e68c77cae3ad23e67b8acd5809652997 (diff) | |
download | gdb-b18be20d0aadff1e7c5b4d161177481aa61b9fc4.zip gdb-b18be20d0aadff1e7c5b4d161177481aa61b9fc4.tar.gz gdb-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.
Diffstat (limited to 'gdb/gnu-v3-abi.c')
-rw-r--r-- | gdb/gnu-v3-abi.c | 43 |
1 files changed, 43 insertions, 0 deletions
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 */ |