]> git.ipfire.org Git - ipfire-3.x.git/blob - gdb/patches/gdb-6.3-ppc64syscall-20040622.patch
wget: LDFLAGS were accidentially overwritten
[ipfire-3.x.git] / gdb / patches / gdb-6.3-ppc64syscall-20040622.patch
1 2004-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
9 Index: gdb-7.2.50.20110117/gdb/rs6000-tdep.c
10 ===================================================================
11 --- gdb-7.2.50.20110117.orig/gdb/rs6000-tdep.c 2011-01-11 20:23:02.000000000 +0100
12 +++ gdb-7.2.50.20110117/gdb/rs6000-tdep.c 2011-01-17 15:48:19.000000000 +0100
13 @@ -126,6 +126,7 @@ static const char *powerpc_vector_abi_st
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 */
21 @@ -1496,7 +1497,6 @@ static CORE_ADDR
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];
29 @@ -1514,12 +1514,14 @@ skip_prologue (struct gdbarch *gdbarch,
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);
37 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
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;
44 @@ -1553,6 +1555,55 @@ skip_prologue (struct gdbarch *gdbarch,
45 break;
46 op = extract_unsigned_integer (buf, 4, byte_order);
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
100 @@ -1734,9 +1785,9 @@ skip_prologue (struct gdbarch *gdbarch,
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)