1/* libunwind - a platform-independent unwind library
2   Copyright (C) 2006-2007 IBM
3   Contributed by
4     Corey Ashford <cjashfor@us.ibm.com>
5     Jose Flavio Aguilar Paulino <jflavio@br.ibm.com> <joseflavio@gmail.com>
6
7   Copied from libunwind-x86_64.h, modified slightly for building
8   frysk successfully on ppc64, by Wu Zhou <woodzltc@cn.ibm.com>
9   Will be replaced when libunwind is ready on ppc64 platform.
10
11This file is part of libunwind.
12
13Permission is hereby granted, free of charge, to any person obtaining
14a copy of this software and associated documentation files (the
15"Software"), to deal in the Software without restriction, including
16without limitation the rights to use, copy, modify, merge, publish,
17distribute, sublicense, and/or sell copies of the Software, and to
18permit persons to whom the Software is furnished to do so, subject to
19the following conditions:
20
21The above copyright notice and this permission notice shall be
22included in all copies or substantial portions of the Software.
23
24THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
31
32#ifndef LIBUNWIND_H
33#define LIBUNWIND_H
34
35#if defined(__cplusplus) || defined(c_plusplus)
36extern "C" {
37#endif
38
39#include <inttypes.h>
40#include <ucontext.h>
41
42#define UNW_TARGET		ppc64
43#define UNW_TARGET_PPC64	1
44
45#define _U_TDEP_QP_TRUE	0	/* see libunwind-dynamic.h  */
46
47/*
48 * This needs to be big enough to accommodate "struct cursor", while
49 * leaving some slack for future expansion.  Changing this value will
50 * require recompiling all users of this library.  Stack allocation is
51 * relatively cheap and unwind-state copying is relatively rare, so we want
52 * to err on making it rather too big than too small.
53 *
54 * To simplify this whole process, we are at least initially taking the
55 * tack that UNW_PPC64_* map straight across to the .eh_frame column register
56 * numbers.  These register numbers come from gcc's source in
57 * gcc/config/rs6000/rs6000.h
58 *
59 * UNW_TDEP_CURSOR_LEN is in terms of unw_word_t size.  Since we have 115
60 * elements in the loc array, each sized 2 * unw_word_t, plus the rest of
61 * the cursor struct, this puts us at about 2 * 115 + 40 = 270.  Let's
62 * round that up to 280.
63 */
64
65#define UNW_TDEP_CURSOR_LEN 280
66
67#if __WORDSIZE==32
68typedef uint32_t unw_word_t;
69typedef int32_t unw_sword_t;
70#else
71typedef uint64_t unw_word_t;
72typedef int64_t unw_sword_t;
73#endif
74
75typedef long double unw_tdep_fpreg_t;
76
77/*
78 * Vector register (in PowerPC64 used for AltiVec registers)
79 */
80typedef struct {
81    uint64_t halves[2];
82} unw_tdep_vreg_t;
83
84typedef enum
85  {
86    UNW_PPC64_R0,
87    UNW_PPC64_R1, /* called STACK_POINTER in gcc */
88    UNW_PPC64_R2,
89    UNW_PPC64_R3,
90    UNW_PPC64_R4,
91    UNW_PPC64_R5,
92    UNW_PPC64_R6,
93    UNW_PPC64_R7,
94    UNW_PPC64_R8,
95    UNW_PPC64_R9,
96    UNW_PPC64_R10,
97    UNW_PPC64_R11, /* called STATIC_CHAIN in gcc */
98    UNW_PPC64_R12,
99    UNW_PPC64_R13,
100    UNW_PPC64_R14,
101    UNW_PPC64_R15,
102    UNW_PPC64_R16,
103    UNW_PPC64_R17,
104    UNW_PPC64_R18,
105    UNW_PPC64_R19,
106    UNW_PPC64_R20,
107    UNW_PPC64_R21,
108    UNW_PPC64_R22,
109    UNW_PPC64_R23,
110    UNW_PPC64_R24,
111    UNW_PPC64_R25,
112    UNW_PPC64_R26,
113    UNW_PPC64_R27,
114    UNW_PPC64_R28,
115    UNW_PPC64_R29,
116    UNW_PPC64_R30,
117    UNW_PPC64_R31, /* called HARD_FRAME_POINTER in gcc */
118
119    UNW_PPC64_F0 = 32,
120    UNW_PPC64_F1,
121    UNW_PPC64_F2,
122    UNW_PPC64_F3,
123    UNW_PPC64_F4,
124    UNW_PPC64_F5,
125    UNW_PPC64_F6,
126    UNW_PPC64_F7,
127    UNW_PPC64_F8,
128    UNW_PPC64_F9,
129    UNW_PPC64_F10,
130    UNW_PPC64_F11,
131    UNW_PPC64_F12,
132    UNW_PPC64_F13,
133    UNW_PPC64_F14,
134    UNW_PPC64_F15,
135    UNW_PPC64_F16,
136    UNW_PPC64_F17,
137    UNW_PPC64_F18,
138    UNW_PPC64_F19,
139    UNW_PPC64_F20,
140    UNW_PPC64_F21,
141    UNW_PPC64_F22,
142    UNW_PPC64_F23,
143    UNW_PPC64_F24,
144    UNW_PPC64_F25,
145    UNW_PPC64_F26,
146    UNW_PPC64_F27,
147    UNW_PPC64_F28,
148    UNW_PPC64_F29,
149    UNW_PPC64_F30,
150    UNW_PPC64_F31,
151    /* Note that there doesn't appear to be an .eh_frame register column
152       for the FPSCR register.  I don't know why this is.  Since .eh_frame
153       info is what this implementation uses for unwinding, we have no way
154       to unwind this register, and so we will not expose an FPSCR register
155       number in the libunwind API.
156     */
157
158    UNW_PPC64_LR = 65,
159    UNW_PPC64_CTR = 66,
160    UNW_PPC64_ARG_POINTER = 67,
161
162    UNW_PPC64_CR0 = 68,
163    UNW_PPC64_CR1,
164    UNW_PPC64_CR2,
165    UNW_PPC64_CR3,
166    UNW_PPC64_CR4,
167    /* CR5 .. CR7 are currently unused */
168    UNW_PPC64_CR5,
169    UNW_PPC64_CR6,
170    UNW_PPC64_CR7,
171
172    UNW_PPC64_XER = 76,
173
174    UNW_PPC64_V0 = 77,
175    UNW_PPC64_V1,
176    UNW_PPC64_V2,
177    UNW_PPC64_V3,
178    UNW_PPC64_V4,
179    UNW_PPC64_V5,
180    UNW_PPC64_V6,
181    UNW_PPC64_V7,
182    UNW_PPC64_V8,
183    UNW_PPC64_V9,
184    UNW_PPC64_V10,
185    UNW_PPC64_V11,
186    UNW_PPC64_V12,
187    UNW_PPC64_V13,
188    UNW_PPC64_V14,
189    UNW_PPC64_V15,
190    UNW_PPC64_V16,
191    UNW_PPC64_V17,
192    UNW_PPC64_V18,
193    UNW_PPC64_V19,
194    UNW_PPC64_V20,
195    UNW_PPC64_V21,
196    UNW_PPC64_V22,
197    UNW_PPC64_V23,
198    UNW_PPC64_V24,
199    UNW_PPC64_V25,
200    UNW_PPC64_V26,
201    UNW_PPC64_V27,
202    UNW_PPC64_V28,
203    UNW_PPC64_V29,
204    UNW_PPC64_V30,
205    UNW_PPC64_V31,
206
207    UNW_PPC64_VRSAVE = 109,
208    UNW_PPC64_VSCR = 110,
209    UNW_PPC64_SPE_ACC = 111,
210    UNW_PPC64_SPEFSCR = 112,
211
212    /* frame info (read-only) */
213    UNW_PPC64_FRAME_POINTER,
214    UNW_PPC64_NIP,
215
216
217    UNW_TDEP_LAST_REG = UNW_PPC64_NIP,
218
219    UNW_TDEP_IP = UNW_PPC64_NIP,
220    UNW_TDEP_SP = UNW_PPC64_R1,
221    UNW_TDEP_EH = UNW_PPC64_R12
222  }
223ppc64_regnum_t;
224
225/*
226 * According to David Edelsohn, GNU gcc uses R3, R4, R5, and maybe R6 for
227 * passing parameters to exception handlers.
228 */
229
230#define UNW_TDEP_NUM_EH_REGS	4
231
232typedef struct unw_tdep_save_loc
233  {
234    /* Additional target-dependent info on a save location.  */
235  }
236unw_tdep_save_loc_t;
237
238/* On ppc64, we can directly use ucontext_t as the unwind context.  */
239typedef ucontext_t unw_tdep_context_t;
240
241/* XXX this is not ideal: an application should not be prevented from
242   using the "getcontext" name just because it's using libunwind.  We
243   can't just use __getcontext() either, because that isn't exported
244   by glibc...  */
245#define unw_tdep_getcontext(uc)		(getcontext (uc), 0)
246
247#include "libunwind-dynamic.h"
248
249typedef struct
250  {
251    /* no ppc64-specific auxiliary proc-info */
252  }
253unw_tdep_proc_info_t;
254
255#include "libunwind-common.h"
256
257#define unw_tdep_is_fpreg		UNW_ARCH_OBJ(is_fpreg)
258extern int unw_tdep_is_fpreg (int);
259
260#if defined(__cplusplus) || defined(c_plusplus)
261}
262#endif
263
264#endif /* LIBUNWIND_H */
265