2004-02-14 Elena Zannoni <ezannoni@redhat.com>
[platform/upstream/binutils.git] / gdb / hppa-hpux-tdep.c
1 /* Target-dependent code for HPUX running on PA-RISC, for GDB.
2
3    Copyright 2002, 2003 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include "defs.h"
22 #include "arch-utils.h"
23 #include "gdbcore.h"
24 #include "osabi.h"
25 #include "gdb_string.h"
26 #include "frame.h"
27
28 /* Forward declarations.  */
29 extern void _initialize_hppa_hpux_tdep (void);
30 extern initialize_file_ftype _initialize_hppa_hpux_tdep;
31
32 /* FIXME: brobecker 2002-12-25.  The following functions will eventually
33    become static, after the multiarching conversion is done.  */
34 int hppa_hpux_pc_in_sigtramp (CORE_ADDR pc, char *name);
35 void hppa32_hpux_frame_saved_pc_in_sigtramp (struct frame_info *fi,
36                                              CORE_ADDR *tmp);
37 void hppa32_hpux_frame_base_before_sigtramp (struct frame_info *fi,
38                                              CORE_ADDR *tmp);
39 void hppa32_hpux_frame_find_saved_regs_in_sigtramp (struct frame_info *fi,
40                                                     CORE_ADDR *fsr);
41 void hppa64_hpux_frame_saved_pc_in_sigtramp (struct frame_info *fi,
42                                              CORE_ADDR *tmp);
43 void hppa64_hpux_frame_base_before_sigtramp (struct frame_info *fi,
44                                              CORE_ADDR *tmp);
45 void hppa64_hpux_frame_find_saved_regs_in_sigtramp (struct frame_info *fi,
46                                                     CORE_ADDR *fsr);
47
48 int
49 hppa_hpux_pc_in_sigtramp (CORE_ADDR pc, char *name)
50 {
51   /* Actually, for a PA running HPUX the kernel calls the signal handler
52      without an intermediate trampoline.  Luckily the kernel always sets
53      the return pointer for the signal handler to point to _sigreturn.  */
54   return (name && (strcmp ("_sigreturn", name) == 0));
55 }
56
57 /* For hppa32_hpux_frame_saved_pc_in_sigtramp, 
58    hppa32_hpux_frame_base_before_sigtramp and
59    hppa32_hpux_frame_find_saved_regs_in_sigtramp:
60
61    The signal context structure pointer is always saved at the base
62    of the frame which "calls" the signal handler.  We only want to find
63    the hardware save state structure, which lives 10 32bit words into
64    sigcontext structure.
65
66    Within the hardware save state structure, registers are found in the
67    same order as the register numbers in GDB.
68
69    At one time we peeked at %r31 rather than the PC queues to determine
70    what instruction took the fault.  This was done on purpose, but I don't
71    remember why.  Looking at the PC queues is really the right way, and
72    I don't remember why that didn't work when this code was originally
73    written.  */
74
75 void
76 hppa32_hpux_frame_saved_pc_in_sigtramp (struct frame_info *fi, CORE_ADDR *tmp)
77 {
78   *tmp = read_memory_integer (get_frame_base (fi) + (43 * 4), 4);
79 }
80
81 void
82 hppa32_hpux_frame_base_before_sigtramp (struct frame_info *fi,
83                                         CORE_ADDR *tmp)
84 {
85   *tmp = read_memory_integer (get_frame_base (fi) + (40 * 4), 4);
86 }
87
88 void
89 hppa32_hpux_frame_find_saved_regs_in_sigtramp (struct frame_info *fi,
90                                                CORE_ADDR *fsr)
91 {
92   int i;
93   const CORE_ADDR tmp = get_frame_base (fi) + (10 * 4);
94
95   for (i = 0; i < NUM_REGS; i++)
96     {
97       if (i == SP_REGNUM)
98         fsr[SP_REGNUM] = read_memory_integer (tmp + SP_REGNUM * 4, 4);
99       else
100         fsr[i] = tmp + i * 4;
101     }
102 }
103
104 /* For hppa64_hpux_frame_saved_pc_in_sigtramp, 
105    hppa64_hpux_frame_base_before_sigtramp and
106    hppa64_hpux_frame_find_saved_regs_in_sigtramp:
107
108    These functions are the PA64 ABI equivalents of the 32bits counterparts
109    above. See the comments there.
110
111    For PA64, the save_state structure is at an offset of 24 32-bit words
112    from the sigcontext structure. The 64 bit general registers are at an
113    offset of 640 bytes from the beginning of the save_state structure,
114    and the floating pointer register are at an offset of 256 bytes from
115    the beginning of the save_state structure.  */
116
117 void
118 hppa64_hpux_frame_saved_pc_in_sigtramp (struct frame_info *fi, CORE_ADDR *tmp)
119 {
120   *tmp = read_memory_integer
121            (get_frame_base (fi) + (24 * 4) + 640 + (33 * 8), 8);
122 }
123
124 void
125 hppa64_hpux_frame_base_before_sigtramp (struct frame_info *fi,
126                                         CORE_ADDR *tmp)
127 {
128   *tmp = read_memory_integer
129            (get_frame_base (fi) + (24 * 4) + 640 + (30 * 8), 8);
130 }
131
132 void
133 hppa64_hpux_frame_find_saved_regs_in_sigtramp (struct frame_info *fi,
134                                                CORE_ADDR *fsr)
135 {
136   int i;
137   const CORE_ADDR tmp1 = get_frame_base (fi) + (24 * 4) + 640;
138   const CORE_ADDR tmp2 = get_frame_base (fi) + (24 * 4) + 256;
139
140   for (i = 0; i < NUM_REGS; i++)
141     {
142       if (i == SP_REGNUM)
143         fsr[SP_REGNUM] = read_memory_integer (tmp1 + SP_REGNUM * 8, 8);
144       else if (i >= FP0_REGNUM)
145         fsr[i] = tmp2 + (i - FP0_REGNUM) * 8;
146       else
147         fsr[i] = tmp1 + i * 8;
148     }
149 }
150
151 static void
152 hppa_hpux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
153 {
154   set_gdbarch_pc_in_sigtramp (gdbarch, hppa_hpux_pc_in_sigtramp);
155 }
156
157 static void
158 hppa_hpux_som_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
159 {
160   hppa_hpux_init_abi (info, gdbarch);
161 }
162
163 static void
164 hppa_hpux_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
165 {
166   hppa_hpux_init_abi (info, gdbarch);
167 }
168
169 void
170 _initialize_hppa_hpux_tdep (void)
171 {
172   gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_HPUX_SOM,
173                           hppa_hpux_som_init_abi);
174   gdbarch_register_osabi (bfd_arch_hppa, bfd_mach_hppa20w, GDB_OSABI_HPUX_ELF,
175                           hppa_hpux_elf_init_abi);
176 }