aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandolph Chung <tausq@debian.org>2004-12-01 06:58:57 +0000
committerRandolph Chung <tausq@debian.org>2004-12-01 06:58:57 +0000
commitb546247c058076147f625e2ec8e161d487ef2131 (patch)
tree7a2eba071f09443ab40b4093111e88ef5cc1c1a3
parent8de0841b1c5d7c498deec6c42dcfa539dc58c1fa (diff)
downloadgdb-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.
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/hppa-linux-tdep.c46
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;
}