]> git.pld-linux.org Git - packages/gdb.git/blame - gdb-6.3-ppc64syscall-20040622.patch
- update to 6.8.91.20090930-1 from fedora
[packages/gdb.git] / gdb-6.3-ppc64syscall-20040622.patch
CommitLineData
3a58abaf
AM
12004-06-22 Andrew Cagney <cagney@gnu.org>
2
3 * rs6000-tdep.c (struct rs6000_framedata): Add field "func_start".
4 (skip_prologue): Delete local variable "orig_pc", use
5 "func_start". Add local variable "num_skip_linux_syscall_insn",
6 use to skip over first half of a GNU/Linux syscall and update
7 "func_start".
8
7566401a 9Index: gdb-6.8.50.20090802/gdb/rs6000-tdep.c
3a58abaf 10===================================================================
7566401a
ER
11--- gdb-6.8.50.20090802.orig/gdb/rs6000-tdep.c 2009-07-31 17:23:20.000000000 +0200
12+++ gdb-6.8.50.20090802/gdb/rs6000-tdep.c 2009-08-03 09:52:39.000000000 +0200
13@@ -126,6 +126,7 @@ static const char *powerpc_vector_abi_st
3a58abaf
AM
14
15 struct rs6000_framedata
16 {
17+ CORE_ADDR func_start; /* True function start. */
18 int offset; /* total size of frame --- the distance
19 by which we decrement sp to allocate
20 the frame */
7566401a 21@@ -1488,7 +1489,6 @@ static CORE_ADDR
3a58abaf
AM
22 skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
23 struct rs6000_framedata *fdata)
24 {
25- CORE_ADDR orig_pc = pc;
26 CORE_ADDR last_prologue_pc = pc;
27 CORE_ADDR li_found_pc = 0;
28 gdb_byte buf[4];
7566401a 29@@ -1506,12 +1506,14 @@ skip_prologue (struct gdbarch *gdbarch,
3a58abaf
AM
30 int minimal_toc_loaded = 0;
31 int prev_insn_was_prologue_insn = 1;
32 int num_skip_non_prologue_insns = 0;
33+ int num_skip_ppc64_gnu_linux_syscall_insn = 0;
34 int r0_contains_arg = 0;
35 const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
36 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
7566401a 37 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
3a58abaf
AM
38
39 memset (fdata, 0, sizeof (struct rs6000_framedata));
40+ fdata->func_start = pc;
41 fdata->saved_gpr = -1;
42 fdata->saved_fpr = -1;
43 fdata->saved_vr = -1;
7566401a 44@@ -1545,6 +1547,55 @@ skip_prologue (struct gdbarch *gdbarch,
3a58abaf 45 break;
7566401a 46 op = extract_unsigned_integer (buf, 4, byte_order);
3a58abaf
AM
47
48+ /* A PPC64 GNU/Linux system call function is split into two
49+ sub-functions: a non-threaded fast-path (__NAME_nocancel)
50+ which does not use a frame; and a threaded slow-path
51+ (Lpseudo_cancel) that does create a frame. Ref:
52+ nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
53+
54+ *INDENT-OFF*
55+ NAME:
56+ SINGLE_THREAD_P
57+ bne- .Lpseudo_cancel
58+ __NAME_nocancel:
59+ li r0,162
60+ sc
61+ bnslr+
62+ b 0x7fe014ef64 <.__syscall_error>
63+ Lpseudo_cancel:
64+ stdu r1,-128(r1)
65+ ...
66+ *INDENT-ON*
67+
68+ Unfortunatly, because the latter case uses a local label (not
69+ in the symbol table) a PC in "Lpseudo_cancel" appears to be
70+ in "__NAME_nocancel". The following code recognizes this,
71+ adjusting FUNC_START to point to where "Lpseudo_cancel"
72+ should be, and parsing the prologue sequence as if
73+ "Lpseudo_cancel" was the entry point. */
74+
75+ if (((op & 0xffff0000) == 0x38000000 /* li r0,N */
76+ && pc == fdata->func_start + 0
77+ && num_skip_ppc64_gnu_linux_syscall_insn == 0)
78+ || (op == 0x44000002 /* sc */
79+ && pc == fdata->func_start + 4
80+ && num_skip_ppc64_gnu_linux_syscall_insn == 1)
81+ || (op == 0x4ca30020 /* bnslr+ */
82+ && pc == fdata->func_start + 8
83+ && num_skip_ppc64_gnu_linux_syscall_insn == 2))
84+ {
85+ num_skip_ppc64_gnu_linux_syscall_insn++;
86+ continue;
87+ }
88+ else if ((op & 0xfc000003) == 0x48000000 /* b __syscall_error */
89+ && pc == fdata->func_start + 12
90+ && num_skip_ppc64_gnu_linux_syscall_insn == 3)
91+ {
92+ num_skip_ppc64_gnu_linux_syscall_insn = -1;
93+ fdata->func_start = pc;
94+ continue;
95+ }
96+
97 if ((op & 0xfc1fffff) == 0x7c0802a6)
98 { /* mflr Rx */
99 /* Since shared library / PIC code, which needs to get its
7566401a 100@@ -1726,9 +1777,9 @@ skip_prologue (struct gdbarch *gdbarch,
3a58abaf
AM
101 we have no line table information or the line info tells
102 us that the subroutine call is not part of the line
103 associated with the prologue. */
104- if ((pc - orig_pc) > 8)
105+ if ((pc - fdata->func_start) > 8)
106 {
107- struct symtab_and_line prologue_sal = find_pc_line (orig_pc, 0);
108+ struct symtab_and_line prologue_sal = find_pc_line (fdata->func_start, 0);
109 struct symtab_and_line this_sal = find_pc_line (pc, 0);
110
111 if ((prologue_sal.line == 0) || (prologue_sal.line != this_sal.line))
This page took 0.046807 seconds and 4 git commands to generate.