]> git.pld-linux.org Git - packages/gdb.git/blob - gdb-6.3-ppc64syscall-20040622.patch
- update to 6.8.91.20090930-1 from fedora
[packages/gdb.git] / 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-6.8.50.20090802/gdb/rs6000-tdep.c
10 ===================================================================
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
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 @@ -1488,7 +1489,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 @@ -1506,12 +1506,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 @@ -1545,6 +1547,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 @@ -1726,9 +1777,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) || (prologue_sal.line != this_sal.line))
This page took 0.047437 seconds and 3 git commands to generate.