diff options
author | Randolph Chung <tausq@debian.org> | 2004-12-01 06:58:57 +0000 |
---|---|---|
committer | Randolph Chung <tausq@debian.org> | 2004-12-01 06:58:57 +0000 |
commit | b546247c058076147f625e2ec8e161d487ef2131 (patch) | |
tree | 7a2eba071f09443ab40b4093111e88ef5cc1c1a3 /gdb | |
parent | 8de0841b1c5d7c498deec6c42dcfa539dc58c1fa (diff) | |
download | gdb-b546247c058076147f625e2ec8e161d487ef2131.zip gdb-b546247c058076147f625e2ec8e161d487ef2131.tar.gz gdb-b546247c058076147f625e2ec8e161d487ef2131.tar.bz2 |
2004-11-30 Randolph Chung <tausq@debian.org>
* hppa-linux-tdep.c (insns_match_pattern_relaxed): New function.
(hppa_linux_in_dyncall): Check that we are inside the range of
$$dyncall, not necessarily at the first insn.
(hppa_linux_in_solib_call_trampoline): Identify a trampoline
even if the pc does not point to the first insn of the trampoline.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/hppa-linux-tdep.c | 46 |
2 files changed, 49 insertions, 5 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 379b0e1..6e1576b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 2004-11-30 Randolph Chung <tausq@debian.org> + * hppa-linux-tdep.c (insns_match_pattern_relaxed): New function. + (hppa_linux_in_dyncall): Check that we are inside the range of + $$dyncall, not necessarily at the first insn. + (hppa_linux_in_solib_call_trampoline): Identify a trampoline + even if the pc does not point to the first insn of the trampoline. + +2004-11-30 Randolph Chung <tausq@debian.org> + * breakpoint.c (break_at_finish_command): Delete. (break_at_finish_command_1): Delete. (break_at_finish_at_depth_command): Delete. diff --git a/gdb/hppa-linux-tdep.c b/gdb/hppa-linux-tdep.c index b7a00bc..4a7657a 100644 --- a/gdb/hppa-linux-tdep.c +++ b/gdb/hppa-linux-tdep.c @@ -161,10 +161,39 @@ insns_match_pattern (CORE_ADDR pc, return 1; } +/* The relaxed version of the insn matcher allows us to match from somewhere + inside the pattern, by looking backwards in the instruction scheme. */ +static int +insns_match_pattern_relaxed (CORE_ADDR pc, + struct insn_pattern *pattern, + unsigned int *insn) +{ + int pat_len = 0; + int offset; + + while (pattern[pat_len].mask) + pat_len++; + + for (offset = 0; offset < pat_len; offset++) + { + if (insns_match_pattern (pc - offset * 4, + pattern, insn)) + return 1; + } + + return 0; +} + static int hppa_linux_in_dyncall (CORE_ADDR pc) { - return pc == hppa_symbol_address("$$dyncall"); + struct unwind_table_entry *u; + u = find_unwind_entry (hppa_symbol_address ("$$dyncall")); + + if (!u) + return 0; + + return pc >= u->region_start && pc <= u->region_end; } /* There are several kinds of "trampolines" that we need to deal with: @@ -182,13 +211,20 @@ hppa_linux_in_solib_call_trampoline (CORE_ADDR pc, char *name) { unsigned int insn[HPPA_MAX_INSN_PATTERN_LEN]; int r; + struct unwind_table_entry *u; + + /* on hppa-linux, linker stubs have no unwind information. Since the pattern + matching for linker stubs can be quite slow, we try to avoid it if + we can. */ + u = find_unwind_entry (pc); r = in_plt_section (pc, name) || hppa_linux_in_dyncall (pc) - || insns_match_pattern (pc, hppa_import_stub, insn) - || insns_match_pattern (pc, hppa_import_pic_stub, insn) - || insns_match_pattern (pc, hppa_long_branch_stub, insn) - || insns_match_pattern (pc, hppa_long_branch_pic_stub, insn); + || (u == NULL + && (insns_match_pattern_relaxed (pc, hppa_import_stub, insn) + || insns_match_pattern_relaxed (pc, hppa_import_pic_stub, insn) + || insns_match_pattern_relaxed (pc, hppa_long_branch_stub, insn) + || insns_match_pattern_relaxed (pc, hppa_long_branch_pic_stub, insn))); return r; } |