1b725ae77Skettenis /* Target-dependent code for the IA-64 for GDB, the GNU debugger.
2b725ae77Skettenis
3b725ae77Skettenis Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software
4b725ae77Skettenis Foundation, Inc.
5b725ae77Skettenis
6b725ae77Skettenis This file is part of GDB.
7b725ae77Skettenis
8b725ae77Skettenis This program is free software; you can redistribute it and/or modify
9b725ae77Skettenis it under the terms of the GNU General Public License as published by
10b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
11b725ae77Skettenis (at your option) any later version.
12b725ae77Skettenis
13b725ae77Skettenis This program is distributed in the hope that it will be useful,
14b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
15b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16b725ae77Skettenis GNU General Public License for more details.
17b725ae77Skettenis
18b725ae77Skettenis You should have received a copy of the GNU General Public License
19b725ae77Skettenis along with this program; if not, write to the Free Software
20b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis Boston, MA 02111-1307, USA. */
22b725ae77Skettenis
23b725ae77Skettenis #include "defs.h"
24b725ae77Skettenis #include "inferior.h"
25b725ae77Skettenis #include "gdbcore.h"
26b725ae77Skettenis #include "arch-utils.h"
27b725ae77Skettenis #include "floatformat.h"
28b725ae77Skettenis #include "regcache.h"
29b725ae77Skettenis #include "reggroups.h"
30b725ae77Skettenis #include "frame.h"
31b725ae77Skettenis #include "frame-base.h"
32b725ae77Skettenis #include "frame-unwind.h"
33b725ae77Skettenis #include "doublest.h"
34b725ae77Skettenis #include "value.h"
35b725ae77Skettenis #include "gdb_assert.h"
36b725ae77Skettenis #include "objfiles.h"
37b725ae77Skettenis #include "elf/common.h" /* for DT_PLTGOT value */
38b725ae77Skettenis #include "elf-bfd.h"
39b725ae77Skettenis #include "dis-asm.h"
40*11efff7fSkettenis #include "infcall.h"
41b725ae77Skettenis #include "ia64-tdep.h"
42b725ae77Skettenis
43b725ae77Skettenis #ifdef HAVE_LIBUNWIND_IA64_H
44*11efff7fSkettenis #include "elf/ia64.h" /* for PT_IA_64_UNWIND value */
45b725ae77Skettenis #include "libunwind-frame.h"
46b725ae77Skettenis #include "libunwind-ia64.h"
47b725ae77Skettenis #endif
48b725ae77Skettenis
49b725ae77Skettenis /* Hook for determining the global pointer when calling functions in
50b725ae77Skettenis the inferior under AIX. The initialization code in ia64-aix-nat.c
51b725ae77Skettenis sets this hook to the address of a function which will find the
52b725ae77Skettenis global pointer for a given address.
53b725ae77Skettenis
54b725ae77Skettenis The generic code which uses the dynamic section in the inferior for
55b725ae77Skettenis finding the global pointer is not of much use on AIX since the
56b725ae77Skettenis values obtained from the inferior have not been relocated. */
57b725ae77Skettenis
58b725ae77Skettenis CORE_ADDR (*native_find_global_pointer) (CORE_ADDR) = 0;
59b725ae77Skettenis
60b725ae77Skettenis /* An enumeration of the different IA-64 instruction types. */
61b725ae77Skettenis
62b725ae77Skettenis typedef enum instruction_type
63b725ae77Skettenis {
64b725ae77Skettenis A, /* Integer ALU ; I-unit or M-unit */
65b725ae77Skettenis I, /* Non-ALU integer; I-unit */
66b725ae77Skettenis M, /* Memory ; M-unit */
67b725ae77Skettenis F, /* Floating-point ; F-unit */
68b725ae77Skettenis B, /* Branch ; B-unit */
69b725ae77Skettenis L, /* Extended (L+X) ; I-unit */
70b725ae77Skettenis X, /* Extended (L+X) ; I-unit */
71b725ae77Skettenis undefined /* undefined or reserved */
72b725ae77Skettenis } instruction_type;
73b725ae77Skettenis
74b725ae77Skettenis /* We represent IA-64 PC addresses as the value of the instruction
75b725ae77Skettenis pointer or'd with some bit combination in the low nibble which
76b725ae77Skettenis represents the slot number in the bundle addressed by the
77b725ae77Skettenis instruction pointer. The problem is that the Linux kernel
78b725ae77Skettenis multiplies its slot numbers (for exceptions) by one while the
79b725ae77Skettenis disassembler multiplies its slot numbers by 6. In addition, I've
80b725ae77Skettenis heard it said that the simulator uses 1 as the multiplier.
81b725ae77Skettenis
82b725ae77Skettenis I've fixed the disassembler so that the bytes_per_line field will
83b725ae77Skettenis be the slot multiplier. If bytes_per_line comes in as zero, it
84b725ae77Skettenis is set to six (which is how it was set up initially). -- objdump
85b725ae77Skettenis displays pretty disassembly dumps with this value. For our purposes,
86b725ae77Skettenis we'll set bytes_per_line to SLOT_MULTIPLIER. This is okay since we
87b725ae77Skettenis never want to also display the raw bytes the way objdump does. */
88b725ae77Skettenis
89b725ae77Skettenis #define SLOT_MULTIPLIER 1
90b725ae77Skettenis
91b725ae77Skettenis /* Length in bytes of an instruction bundle */
92b725ae77Skettenis
93b725ae77Skettenis #define BUNDLE_LEN 16
94b725ae77Skettenis
95b725ae77Skettenis static gdbarch_init_ftype ia64_gdbarch_init;
96b725ae77Skettenis
97b725ae77Skettenis static gdbarch_register_name_ftype ia64_register_name;
98b725ae77Skettenis static gdbarch_register_type_ftype ia64_register_type;
99b725ae77Skettenis static gdbarch_breakpoint_from_pc_ftype ia64_breakpoint_from_pc;
100b725ae77Skettenis static gdbarch_skip_prologue_ftype ia64_skip_prologue;
101b725ae77Skettenis static gdbarch_extract_return_value_ftype ia64_extract_return_value;
102b725ae77Skettenis static struct type *is_float_or_hfa_type (struct type *t);
103b725ae77Skettenis
104b725ae77Skettenis static struct type *builtin_type_ia64_ext;
105b725ae77Skettenis
106b725ae77Skettenis #define NUM_IA64_RAW_REGS 462
107b725ae77Skettenis
108b725ae77Skettenis static int sp_regnum = IA64_GR12_REGNUM;
109b725ae77Skettenis static int fp_regnum = IA64_VFP_REGNUM;
110b725ae77Skettenis static int lr_regnum = IA64_VRAP_REGNUM;
111b725ae77Skettenis
112b725ae77Skettenis /* NOTE: we treat the register stack registers r32-r127 as pseudo-registers because
113b725ae77Skettenis they may not be accessible via the ptrace register get/set interfaces. */
114b725ae77Skettenis enum pseudo_regs { FIRST_PSEUDO_REGNUM = NUM_IA64_RAW_REGS, VBOF_REGNUM = IA64_NAT127_REGNUM + 1, V32_REGNUM,
115b725ae77Skettenis V127_REGNUM = V32_REGNUM + 95,
116b725ae77Skettenis VP0_REGNUM, VP16_REGNUM = VP0_REGNUM + 16, VP63_REGNUM = VP0_REGNUM + 63, LAST_PSEUDO_REGNUM };
117b725ae77Skettenis
118b725ae77Skettenis /* Array of register names; There should be ia64_num_regs strings in
119b725ae77Skettenis the initializer. */
120b725ae77Skettenis
121b725ae77Skettenis static char *ia64_register_names[] =
122b725ae77Skettenis { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
123b725ae77Skettenis "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
124b725ae77Skettenis "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
125b725ae77Skettenis "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
126b725ae77Skettenis "", "", "", "", "", "", "", "",
127b725ae77Skettenis "", "", "", "", "", "", "", "",
128b725ae77Skettenis "", "", "", "", "", "", "", "",
129b725ae77Skettenis "", "", "", "", "", "", "", "",
130b725ae77Skettenis "", "", "", "", "", "", "", "",
131b725ae77Skettenis "", "", "", "", "", "", "", "",
132b725ae77Skettenis "", "", "", "", "", "", "", "",
133b725ae77Skettenis "", "", "", "", "", "", "", "",
134b725ae77Skettenis "", "", "", "", "", "", "", "",
135b725ae77Skettenis "", "", "", "", "", "", "", "",
136b725ae77Skettenis "", "", "", "", "", "", "", "",
137b725ae77Skettenis "", "", "", "", "", "", "", "",
138b725ae77Skettenis
139b725ae77Skettenis "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
140b725ae77Skettenis "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
141b725ae77Skettenis "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
142b725ae77Skettenis "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
143b725ae77Skettenis "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
144b725ae77Skettenis "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
145b725ae77Skettenis "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
146b725ae77Skettenis "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
147b725ae77Skettenis "f64", "f65", "f66", "f67", "f68", "f69", "f70", "f71",
148b725ae77Skettenis "f72", "f73", "f74", "f75", "f76", "f77", "f78", "f79",
149b725ae77Skettenis "f80", "f81", "f82", "f83", "f84", "f85", "f86", "f87",
150b725ae77Skettenis "f88", "f89", "f90", "f91", "f92", "f93", "f94", "f95",
151b725ae77Skettenis "f96", "f97", "f98", "f99", "f100", "f101", "f102", "f103",
152b725ae77Skettenis "f104", "f105", "f106", "f107", "f108", "f109", "f110", "f111",
153b725ae77Skettenis "f112", "f113", "f114", "f115", "f116", "f117", "f118", "f119",
154b725ae77Skettenis "f120", "f121", "f122", "f123", "f124", "f125", "f126", "f127",
155b725ae77Skettenis
156b725ae77Skettenis "", "", "", "", "", "", "", "",
157b725ae77Skettenis "", "", "", "", "", "", "", "",
158b725ae77Skettenis "", "", "", "", "", "", "", "",
159b725ae77Skettenis "", "", "", "", "", "", "", "",
160b725ae77Skettenis "", "", "", "", "", "", "", "",
161b725ae77Skettenis "", "", "", "", "", "", "", "",
162b725ae77Skettenis "", "", "", "", "", "", "", "",
163b725ae77Skettenis "", "", "", "", "", "", "", "",
164b725ae77Skettenis
165b725ae77Skettenis "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
166b725ae77Skettenis
167b725ae77Skettenis "vfp", "vrap",
168b725ae77Skettenis
169b725ae77Skettenis "pr", "ip", "psr", "cfm",
170b725ae77Skettenis
171b725ae77Skettenis "kr0", "kr1", "kr2", "kr3", "kr4", "kr5", "kr6", "kr7",
172b725ae77Skettenis "", "", "", "", "", "", "", "",
173b725ae77Skettenis "rsc", "bsp", "bspstore", "rnat",
174b725ae77Skettenis "", "fcr", "", "",
175b725ae77Skettenis "eflag", "csd", "ssd", "cflg", "fsr", "fir", "fdr", "",
176b725ae77Skettenis "ccv", "", "", "", "unat", "", "", "",
177b725ae77Skettenis "fpsr", "", "", "", "itc",
178b725ae77Skettenis "", "", "", "", "", "", "", "", "", "",
179b725ae77Skettenis "", "", "", "", "", "", "", "", "",
180b725ae77Skettenis "pfs", "lc", "ec",
181b725ae77Skettenis "", "", "", "", "", "", "", "", "", "",
182b725ae77Skettenis "", "", "", "", "", "", "", "", "", "",
183b725ae77Skettenis "", "", "", "", "", "", "", "", "", "",
184b725ae77Skettenis "", "", "", "", "", "", "", "", "", "",
185b725ae77Skettenis "", "", "", "", "", "", "", "", "", "",
186b725ae77Skettenis "", "", "", "", "", "", "", "", "", "",
187b725ae77Skettenis "",
188b725ae77Skettenis "nat0", "nat1", "nat2", "nat3", "nat4", "nat5", "nat6", "nat7",
189b725ae77Skettenis "nat8", "nat9", "nat10", "nat11", "nat12", "nat13", "nat14", "nat15",
190b725ae77Skettenis "nat16", "nat17", "nat18", "nat19", "nat20", "nat21", "nat22", "nat23",
191b725ae77Skettenis "nat24", "nat25", "nat26", "nat27", "nat28", "nat29", "nat30", "nat31",
192b725ae77Skettenis "nat32", "nat33", "nat34", "nat35", "nat36", "nat37", "nat38", "nat39",
193b725ae77Skettenis "nat40", "nat41", "nat42", "nat43", "nat44", "nat45", "nat46", "nat47",
194b725ae77Skettenis "nat48", "nat49", "nat50", "nat51", "nat52", "nat53", "nat54", "nat55",
195b725ae77Skettenis "nat56", "nat57", "nat58", "nat59", "nat60", "nat61", "nat62", "nat63",
196b725ae77Skettenis "nat64", "nat65", "nat66", "nat67", "nat68", "nat69", "nat70", "nat71",
197b725ae77Skettenis "nat72", "nat73", "nat74", "nat75", "nat76", "nat77", "nat78", "nat79",
198b725ae77Skettenis "nat80", "nat81", "nat82", "nat83", "nat84", "nat85", "nat86", "nat87",
199b725ae77Skettenis "nat88", "nat89", "nat90", "nat91", "nat92", "nat93", "nat94", "nat95",
200b725ae77Skettenis "nat96", "nat97", "nat98", "nat99", "nat100","nat101","nat102","nat103",
201b725ae77Skettenis "nat104","nat105","nat106","nat107","nat108","nat109","nat110","nat111",
202b725ae77Skettenis "nat112","nat113","nat114","nat115","nat116","nat117","nat118","nat119",
203b725ae77Skettenis "nat120","nat121","nat122","nat123","nat124","nat125","nat126","nat127",
204b725ae77Skettenis
205b725ae77Skettenis "bof",
206b725ae77Skettenis
207b725ae77Skettenis "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
208b725ae77Skettenis "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
209b725ae77Skettenis "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
210b725ae77Skettenis "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",
211b725ae77Skettenis "r64", "r65", "r66", "r67", "r68", "r69", "r70", "r71",
212b725ae77Skettenis "r72", "r73", "r74", "r75", "r76", "r77", "r78", "r79",
213b725ae77Skettenis "r80", "r81", "r82", "r83", "r84", "r85", "r86", "r87",
214b725ae77Skettenis "r88", "r89", "r90", "r91", "r92", "r93", "r94", "r95",
215b725ae77Skettenis "r96", "r97", "r98", "r99", "r100", "r101", "r102", "r103",
216b725ae77Skettenis "r104", "r105", "r106", "r107", "r108", "r109", "r110", "r111",
217b725ae77Skettenis "r112", "r113", "r114", "r115", "r116", "r117", "r118", "r119",
218b725ae77Skettenis "r120", "r121", "r122", "r123", "r124", "r125", "r126", "r127",
219b725ae77Skettenis
220b725ae77Skettenis "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
221b725ae77Skettenis "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
222b725ae77Skettenis "p16", "p17", "p18", "p19", "p20", "p21", "p22", "p23",
223b725ae77Skettenis "p24", "p25", "p26", "p27", "p28", "p29", "p30", "p31",
224b725ae77Skettenis "p32", "p33", "p34", "p35", "p36", "p37", "p38", "p39",
225b725ae77Skettenis "p40", "p41", "p42", "p43", "p44", "p45", "p46", "p47",
226b725ae77Skettenis "p48", "p49", "p50", "p51", "p52", "p53", "p54", "p55",
227b725ae77Skettenis "p56", "p57", "p58", "p59", "p60", "p61", "p62", "p63",
228b725ae77Skettenis };
229b725ae77Skettenis
230b725ae77Skettenis struct ia64_frame_cache
231b725ae77Skettenis {
232b725ae77Skettenis CORE_ADDR base; /* frame pointer base for frame */
233b725ae77Skettenis CORE_ADDR pc; /* function start pc for frame */
234b725ae77Skettenis CORE_ADDR saved_sp; /* stack pointer for frame */
235b725ae77Skettenis CORE_ADDR bsp; /* points at r32 for the current frame */
236b725ae77Skettenis CORE_ADDR cfm; /* cfm value for current frame */
237b725ae77Skettenis CORE_ADDR prev_cfm; /* cfm value for previous frame */
238b725ae77Skettenis int frameless;
239b725ae77Skettenis int sof; /* Size of frame (decoded from cfm value) */
240b725ae77Skettenis int sol; /* Size of locals (decoded from cfm value) */
241b725ae77Skettenis int sor; /* Number of rotating registers. (decoded from cfm value) */
242b725ae77Skettenis CORE_ADDR after_prologue;
243b725ae77Skettenis /* Address of first instruction after the last
244b725ae77Skettenis prologue instruction; Note that there may
245b725ae77Skettenis be instructions from the function's body
246b725ae77Skettenis intermingled with the prologue. */
247b725ae77Skettenis int mem_stack_frame_size;
248b725ae77Skettenis /* Size of the memory stack frame (may be zero),
249b725ae77Skettenis or -1 if it has not been determined yet. */
250b725ae77Skettenis int fp_reg; /* Register number (if any) used a frame pointer
251b725ae77Skettenis for this frame. 0 if no register is being used
252b725ae77Skettenis as the frame pointer. */
253b725ae77Skettenis
254b725ae77Skettenis /* Saved registers. */
255b725ae77Skettenis CORE_ADDR saved_regs[NUM_IA64_RAW_REGS];
256b725ae77Skettenis
257b725ae77Skettenis };
258b725ae77Skettenis
259b725ae77Skettenis struct gdbarch_tdep
260b725ae77Skettenis {
261b725ae77Skettenis CORE_ADDR (*sigcontext_register_address) (CORE_ADDR, int);
262b725ae77Skettenis /* OS specific function which, given a frame address
263b725ae77Skettenis and register number, returns the offset to the
264b725ae77Skettenis given register from the start of the frame. */
265b725ae77Skettenis CORE_ADDR (*find_global_pointer) (CORE_ADDR);
266b725ae77Skettenis };
267b725ae77Skettenis
268b725ae77Skettenis #define SIGCONTEXT_REGISTER_ADDRESS \
269b725ae77Skettenis (gdbarch_tdep (current_gdbarch)->sigcontext_register_address)
270b725ae77Skettenis #define FIND_GLOBAL_POINTER \
271b725ae77Skettenis (gdbarch_tdep (current_gdbarch)->find_global_pointer)
272b725ae77Skettenis
273b725ae77Skettenis int
ia64_register_reggroup_p(struct gdbarch * gdbarch,int regnum,struct reggroup * group)274b725ae77Skettenis ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
275b725ae77Skettenis struct reggroup *group)
276b725ae77Skettenis {
277b725ae77Skettenis int vector_p;
278b725ae77Skettenis int float_p;
279b725ae77Skettenis int raw_p;
280b725ae77Skettenis if (group == all_reggroup)
281b725ae77Skettenis return 1;
282b725ae77Skettenis vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
283b725ae77Skettenis float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
284b725ae77Skettenis raw_p = regnum < NUM_IA64_RAW_REGS;
285b725ae77Skettenis if (group == float_reggroup)
286b725ae77Skettenis return float_p;
287b725ae77Skettenis if (group == vector_reggroup)
288b725ae77Skettenis return vector_p;
289b725ae77Skettenis if (group == general_reggroup)
290b725ae77Skettenis return (!vector_p && !float_p);
291b725ae77Skettenis if (group == save_reggroup || group == restore_reggroup)
292b725ae77Skettenis return raw_p;
293b725ae77Skettenis return 0;
294b725ae77Skettenis }
295b725ae77Skettenis
296b725ae77Skettenis static const char *
ia64_register_name(int reg)297b725ae77Skettenis ia64_register_name (int reg)
298b725ae77Skettenis {
299b725ae77Skettenis return ia64_register_names[reg];
300b725ae77Skettenis }
301b725ae77Skettenis
302b725ae77Skettenis struct type *
ia64_register_type(struct gdbarch * arch,int reg)303b725ae77Skettenis ia64_register_type (struct gdbarch *arch, int reg)
304b725ae77Skettenis {
305b725ae77Skettenis if (reg >= IA64_FR0_REGNUM && reg <= IA64_FR127_REGNUM)
306b725ae77Skettenis return builtin_type_ia64_ext;
307b725ae77Skettenis else
308b725ae77Skettenis return builtin_type_long;
309b725ae77Skettenis }
310b725ae77Skettenis
311b725ae77Skettenis static int
ia64_dwarf_reg_to_regnum(int reg)312b725ae77Skettenis ia64_dwarf_reg_to_regnum (int reg)
313b725ae77Skettenis {
314b725ae77Skettenis if (reg >= IA64_GR32_REGNUM && reg <= IA64_GR127_REGNUM)
315b725ae77Skettenis return V32_REGNUM + (reg - IA64_GR32_REGNUM);
316b725ae77Skettenis return reg;
317b725ae77Skettenis }
318b725ae77Skettenis
319b725ae77Skettenis static int
floatformat_valid(const struct floatformat * fmt,const char * from)320b725ae77Skettenis floatformat_valid (const struct floatformat *fmt, const char *from)
321b725ae77Skettenis {
322b725ae77Skettenis return 1;
323b725ae77Skettenis }
324b725ae77Skettenis
325b725ae77Skettenis const struct floatformat floatformat_ia64_ext =
326b725ae77Skettenis {
327b725ae77Skettenis floatformat_little, 82, 0, 1, 17, 65535, 0x1ffff, 18, 64,
328b725ae77Skettenis floatformat_intbit_yes, "floatformat_ia64_ext", floatformat_valid
329b725ae77Skettenis };
330b725ae77Skettenis
331b725ae77Skettenis
332b725ae77Skettenis /* Extract ``len'' bits from an instruction bundle starting at
333b725ae77Skettenis bit ``from''. */
334b725ae77Skettenis
335b725ae77Skettenis static long long
extract_bit_field(char * bundle,int from,int len)336b725ae77Skettenis extract_bit_field (char *bundle, int from, int len)
337b725ae77Skettenis {
338b725ae77Skettenis long long result = 0LL;
339b725ae77Skettenis int to = from + len;
340b725ae77Skettenis int from_byte = from / 8;
341b725ae77Skettenis int to_byte = to / 8;
342b725ae77Skettenis unsigned char *b = (unsigned char *) bundle;
343b725ae77Skettenis unsigned char c;
344b725ae77Skettenis int lshift;
345b725ae77Skettenis int i;
346b725ae77Skettenis
347b725ae77Skettenis c = b[from_byte];
348b725ae77Skettenis if (from_byte == to_byte)
349b725ae77Skettenis c = ((unsigned char) (c << (8 - to % 8))) >> (8 - to % 8);
350b725ae77Skettenis result = c >> (from % 8);
351b725ae77Skettenis lshift = 8 - (from % 8);
352b725ae77Skettenis
353b725ae77Skettenis for (i = from_byte+1; i < to_byte; i++)
354b725ae77Skettenis {
355b725ae77Skettenis result |= ((long long) b[i]) << lshift;
356b725ae77Skettenis lshift += 8;
357b725ae77Skettenis }
358b725ae77Skettenis
359b725ae77Skettenis if (from_byte < to_byte && (to % 8 != 0))
360b725ae77Skettenis {
361b725ae77Skettenis c = b[to_byte];
362b725ae77Skettenis c = ((unsigned char) (c << (8 - to % 8))) >> (8 - to % 8);
363b725ae77Skettenis result |= ((long long) c) << lshift;
364b725ae77Skettenis }
365b725ae77Skettenis
366b725ae77Skettenis return result;
367b725ae77Skettenis }
368b725ae77Skettenis
369b725ae77Skettenis /* Replace the specified bits in an instruction bundle */
370b725ae77Skettenis
371b725ae77Skettenis static void
replace_bit_field(char * bundle,long long val,int from,int len)372b725ae77Skettenis replace_bit_field (char *bundle, long long val, int from, int len)
373b725ae77Skettenis {
374b725ae77Skettenis int to = from + len;
375b725ae77Skettenis int from_byte = from / 8;
376b725ae77Skettenis int to_byte = to / 8;
377b725ae77Skettenis unsigned char *b = (unsigned char *) bundle;
378b725ae77Skettenis unsigned char c;
379b725ae77Skettenis
380b725ae77Skettenis if (from_byte == to_byte)
381b725ae77Skettenis {
382b725ae77Skettenis unsigned char left, right;
383b725ae77Skettenis c = b[from_byte];
384b725ae77Skettenis left = (c >> (to % 8)) << (to % 8);
385b725ae77Skettenis right = ((unsigned char) (c << (8 - from % 8))) >> (8 - from % 8);
386b725ae77Skettenis c = (unsigned char) (val & 0xff);
387b725ae77Skettenis c = (unsigned char) (c << (from % 8 + 8 - to % 8)) >> (8 - to % 8);
388b725ae77Skettenis c |= right | left;
389b725ae77Skettenis b[from_byte] = c;
390b725ae77Skettenis }
391b725ae77Skettenis else
392b725ae77Skettenis {
393b725ae77Skettenis int i;
394b725ae77Skettenis c = b[from_byte];
395b725ae77Skettenis c = ((unsigned char) (c << (8 - from % 8))) >> (8 - from % 8);
396b725ae77Skettenis c = c | (val << (from % 8));
397b725ae77Skettenis b[from_byte] = c;
398b725ae77Skettenis val >>= 8 - from % 8;
399b725ae77Skettenis
400b725ae77Skettenis for (i = from_byte+1; i < to_byte; i++)
401b725ae77Skettenis {
402b725ae77Skettenis c = val & 0xff;
403b725ae77Skettenis val >>= 8;
404b725ae77Skettenis b[i] = c;
405b725ae77Skettenis }
406b725ae77Skettenis
407b725ae77Skettenis if (to % 8 != 0)
408b725ae77Skettenis {
409b725ae77Skettenis unsigned char cv = (unsigned char) val;
410b725ae77Skettenis c = b[to_byte];
411b725ae77Skettenis c = c >> (to % 8) << (to % 8);
412b725ae77Skettenis c |= ((unsigned char) (cv << (8 - to % 8))) >> (8 - to % 8);
413b725ae77Skettenis b[to_byte] = c;
414b725ae77Skettenis }
415b725ae77Skettenis }
416b725ae77Skettenis }
417b725ae77Skettenis
418b725ae77Skettenis /* Return the contents of slot N (for N = 0, 1, or 2) in
419b725ae77Skettenis and instruction bundle */
420b725ae77Skettenis
421b725ae77Skettenis static long long
slotN_contents(char * bundle,int slotnum)422b725ae77Skettenis slotN_contents (char *bundle, int slotnum)
423b725ae77Skettenis {
424b725ae77Skettenis return extract_bit_field (bundle, 5+41*slotnum, 41);
425b725ae77Skettenis }
426b725ae77Skettenis
427b725ae77Skettenis /* Store an instruction in an instruction bundle */
428b725ae77Skettenis
429b725ae77Skettenis static void
replace_slotN_contents(char * bundle,long long instr,int slotnum)430b725ae77Skettenis replace_slotN_contents (char *bundle, long long instr, int slotnum)
431b725ae77Skettenis {
432b725ae77Skettenis replace_bit_field (bundle, instr, 5+41*slotnum, 41);
433b725ae77Skettenis }
434b725ae77Skettenis
435b725ae77Skettenis static enum instruction_type template_encoding_table[32][3] =
436b725ae77Skettenis {
437b725ae77Skettenis { M, I, I }, /* 00 */
438b725ae77Skettenis { M, I, I }, /* 01 */
439b725ae77Skettenis { M, I, I }, /* 02 */
440b725ae77Skettenis { M, I, I }, /* 03 */
441b725ae77Skettenis { M, L, X }, /* 04 */
442b725ae77Skettenis { M, L, X }, /* 05 */
443b725ae77Skettenis { undefined, undefined, undefined }, /* 06 */
444b725ae77Skettenis { undefined, undefined, undefined }, /* 07 */
445b725ae77Skettenis { M, M, I }, /* 08 */
446b725ae77Skettenis { M, M, I }, /* 09 */
447b725ae77Skettenis { M, M, I }, /* 0A */
448b725ae77Skettenis { M, M, I }, /* 0B */
449b725ae77Skettenis { M, F, I }, /* 0C */
450b725ae77Skettenis { M, F, I }, /* 0D */
451b725ae77Skettenis { M, M, F }, /* 0E */
452b725ae77Skettenis { M, M, F }, /* 0F */
453b725ae77Skettenis { M, I, B }, /* 10 */
454b725ae77Skettenis { M, I, B }, /* 11 */
455b725ae77Skettenis { M, B, B }, /* 12 */
456b725ae77Skettenis { M, B, B }, /* 13 */
457b725ae77Skettenis { undefined, undefined, undefined }, /* 14 */
458b725ae77Skettenis { undefined, undefined, undefined }, /* 15 */
459b725ae77Skettenis { B, B, B }, /* 16 */
460b725ae77Skettenis { B, B, B }, /* 17 */
461b725ae77Skettenis { M, M, B }, /* 18 */
462b725ae77Skettenis { M, M, B }, /* 19 */
463b725ae77Skettenis { undefined, undefined, undefined }, /* 1A */
464b725ae77Skettenis { undefined, undefined, undefined }, /* 1B */
465b725ae77Skettenis { M, F, B }, /* 1C */
466b725ae77Skettenis { M, F, B }, /* 1D */
467b725ae77Skettenis { undefined, undefined, undefined }, /* 1E */
468b725ae77Skettenis { undefined, undefined, undefined }, /* 1F */
469b725ae77Skettenis };
470b725ae77Skettenis
471b725ae77Skettenis /* Fetch and (partially) decode an instruction at ADDR and return the
472b725ae77Skettenis address of the next instruction to fetch. */
473b725ae77Skettenis
474b725ae77Skettenis static CORE_ADDR
fetch_instruction(CORE_ADDR addr,instruction_type * it,long long * instr)475b725ae77Skettenis fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr)
476b725ae77Skettenis {
477b725ae77Skettenis char bundle[BUNDLE_LEN];
478b725ae77Skettenis int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
479b725ae77Skettenis long long template;
480b725ae77Skettenis int val;
481b725ae77Skettenis
482b725ae77Skettenis /* Warn about slot numbers greater than 2. We used to generate
483b725ae77Skettenis an error here on the assumption that the user entered an invalid
484b725ae77Skettenis address. But, sometimes GDB itself requests an invalid address.
485b725ae77Skettenis This can (easily) happen when execution stops in a function for
486b725ae77Skettenis which there are no symbols. The prologue scanner will attempt to
487b725ae77Skettenis find the beginning of the function - if the nearest symbol
488b725ae77Skettenis happens to not be aligned on a bundle boundary (16 bytes), the
489b725ae77Skettenis resulting starting address will cause GDB to think that the slot
490b725ae77Skettenis number is too large.
491b725ae77Skettenis
492b725ae77Skettenis So we warn about it and set the slot number to zero. It is
493b725ae77Skettenis not necessarily a fatal condition, particularly if debugging
494b725ae77Skettenis at the assembly language level. */
495b725ae77Skettenis if (slotnum > 2)
496b725ae77Skettenis {
497b725ae77Skettenis warning ("Can't fetch instructions for slot numbers greater than 2.\n"
498b725ae77Skettenis "Using slot 0 instead");
499b725ae77Skettenis slotnum = 0;
500b725ae77Skettenis }
501b725ae77Skettenis
502b725ae77Skettenis addr &= ~0x0f;
503b725ae77Skettenis
504b725ae77Skettenis val = target_read_memory (addr, bundle, BUNDLE_LEN);
505b725ae77Skettenis
506b725ae77Skettenis if (val != 0)
507b725ae77Skettenis return 0;
508b725ae77Skettenis
509b725ae77Skettenis *instr = slotN_contents (bundle, slotnum);
510b725ae77Skettenis template = extract_bit_field (bundle, 0, 5);
511b725ae77Skettenis *it = template_encoding_table[(int)template][slotnum];
512b725ae77Skettenis
513b725ae77Skettenis if (slotnum == 2 || (slotnum == 1 && *it == L))
514b725ae77Skettenis addr += 16;
515b725ae77Skettenis else
516b725ae77Skettenis addr += (slotnum + 1) * SLOT_MULTIPLIER;
517b725ae77Skettenis
518b725ae77Skettenis return addr;
519b725ae77Skettenis }
520b725ae77Skettenis
521b725ae77Skettenis /* There are 5 different break instructions (break.i, break.b,
522b725ae77Skettenis break.m, break.f, and break.x), but they all have the same
523b725ae77Skettenis encoding. (The five bit template in the low five bits of the
524b725ae77Skettenis instruction bundle distinguishes one from another.)
525b725ae77Skettenis
526b725ae77Skettenis The runtime architecture manual specifies that break instructions
527b725ae77Skettenis used for debugging purposes must have the upper two bits of the 21
528b725ae77Skettenis bit immediate set to a 0 and a 1 respectively. A breakpoint
529b725ae77Skettenis instruction encodes the most significant bit of its 21 bit
530b725ae77Skettenis immediate at bit 36 of the 41 bit instruction. The penultimate msb
531b725ae77Skettenis is at bit 25 which leads to the pattern below.
532b725ae77Skettenis
533b725ae77Skettenis Originally, I had this set up to do, e.g, a "break.i 0x80000" But
534b725ae77Skettenis it turns out that 0x80000 was used as the syscall break in the early
535b725ae77Skettenis simulators. So I changed the pattern slightly to do "break.i 0x080001"
536b725ae77Skettenis instead. But that didn't work either (I later found out that this
537b725ae77Skettenis pattern was used by the simulator that I was using.) So I ended up
538b725ae77Skettenis using the pattern seen below. */
539b725ae77Skettenis
540b725ae77Skettenis #if 0
541b725ae77Skettenis #define IA64_BREAKPOINT 0x00002000040LL
542b725ae77Skettenis #endif
543b725ae77Skettenis #define IA64_BREAKPOINT 0x00003333300LL
544b725ae77Skettenis
545b725ae77Skettenis static int
ia64_memory_insert_breakpoint(CORE_ADDR addr,char * contents_cache)546b725ae77Skettenis ia64_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
547b725ae77Skettenis {
548b725ae77Skettenis char bundle[BUNDLE_LEN];
549b725ae77Skettenis int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
550b725ae77Skettenis long long instr;
551b725ae77Skettenis int val;
552b725ae77Skettenis int template;
553b725ae77Skettenis
554b725ae77Skettenis if (slotnum > 2)
555b725ae77Skettenis error("Can't insert breakpoint for slot numbers greater than 2.");
556b725ae77Skettenis
557b725ae77Skettenis addr &= ~0x0f;
558b725ae77Skettenis
559b725ae77Skettenis val = target_read_memory (addr, bundle, BUNDLE_LEN);
560b725ae77Skettenis
561b725ae77Skettenis /* Check for L type instruction in 2nd slot, if present then
562b725ae77Skettenis bump up the slot number to the 3rd slot */
563b725ae77Skettenis template = extract_bit_field (bundle, 0, 5);
564b725ae77Skettenis if (slotnum == 1 && template_encoding_table[template][1] == L)
565b725ae77Skettenis {
566b725ae77Skettenis slotnum = 2;
567b725ae77Skettenis }
568b725ae77Skettenis
569b725ae77Skettenis instr = slotN_contents (bundle, slotnum);
570b725ae77Skettenis memcpy(contents_cache, &instr, sizeof(instr));
571b725ae77Skettenis replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum);
572b725ae77Skettenis if (val == 0)
573b725ae77Skettenis target_write_memory (addr, bundle, BUNDLE_LEN);
574b725ae77Skettenis
575b725ae77Skettenis return val;
576b725ae77Skettenis }
577b725ae77Skettenis
578b725ae77Skettenis static int
ia64_memory_remove_breakpoint(CORE_ADDR addr,char * contents_cache)579b725ae77Skettenis ia64_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
580b725ae77Skettenis {
581b725ae77Skettenis char bundle[BUNDLE_LEN];
582b725ae77Skettenis int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER;
583b725ae77Skettenis long long instr;
584b725ae77Skettenis int val;
585b725ae77Skettenis int template;
586b725ae77Skettenis
587b725ae77Skettenis addr &= ~0x0f;
588b725ae77Skettenis
589b725ae77Skettenis val = target_read_memory (addr, bundle, BUNDLE_LEN);
590b725ae77Skettenis
591b725ae77Skettenis /* Check for L type instruction in 2nd slot, if present then
592b725ae77Skettenis bump up the slot number to the 3rd slot */
593b725ae77Skettenis template = extract_bit_field (bundle, 0, 5);
594b725ae77Skettenis if (slotnum == 1 && template_encoding_table[template][1] == L)
595b725ae77Skettenis {
596b725ae77Skettenis slotnum = 2;
597b725ae77Skettenis }
598b725ae77Skettenis
599b725ae77Skettenis memcpy (&instr, contents_cache, sizeof instr);
600b725ae77Skettenis replace_slotN_contents (bundle, instr, slotnum);
601b725ae77Skettenis if (val == 0)
602b725ae77Skettenis target_write_memory (addr, bundle, BUNDLE_LEN);
603b725ae77Skettenis
604b725ae77Skettenis return val;
605b725ae77Skettenis }
606b725ae77Skettenis
607b725ae77Skettenis /* We don't really want to use this, but remote.c needs to call it in order
608b725ae77Skettenis to figure out if Z-packets are supported or not. Oh, well. */
609b725ae77Skettenis const unsigned char *
ia64_breakpoint_from_pc(CORE_ADDR * pcptr,int * lenptr)610b725ae77Skettenis ia64_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
611b725ae77Skettenis {
612b725ae77Skettenis static unsigned char breakpoint[] =
613b725ae77Skettenis { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
614b725ae77Skettenis *lenptr = sizeof (breakpoint);
615b725ae77Skettenis #if 0
616b725ae77Skettenis *pcptr &= ~0x0f;
617b725ae77Skettenis #endif
618b725ae77Skettenis return breakpoint;
619b725ae77Skettenis }
620b725ae77Skettenis
621b725ae77Skettenis static CORE_ADDR
ia64_read_pc(ptid_t ptid)622b725ae77Skettenis ia64_read_pc (ptid_t ptid)
623b725ae77Skettenis {
624b725ae77Skettenis CORE_ADDR psr_value = read_register_pid (IA64_PSR_REGNUM, ptid);
625b725ae77Skettenis CORE_ADDR pc_value = read_register_pid (IA64_IP_REGNUM, ptid);
626b725ae77Skettenis int slot_num = (psr_value >> 41) & 3;
627b725ae77Skettenis
628b725ae77Skettenis return pc_value | (slot_num * SLOT_MULTIPLIER);
629b725ae77Skettenis }
630b725ae77Skettenis
631b725ae77Skettenis void
ia64_write_pc(CORE_ADDR new_pc,ptid_t ptid)632b725ae77Skettenis ia64_write_pc (CORE_ADDR new_pc, ptid_t ptid)
633b725ae77Skettenis {
634b725ae77Skettenis int slot_num = (int) (new_pc & 0xf) / SLOT_MULTIPLIER;
635b725ae77Skettenis CORE_ADDR psr_value = read_register_pid (IA64_PSR_REGNUM, ptid);
636b725ae77Skettenis psr_value &= ~(3LL << 41);
637b725ae77Skettenis psr_value |= (CORE_ADDR)(slot_num & 0x3) << 41;
638b725ae77Skettenis
639b725ae77Skettenis new_pc &= ~0xfLL;
640b725ae77Skettenis
641b725ae77Skettenis write_register_pid (IA64_PSR_REGNUM, psr_value, ptid);
642b725ae77Skettenis write_register_pid (IA64_IP_REGNUM, new_pc, ptid);
643b725ae77Skettenis }
644b725ae77Skettenis
645b725ae77Skettenis #define IS_NaT_COLLECTION_ADDR(addr) ((((addr) >> 3) & 0x3f) == 0x3f)
646b725ae77Skettenis
647b725ae77Skettenis /* Returns the address of the slot that's NSLOTS slots away from
648b725ae77Skettenis the address ADDR. NSLOTS may be positive or negative. */
649b725ae77Skettenis static CORE_ADDR
rse_address_add(CORE_ADDR addr,int nslots)650b725ae77Skettenis rse_address_add(CORE_ADDR addr, int nslots)
651b725ae77Skettenis {
652b725ae77Skettenis CORE_ADDR new_addr;
653b725ae77Skettenis int mandatory_nat_slots = nslots / 63;
654b725ae77Skettenis int direction = nslots < 0 ? -1 : 1;
655b725ae77Skettenis
656b725ae77Skettenis new_addr = addr + 8 * (nslots + mandatory_nat_slots);
657b725ae77Skettenis
658b725ae77Skettenis if ((new_addr >> 9) != ((addr + 8 * 64 * mandatory_nat_slots) >> 9))
659b725ae77Skettenis new_addr += 8 * direction;
660b725ae77Skettenis
661b725ae77Skettenis if (IS_NaT_COLLECTION_ADDR(new_addr))
662b725ae77Skettenis new_addr += 8 * direction;
663b725ae77Skettenis
664b725ae77Skettenis return new_addr;
665b725ae77Skettenis }
666b725ae77Skettenis
667b725ae77Skettenis static void
ia64_pseudo_register_read(struct gdbarch * gdbarch,struct regcache * regcache,int regnum,void * buf)668b725ae77Skettenis ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
669b725ae77Skettenis int regnum, void *buf)
670b725ae77Skettenis {
671b725ae77Skettenis if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
672b725ae77Skettenis {
673b725ae77Skettenis ULONGEST bsp;
674b725ae77Skettenis ULONGEST cfm;
675b725ae77Skettenis CORE_ADDR reg;
676b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
677b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
678b725ae77Skettenis
679b725ae77Skettenis /* The bsp points at the end of the register frame so we
680b725ae77Skettenis subtract the size of frame from it to get start of register frame. */
681b725ae77Skettenis bsp = rse_address_add (bsp, -(cfm & 0x7f));
682b725ae77Skettenis
683b725ae77Skettenis if ((cfm & 0x7f) > regnum - V32_REGNUM)
684b725ae77Skettenis {
685b725ae77Skettenis ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
686b725ae77Skettenis reg = read_memory_integer ((CORE_ADDR)reg_addr, 8);
687b725ae77Skettenis store_unsigned_integer (buf, register_size (current_gdbarch, regnum), reg);
688b725ae77Skettenis }
689b725ae77Skettenis else
690b725ae77Skettenis store_unsigned_integer (buf, register_size (current_gdbarch, regnum), 0);
691b725ae77Skettenis }
692b725ae77Skettenis else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
693b725ae77Skettenis {
694b725ae77Skettenis ULONGEST unatN_val;
695b725ae77Skettenis ULONGEST unat;
696b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
697b725ae77Skettenis unatN_val = (unat & (1LL << (regnum - IA64_NAT0_REGNUM))) != 0;
698b725ae77Skettenis store_unsigned_integer (buf, register_size (current_gdbarch, regnum), unatN_val);
699b725ae77Skettenis }
700b725ae77Skettenis else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
701b725ae77Skettenis {
702b725ae77Skettenis ULONGEST natN_val = 0;
703b725ae77Skettenis ULONGEST bsp;
704b725ae77Skettenis ULONGEST cfm;
705b725ae77Skettenis CORE_ADDR gr_addr = 0;
706b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
707b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
708b725ae77Skettenis
709b725ae77Skettenis /* The bsp points at the end of the register frame so we
710b725ae77Skettenis subtract the size of frame from it to get start of register frame. */
711b725ae77Skettenis bsp = rse_address_add (bsp, -(cfm & 0x7f));
712b725ae77Skettenis
713b725ae77Skettenis if ((cfm & 0x7f) > regnum - V32_REGNUM)
714b725ae77Skettenis gr_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
715b725ae77Skettenis
716b725ae77Skettenis if (gr_addr != 0)
717b725ae77Skettenis {
718b725ae77Skettenis /* Compute address of nat collection bits. */
719b725ae77Skettenis CORE_ADDR nat_addr = gr_addr | 0x1f8;
720b725ae77Skettenis CORE_ADDR nat_collection;
721b725ae77Skettenis int nat_bit;
722b725ae77Skettenis /* If our nat collection address is bigger than bsp, we have to get
723b725ae77Skettenis the nat collection from rnat. Otherwise, we fetch the nat
724b725ae77Skettenis collection from the computed address. */
725b725ae77Skettenis if (nat_addr >= bsp)
726b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM, &nat_collection);
727b725ae77Skettenis else
728b725ae77Skettenis nat_collection = read_memory_integer (nat_addr, 8);
729b725ae77Skettenis nat_bit = (gr_addr >> 3) & 0x3f;
730b725ae77Skettenis natN_val = (nat_collection >> nat_bit) & 1;
731b725ae77Skettenis }
732b725ae77Skettenis
733b725ae77Skettenis store_unsigned_integer (buf, register_size (current_gdbarch, regnum), natN_val);
734b725ae77Skettenis }
735b725ae77Skettenis else if (regnum == VBOF_REGNUM)
736b725ae77Skettenis {
737b725ae77Skettenis /* A virtual register frame start is provided for user convenience.
738b725ae77Skettenis It can be calculated as the bsp - sof (sizeof frame). */
739b725ae77Skettenis ULONGEST bsp, vbsp;
740b725ae77Skettenis ULONGEST cfm;
741b725ae77Skettenis CORE_ADDR reg;
742b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
743b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
744b725ae77Skettenis
745b725ae77Skettenis /* The bsp points at the end of the register frame so we
746b725ae77Skettenis subtract the size of frame from it to get beginning of frame. */
747b725ae77Skettenis vbsp = rse_address_add (bsp, -(cfm & 0x7f));
748b725ae77Skettenis store_unsigned_integer (buf, register_size (current_gdbarch, regnum), vbsp);
749b725ae77Skettenis }
750b725ae77Skettenis else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
751b725ae77Skettenis {
752b725ae77Skettenis ULONGEST pr;
753b725ae77Skettenis ULONGEST cfm;
754b725ae77Skettenis ULONGEST prN_val;
755b725ae77Skettenis CORE_ADDR reg;
756b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr);
757b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
758b725ae77Skettenis
759b725ae77Skettenis if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
760b725ae77Skettenis {
761b725ae77Skettenis /* Fetch predicate register rename base from current frame
762b725ae77Skettenis marker for this frame. */
763b725ae77Skettenis int rrb_pr = (cfm >> 32) & 0x3f;
764b725ae77Skettenis
765b725ae77Skettenis /* Adjust the register number to account for register rotation. */
766b725ae77Skettenis regnum = VP16_REGNUM
767b725ae77Skettenis + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
768b725ae77Skettenis }
769b725ae77Skettenis prN_val = (pr & (1LL << (regnum - VP0_REGNUM))) != 0;
770b725ae77Skettenis store_unsigned_integer (buf, register_size (current_gdbarch, regnum), prN_val);
771b725ae77Skettenis }
772b725ae77Skettenis else
773b725ae77Skettenis memset (buf, 0, register_size (current_gdbarch, regnum));
774b725ae77Skettenis }
775b725ae77Skettenis
776b725ae77Skettenis static void
ia64_pseudo_register_write(struct gdbarch * gdbarch,struct regcache * regcache,int regnum,const void * buf)777b725ae77Skettenis ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
778b725ae77Skettenis int regnum, const void *buf)
779b725ae77Skettenis {
780b725ae77Skettenis if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
781b725ae77Skettenis {
782b725ae77Skettenis ULONGEST bsp;
783b725ae77Skettenis ULONGEST cfm;
784b725ae77Skettenis CORE_ADDR reg;
785b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
786b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
787b725ae77Skettenis
788b725ae77Skettenis bsp = rse_address_add (bsp, -(cfm & 0x7f));
789b725ae77Skettenis
790b725ae77Skettenis if ((cfm & 0x7f) > regnum - V32_REGNUM)
791b725ae77Skettenis {
792b725ae77Skettenis ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
793b725ae77Skettenis write_memory (reg_addr, (void *)buf, 8);
794b725ae77Skettenis }
795b725ae77Skettenis }
796b725ae77Skettenis else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
797b725ae77Skettenis {
798b725ae77Skettenis ULONGEST unatN_val, unat, unatN_mask;
799b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
800b725ae77Skettenis unatN_val = extract_unsigned_integer (buf, register_size (current_gdbarch, regnum));
801b725ae77Skettenis unatN_mask = (1LL << (regnum - IA64_NAT0_REGNUM));
802b725ae77Skettenis if (unatN_val == 0)
803b725ae77Skettenis unat &= ~unatN_mask;
804b725ae77Skettenis else if (unatN_val == 1)
805b725ae77Skettenis unat |= unatN_mask;
806b725ae77Skettenis regcache_cooked_write_unsigned (regcache, IA64_UNAT_REGNUM, unat);
807b725ae77Skettenis }
808b725ae77Skettenis else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
809b725ae77Skettenis {
810b725ae77Skettenis ULONGEST natN_val;
811b725ae77Skettenis ULONGEST bsp;
812b725ae77Skettenis ULONGEST cfm;
813b725ae77Skettenis CORE_ADDR gr_addr = 0;
814b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
815b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
816b725ae77Skettenis
817b725ae77Skettenis /* The bsp points at the end of the register frame so we
818b725ae77Skettenis subtract the size of frame from it to get start of register frame. */
819b725ae77Skettenis bsp = rse_address_add (bsp, -(cfm & 0x7f));
820b725ae77Skettenis
821b725ae77Skettenis if ((cfm & 0x7f) > regnum - V32_REGNUM)
822b725ae77Skettenis gr_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
823b725ae77Skettenis
824b725ae77Skettenis natN_val = extract_unsigned_integer (buf, register_size (current_gdbarch, regnum));
825b725ae77Skettenis
826b725ae77Skettenis if (gr_addr != 0 && (natN_val == 0 || natN_val == 1))
827b725ae77Skettenis {
828b725ae77Skettenis /* Compute address of nat collection bits. */
829b725ae77Skettenis CORE_ADDR nat_addr = gr_addr | 0x1f8;
830b725ae77Skettenis CORE_ADDR nat_collection;
831b725ae77Skettenis int natN_bit = (gr_addr >> 3) & 0x3f;
832b725ae77Skettenis ULONGEST natN_mask = (1LL << natN_bit);
833b725ae77Skettenis /* If our nat collection address is bigger than bsp, we have to get
834b725ae77Skettenis the nat collection from rnat. Otherwise, we fetch the nat
835b725ae77Skettenis collection from the computed address. */
836b725ae77Skettenis if (nat_addr >= bsp)
837b725ae77Skettenis {
838b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM, &nat_collection);
839b725ae77Skettenis if (natN_val)
840b725ae77Skettenis nat_collection |= natN_mask;
841b725ae77Skettenis else
842b725ae77Skettenis nat_collection &= ~natN_mask;
843b725ae77Skettenis regcache_cooked_write_unsigned (regcache, IA64_RNAT_REGNUM, nat_collection);
844b725ae77Skettenis }
845b725ae77Skettenis else
846b725ae77Skettenis {
847b725ae77Skettenis char nat_buf[8];
848b725ae77Skettenis nat_collection = read_memory_integer (nat_addr, 8);
849b725ae77Skettenis if (natN_val)
850b725ae77Skettenis nat_collection |= natN_mask;
851b725ae77Skettenis else
852b725ae77Skettenis nat_collection &= ~natN_mask;
853b725ae77Skettenis store_unsigned_integer (nat_buf, register_size (current_gdbarch, regnum), nat_collection);
854b725ae77Skettenis write_memory (nat_addr, nat_buf, 8);
855b725ae77Skettenis }
856b725ae77Skettenis }
857b725ae77Skettenis }
858b725ae77Skettenis else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
859b725ae77Skettenis {
860b725ae77Skettenis ULONGEST pr;
861b725ae77Skettenis ULONGEST cfm;
862b725ae77Skettenis ULONGEST prN_val;
863b725ae77Skettenis ULONGEST prN_mask;
864b725ae77Skettenis
865b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr);
866b725ae77Skettenis regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
867b725ae77Skettenis
868b725ae77Skettenis if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
869b725ae77Skettenis {
870b725ae77Skettenis /* Fetch predicate register rename base from current frame
871b725ae77Skettenis marker for this frame. */
872b725ae77Skettenis int rrb_pr = (cfm >> 32) & 0x3f;
873b725ae77Skettenis
874b725ae77Skettenis /* Adjust the register number to account for register rotation. */
875b725ae77Skettenis regnum = VP16_REGNUM
876b725ae77Skettenis + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
877b725ae77Skettenis }
878b725ae77Skettenis prN_val = extract_unsigned_integer (buf, register_size (current_gdbarch, regnum));
879b725ae77Skettenis prN_mask = (1LL << (regnum - VP0_REGNUM));
880b725ae77Skettenis if (prN_val == 0)
881b725ae77Skettenis pr &= ~prN_mask;
882b725ae77Skettenis else if (prN_val == 1)
883b725ae77Skettenis pr |= prN_mask;
884b725ae77Skettenis regcache_cooked_write_unsigned (regcache, IA64_PR_REGNUM, pr);
885b725ae77Skettenis }
886b725ae77Skettenis }
887b725ae77Skettenis
888b725ae77Skettenis /* The ia64 needs to convert between various ieee floating-point formats
889b725ae77Skettenis and the special ia64 floating point register format. */
890b725ae77Skettenis
891b725ae77Skettenis static int
ia64_convert_register_p(int regno,struct type * type)892b725ae77Skettenis ia64_convert_register_p (int regno, struct type *type)
893b725ae77Skettenis {
894b725ae77Skettenis return (regno >= IA64_FR0_REGNUM && regno <= IA64_FR127_REGNUM);
895b725ae77Skettenis }
896b725ae77Skettenis
897b725ae77Skettenis static void
ia64_register_to_value(struct frame_info * frame,int regnum,struct type * valtype,void * out)898b725ae77Skettenis ia64_register_to_value (struct frame_info *frame, int regnum,
899b725ae77Skettenis struct type *valtype, void *out)
900b725ae77Skettenis {
901b725ae77Skettenis char in[MAX_REGISTER_SIZE];
902b725ae77Skettenis frame_register_read (frame, regnum, in);
903b725ae77Skettenis convert_typed_floating (in, builtin_type_ia64_ext, out, valtype);
904b725ae77Skettenis }
905b725ae77Skettenis
906b725ae77Skettenis static void
ia64_value_to_register(struct frame_info * frame,int regnum,struct type * valtype,const void * in)907b725ae77Skettenis ia64_value_to_register (struct frame_info *frame, int regnum,
908b725ae77Skettenis struct type *valtype, const void *in)
909b725ae77Skettenis {
910b725ae77Skettenis char out[MAX_REGISTER_SIZE];
911b725ae77Skettenis convert_typed_floating (in, valtype, out, builtin_type_ia64_ext);
912b725ae77Skettenis put_frame_register (frame, regnum, out);
913b725ae77Skettenis }
914b725ae77Skettenis
915b725ae77Skettenis
916b725ae77Skettenis /* Limit the number of skipped non-prologue instructions since examining
917b725ae77Skettenis of the prologue is expensive. */
918b725ae77Skettenis static int max_skip_non_prologue_insns = 40;
919b725ae77Skettenis
920b725ae77Skettenis /* Given PC representing the starting address of a function, and
921b725ae77Skettenis LIM_PC which is the (sloppy) limit to which to scan when looking
922b725ae77Skettenis for a prologue, attempt to further refine this limit by using
923b725ae77Skettenis the line data in the symbol table. If successful, a better guess
924b725ae77Skettenis on where the prologue ends is returned, otherwise the previous
925b725ae77Skettenis value of lim_pc is returned. TRUST_LIMIT is a pointer to a flag
926b725ae77Skettenis which will be set to indicate whether the returned limit may be
927b725ae77Skettenis used with no further scanning in the event that the function is
928b725ae77Skettenis frameless. */
929b725ae77Skettenis
930b725ae77Skettenis /* FIXME: cagney/2004-02-14: This function and logic have largely been
931b725ae77Skettenis superseded by skip_prologue_using_sal. */
932b725ae77Skettenis
933b725ae77Skettenis static CORE_ADDR
refine_prologue_limit(CORE_ADDR pc,CORE_ADDR lim_pc,int * trust_limit)934b725ae77Skettenis refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc, int *trust_limit)
935b725ae77Skettenis {
936b725ae77Skettenis struct symtab_and_line prologue_sal;
937b725ae77Skettenis CORE_ADDR start_pc = pc;
938b725ae77Skettenis
939b725ae77Skettenis /* Start off not trusting the limit. */
940b725ae77Skettenis *trust_limit = 0;
941b725ae77Skettenis
942b725ae77Skettenis prologue_sal = find_pc_line (pc, 0);
943b725ae77Skettenis if (prologue_sal.line != 0)
944b725ae77Skettenis {
945b725ae77Skettenis int i;
946b725ae77Skettenis CORE_ADDR addr = prologue_sal.end;
947b725ae77Skettenis
948b725ae77Skettenis /* Handle the case in which compiler's optimizer/scheduler
949b725ae77Skettenis has moved instructions into the prologue. We scan ahead
950b725ae77Skettenis in the function looking for address ranges whose corresponding
951b725ae77Skettenis line number is less than or equal to the first one that we
952b725ae77Skettenis found for the function. (It can be less than when the
953b725ae77Skettenis scheduler puts a body instruction before the first prologue
954b725ae77Skettenis instruction.) */
955b725ae77Skettenis for (i = 2 * max_skip_non_prologue_insns;
956b725ae77Skettenis i > 0 && (lim_pc == 0 || addr < lim_pc);
957b725ae77Skettenis i--)
958b725ae77Skettenis {
959b725ae77Skettenis struct symtab_and_line sal;
960b725ae77Skettenis
961b725ae77Skettenis sal = find_pc_line (addr, 0);
962b725ae77Skettenis if (sal.line == 0)
963b725ae77Skettenis break;
964b725ae77Skettenis if (sal.line <= prologue_sal.line
965b725ae77Skettenis && sal.symtab == prologue_sal.symtab)
966b725ae77Skettenis {
967b725ae77Skettenis prologue_sal = sal;
968b725ae77Skettenis }
969b725ae77Skettenis addr = sal.end;
970b725ae77Skettenis }
971b725ae77Skettenis
972b725ae77Skettenis if (lim_pc == 0 || prologue_sal.end < lim_pc)
973b725ae77Skettenis {
974b725ae77Skettenis lim_pc = prologue_sal.end;
975b725ae77Skettenis if (start_pc == get_pc_function_start (lim_pc))
976b725ae77Skettenis *trust_limit = 1;
977b725ae77Skettenis }
978b725ae77Skettenis }
979b725ae77Skettenis return lim_pc;
980b725ae77Skettenis }
981b725ae77Skettenis
982b725ae77Skettenis #define isScratch(_regnum_) ((_regnum_) == 2 || (_regnum_) == 3 \
983b725ae77Skettenis || (8 <= (_regnum_) && (_regnum_) <= 11) \
984b725ae77Skettenis || (14 <= (_regnum_) && (_regnum_) <= 31))
985b725ae77Skettenis #define imm9(_instr_) \
986b725ae77Skettenis ( ((((_instr_) & 0x01000000000LL) ? -1 : 0) << 8) \
987b725ae77Skettenis | (((_instr_) & 0x00008000000LL) >> 20) \
988b725ae77Skettenis | (((_instr_) & 0x00000001fc0LL) >> 6))
989b725ae77Skettenis
990b725ae77Skettenis /* Allocate and initialize a frame cache. */
991b725ae77Skettenis
992b725ae77Skettenis static struct ia64_frame_cache *
ia64_alloc_frame_cache(void)993b725ae77Skettenis ia64_alloc_frame_cache (void)
994b725ae77Skettenis {
995b725ae77Skettenis struct ia64_frame_cache *cache;
996b725ae77Skettenis int i;
997b725ae77Skettenis
998b725ae77Skettenis cache = FRAME_OBSTACK_ZALLOC (struct ia64_frame_cache);
999b725ae77Skettenis
1000b725ae77Skettenis /* Base address. */
1001b725ae77Skettenis cache->base = 0;
1002b725ae77Skettenis cache->pc = 0;
1003b725ae77Skettenis cache->cfm = 0;
1004b725ae77Skettenis cache->prev_cfm = 0;
1005b725ae77Skettenis cache->sof = 0;
1006b725ae77Skettenis cache->sol = 0;
1007b725ae77Skettenis cache->sor = 0;
1008b725ae77Skettenis cache->bsp = 0;
1009b725ae77Skettenis cache->fp_reg = 0;
1010b725ae77Skettenis cache->frameless = 1;
1011b725ae77Skettenis
1012b725ae77Skettenis for (i = 0; i < NUM_IA64_RAW_REGS; i++)
1013b725ae77Skettenis cache->saved_regs[i] = 0;
1014b725ae77Skettenis
1015b725ae77Skettenis return cache;
1016b725ae77Skettenis }
1017b725ae77Skettenis
1018b725ae77Skettenis static CORE_ADDR
examine_prologue(CORE_ADDR pc,CORE_ADDR lim_pc,struct frame_info * next_frame,struct ia64_frame_cache * cache)1019b725ae77Skettenis examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame, struct ia64_frame_cache *cache)
1020b725ae77Skettenis {
1021b725ae77Skettenis CORE_ADDR next_pc;
1022b725ae77Skettenis CORE_ADDR last_prologue_pc = pc;
1023b725ae77Skettenis instruction_type it;
1024b725ae77Skettenis long long instr;
1025b725ae77Skettenis int cfm_reg = 0;
1026b725ae77Skettenis int ret_reg = 0;
1027b725ae77Skettenis int fp_reg = 0;
1028b725ae77Skettenis int unat_save_reg = 0;
1029b725ae77Skettenis int pr_save_reg = 0;
1030b725ae77Skettenis int mem_stack_frame_size = 0;
1031b725ae77Skettenis int spill_reg = 0;
1032b725ae77Skettenis CORE_ADDR spill_addr = 0;
1033b725ae77Skettenis char instores[8];
1034b725ae77Skettenis char infpstores[8];
1035b725ae77Skettenis char reg_contents[256];
1036b725ae77Skettenis int trust_limit;
1037b725ae77Skettenis int frameless = 1;
1038b725ae77Skettenis int i;
1039b725ae77Skettenis CORE_ADDR addr;
1040b725ae77Skettenis char buf[8];
1041b725ae77Skettenis CORE_ADDR bof, sor, sol, sof, cfm, rrb_gr;
1042b725ae77Skettenis
1043b725ae77Skettenis memset (instores, 0, sizeof instores);
1044b725ae77Skettenis memset (infpstores, 0, sizeof infpstores);
1045b725ae77Skettenis memset (reg_contents, 0, sizeof reg_contents);
1046b725ae77Skettenis
1047b725ae77Skettenis if (cache->after_prologue != 0
1048b725ae77Skettenis && cache->after_prologue <= lim_pc)
1049b725ae77Skettenis return cache->after_prologue;
1050b725ae77Skettenis
1051b725ae77Skettenis lim_pc = refine_prologue_limit (pc, lim_pc, &trust_limit);
1052b725ae77Skettenis next_pc = fetch_instruction (pc, &it, &instr);
1053b725ae77Skettenis
1054b725ae77Skettenis /* We want to check if we have a recognizable function start before we
1055b725ae77Skettenis look ahead for a prologue. */
1056b725ae77Skettenis if (pc < lim_pc && next_pc
1057b725ae77Skettenis && it == M && ((instr & 0x1ee0000003fLL) == 0x02c00000000LL))
1058b725ae77Skettenis {
1059b725ae77Skettenis /* alloc - start of a regular function. */
1060b725ae77Skettenis int sor = (int) ((instr & 0x00078000000LL) >> 27);
1061b725ae77Skettenis int sol = (int) ((instr & 0x00007f00000LL) >> 20);
1062b725ae77Skettenis int sof = (int) ((instr & 0x000000fe000LL) >> 13);
1063b725ae77Skettenis int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
1064b725ae77Skettenis
1065b725ae77Skettenis /* Verify that the current cfm matches what we think is the
1066b725ae77Skettenis function start. If we have somehow jumped within a function,
1067b725ae77Skettenis we do not want to interpret the prologue and calculate the
1068b725ae77Skettenis addresses of various registers such as the return address.
1069b725ae77Skettenis We will instead treat the frame as frameless. */
1070b725ae77Skettenis if (!next_frame ||
1071b725ae77Skettenis (sof == (cache->cfm & 0x7f) &&
1072b725ae77Skettenis sol == ((cache->cfm >> 7) & 0x7f)))
1073b725ae77Skettenis frameless = 0;
1074b725ae77Skettenis
1075b725ae77Skettenis cfm_reg = rN;
1076b725ae77Skettenis last_prologue_pc = next_pc;
1077b725ae77Skettenis pc = next_pc;
1078b725ae77Skettenis }
1079b725ae77Skettenis else
1080b725ae77Skettenis {
1081b725ae77Skettenis /* Look for a leaf routine. */
1082b725ae77Skettenis if (pc < lim_pc && next_pc
1083b725ae77Skettenis && (it == I || it == M)
1084b725ae77Skettenis && ((instr & 0x1ee00000000LL) == 0x10800000000LL))
1085b725ae77Skettenis {
1086b725ae77Skettenis /* adds rN = imm14, rM (or mov rN, rM when imm14 is 0) */
1087b725ae77Skettenis int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13)
1088b725ae77Skettenis | ((instr & 0x001f8000000LL) >> 20)
1089b725ae77Skettenis | ((instr & 0x000000fe000LL) >> 13));
1090b725ae77Skettenis int rM = (int) ((instr & 0x00007f00000LL) >> 20);
1091b725ae77Skettenis int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
1092b725ae77Skettenis int qp = (int) (instr & 0x0000000003fLL);
1093b725ae77Skettenis if (qp == 0 && rN == 2 && imm == 0 && rM == 12 && fp_reg == 0)
1094b725ae77Skettenis {
1095b725ae77Skettenis /* mov r2, r12 - beginning of leaf routine */
1096b725ae77Skettenis fp_reg = rN;
1097b725ae77Skettenis last_prologue_pc = next_pc;
1098b725ae77Skettenis }
1099b725ae77Skettenis }
1100b725ae77Skettenis
1101b725ae77Skettenis /* If we don't recognize a regular function or leaf routine, we are
1102b725ae77Skettenis done. */
1103b725ae77Skettenis if (!fp_reg)
1104b725ae77Skettenis {
1105b725ae77Skettenis pc = lim_pc;
1106b725ae77Skettenis if (trust_limit)
1107b725ae77Skettenis last_prologue_pc = lim_pc;
1108b725ae77Skettenis }
1109b725ae77Skettenis }
1110b725ae77Skettenis
1111b725ae77Skettenis /* Loop, looking for prologue instructions, keeping track of
1112b725ae77Skettenis where preserved registers were spilled. */
1113b725ae77Skettenis while (pc < lim_pc)
1114b725ae77Skettenis {
1115b725ae77Skettenis next_pc = fetch_instruction (pc, &it, &instr);
1116b725ae77Skettenis if (next_pc == 0)
1117b725ae77Skettenis break;
1118b725ae77Skettenis
1119*11efff7fSkettenis if (it == B && ((instr & 0x1e1f800003fLL) != 0x04000000000LL))
1120b725ae77Skettenis {
1121b725ae77Skettenis /* Exit loop upon hitting a non-nop branch instruction. */
1122b725ae77Skettenis if (trust_limit)
1123b725ae77Skettenis lim_pc = pc;
1124b725ae77Skettenis break;
1125b725ae77Skettenis }
1126b725ae77Skettenis else if (((instr & 0x3fLL) != 0LL) &&
1127b725ae77Skettenis (frameless || ret_reg != 0))
1128b725ae77Skettenis {
1129b725ae77Skettenis /* Exit loop upon hitting a predicated instruction if
1130b725ae77Skettenis we already have the return register or if we are frameless. */
1131b725ae77Skettenis if (trust_limit)
1132b725ae77Skettenis lim_pc = pc;
1133b725ae77Skettenis break;
1134b725ae77Skettenis }
1135b725ae77Skettenis else if (it == I && ((instr & 0x1eff8000000LL) == 0x00188000000LL))
1136b725ae77Skettenis {
1137b725ae77Skettenis /* Move from BR */
1138b725ae77Skettenis int b2 = (int) ((instr & 0x0000000e000LL) >> 13);
1139b725ae77Skettenis int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
1140b725ae77Skettenis int qp = (int) (instr & 0x0000000003f);
1141b725ae77Skettenis
1142b725ae77Skettenis if (qp == 0 && b2 == 0 && rN >= 32 && ret_reg == 0)
1143b725ae77Skettenis {
1144b725ae77Skettenis ret_reg = rN;
1145b725ae77Skettenis last_prologue_pc = next_pc;
1146b725ae77Skettenis }
1147b725ae77Skettenis }
1148b725ae77Skettenis else if ((it == I || it == M)
1149b725ae77Skettenis && ((instr & 0x1ee00000000LL) == 0x10800000000LL))
1150b725ae77Skettenis {
1151b725ae77Skettenis /* adds rN = imm14, rM (or mov rN, rM when imm14 is 0) */
1152b725ae77Skettenis int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13)
1153b725ae77Skettenis | ((instr & 0x001f8000000LL) >> 20)
1154b725ae77Skettenis | ((instr & 0x000000fe000LL) >> 13));
1155b725ae77Skettenis int rM = (int) ((instr & 0x00007f00000LL) >> 20);
1156b725ae77Skettenis int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
1157b725ae77Skettenis int qp = (int) (instr & 0x0000000003fLL);
1158b725ae77Skettenis
1159b725ae77Skettenis if (qp == 0 && rN >= 32 && imm == 0 && rM == 12 && fp_reg == 0)
1160b725ae77Skettenis {
1161b725ae77Skettenis /* mov rN, r12 */
1162b725ae77Skettenis fp_reg = rN;
1163b725ae77Skettenis last_prologue_pc = next_pc;
1164b725ae77Skettenis }
1165b725ae77Skettenis else if (qp == 0 && rN == 12 && rM == 12)
1166b725ae77Skettenis {
1167b725ae77Skettenis /* adds r12, -mem_stack_frame_size, r12 */
1168b725ae77Skettenis mem_stack_frame_size -= imm;
1169b725ae77Skettenis last_prologue_pc = next_pc;
1170b725ae77Skettenis }
1171b725ae77Skettenis else if (qp == 0 && rN == 2
1172b725ae77Skettenis && ((rM == fp_reg && fp_reg != 0) || rM == 12))
1173b725ae77Skettenis {
1174b725ae77Skettenis char buf[MAX_REGISTER_SIZE];
1175b725ae77Skettenis CORE_ADDR saved_sp = 0;
1176b725ae77Skettenis /* adds r2, spilloffset, rFramePointer
1177b725ae77Skettenis or
1178b725ae77Skettenis adds r2, spilloffset, r12
1179b725ae77Skettenis
1180b725ae77Skettenis Get ready for stf.spill or st8.spill instructions.
1181b725ae77Skettenis The address to start spilling at is loaded into r2.
1182b725ae77Skettenis FIXME: Why r2? That's what gcc currently uses; it
1183b725ae77Skettenis could well be different for other compilers. */
1184b725ae77Skettenis
1185b725ae77Skettenis /* Hmm... whether or not this will work will depend on
1186b725ae77Skettenis where the pc is. If it's still early in the prologue
1187b725ae77Skettenis this'll be wrong. FIXME */
1188b725ae77Skettenis if (next_frame)
1189b725ae77Skettenis {
1190b725ae77Skettenis frame_unwind_register (next_frame, sp_regnum, buf);
1191b725ae77Skettenis saved_sp = extract_unsigned_integer (buf, 8);
1192b725ae77Skettenis }
1193b725ae77Skettenis spill_addr = saved_sp
1194b725ae77Skettenis + (rM == 12 ? 0 : mem_stack_frame_size)
1195b725ae77Skettenis + imm;
1196b725ae77Skettenis spill_reg = rN;
1197b725ae77Skettenis last_prologue_pc = next_pc;
1198b725ae77Skettenis }
1199b725ae77Skettenis else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM] &&
1200b725ae77Skettenis rN < 256 && imm == 0)
1201b725ae77Skettenis {
1202b725ae77Skettenis /* mov rN, rM where rM is an input register */
1203b725ae77Skettenis reg_contents[rN] = rM;
1204b725ae77Skettenis last_prologue_pc = next_pc;
1205b725ae77Skettenis }
1206b725ae77Skettenis else if (frameless && qp == 0 && rN == fp_reg && imm == 0 &&
1207b725ae77Skettenis rM == 2)
1208b725ae77Skettenis {
1209b725ae77Skettenis /* mov r12, r2 */
1210b725ae77Skettenis last_prologue_pc = next_pc;
1211b725ae77Skettenis break;
1212b725ae77Skettenis }
1213b725ae77Skettenis }
1214b725ae77Skettenis else if (it == M
1215b725ae77Skettenis && ( ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
1216b725ae77Skettenis || ((instr & 0x1ffc8000000LL) == 0x0cec0000000LL) ))
1217b725ae77Skettenis {
1218b725ae77Skettenis /* stf.spill [rN] = fM, imm9
1219b725ae77Skettenis or
1220b725ae77Skettenis stf.spill [rN] = fM */
1221b725ae77Skettenis
1222b725ae77Skettenis int imm = imm9(instr);
1223b725ae77Skettenis int rN = (int) ((instr & 0x00007f00000LL) >> 20);
1224b725ae77Skettenis int fM = (int) ((instr & 0x000000fe000LL) >> 13);
1225b725ae77Skettenis int qp = (int) (instr & 0x0000000003fLL);
1226b725ae77Skettenis if (qp == 0 && rN == spill_reg && spill_addr != 0
1227b725ae77Skettenis && ((2 <= fM && fM <= 5) || (16 <= fM && fM <= 31)))
1228b725ae77Skettenis {
1229b725ae77Skettenis cache->saved_regs[IA64_FR0_REGNUM + fM] = spill_addr;
1230b725ae77Skettenis
1231*11efff7fSkettenis if ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
1232b725ae77Skettenis spill_addr += imm;
1233b725ae77Skettenis else
1234b725ae77Skettenis spill_addr = 0; /* last one; must be done */
1235b725ae77Skettenis last_prologue_pc = next_pc;
1236b725ae77Skettenis }
1237b725ae77Skettenis }
1238b725ae77Skettenis else if ((it == M && ((instr & 0x1eff8000000LL) == 0x02110000000LL))
1239b725ae77Skettenis || (it == I && ((instr & 0x1eff8000000LL) == 0x00050000000LL)) )
1240b725ae77Skettenis {
1241b725ae77Skettenis /* mov.m rN = arM
1242b725ae77Skettenis or
1243b725ae77Skettenis mov.i rN = arM */
1244b725ae77Skettenis
1245b725ae77Skettenis int arM = (int) ((instr & 0x00007f00000LL) >> 20);
1246b725ae77Skettenis int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
1247b725ae77Skettenis int qp = (int) (instr & 0x0000000003fLL);
1248b725ae77Skettenis if (qp == 0 && isScratch (rN) && arM == 36 /* ar.unat */)
1249b725ae77Skettenis {
1250b725ae77Skettenis /* We have something like "mov.m r3 = ar.unat". Remember the
1251b725ae77Skettenis r3 (or whatever) and watch for a store of this register... */
1252b725ae77Skettenis unat_save_reg = rN;
1253b725ae77Skettenis last_prologue_pc = next_pc;
1254b725ae77Skettenis }
1255b725ae77Skettenis }
1256b725ae77Skettenis else if (it == I && ((instr & 0x1eff8000000LL) == 0x00198000000LL))
1257b725ae77Skettenis {
1258b725ae77Skettenis /* mov rN = pr */
1259b725ae77Skettenis int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
1260b725ae77Skettenis int qp = (int) (instr & 0x0000000003fLL);
1261b725ae77Skettenis if (qp == 0 && isScratch (rN))
1262b725ae77Skettenis {
1263b725ae77Skettenis pr_save_reg = rN;
1264b725ae77Skettenis last_prologue_pc = next_pc;
1265b725ae77Skettenis }
1266b725ae77Skettenis }
1267b725ae77Skettenis else if (it == M
1268b725ae77Skettenis && ( ((instr & 0x1ffc8000000LL) == 0x08cc0000000LL)
1269b725ae77Skettenis || ((instr & 0x1efc0000000LL) == 0x0acc0000000LL)))
1270b725ae77Skettenis {
1271b725ae77Skettenis /* st8 [rN] = rM
1272b725ae77Skettenis or
1273b725ae77Skettenis st8 [rN] = rM, imm9 */
1274b725ae77Skettenis int rN = (int) ((instr & 0x00007f00000LL) >> 20);
1275b725ae77Skettenis int rM = (int) ((instr & 0x000000fe000LL) >> 13);
1276b725ae77Skettenis int qp = (int) (instr & 0x0000000003fLL);
1277b725ae77Skettenis int indirect = rM < 256 ? reg_contents[rM] : 0;
1278b725ae77Skettenis if (qp == 0 && rN == spill_reg && spill_addr != 0
1279b725ae77Skettenis && (rM == unat_save_reg || rM == pr_save_reg))
1280b725ae77Skettenis {
1281b725ae77Skettenis /* We've found a spill of either the UNAT register or the PR
1282b725ae77Skettenis register. (Well, not exactly; what we've actually found is
1283b725ae77Skettenis a spill of the register that UNAT or PR was moved to).
1284b725ae77Skettenis Record that fact and move on... */
1285b725ae77Skettenis if (rM == unat_save_reg)
1286b725ae77Skettenis {
1287b725ae77Skettenis /* Track UNAT register */
1288b725ae77Skettenis cache->saved_regs[IA64_UNAT_REGNUM] = spill_addr;
1289b725ae77Skettenis unat_save_reg = 0;
1290b725ae77Skettenis }
1291b725ae77Skettenis else
1292b725ae77Skettenis {
1293b725ae77Skettenis /* Track PR register */
1294b725ae77Skettenis cache->saved_regs[IA64_PR_REGNUM] = spill_addr;
1295b725ae77Skettenis pr_save_reg = 0;
1296b725ae77Skettenis }
1297b725ae77Skettenis if ((instr & 0x1efc0000000LL) == 0x0acc0000000LL)
1298b725ae77Skettenis /* st8 [rN] = rM, imm9 */
1299b725ae77Skettenis spill_addr += imm9(instr);
1300b725ae77Skettenis else
1301b725ae77Skettenis spill_addr = 0; /* must be done spilling */
1302b725ae77Skettenis last_prologue_pc = next_pc;
1303b725ae77Skettenis }
1304b725ae77Skettenis else if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
1305b725ae77Skettenis {
1306b725ae77Skettenis /* Allow up to one store of each input register. */
1307b725ae77Skettenis instores[rM-32] = 1;
1308b725ae77Skettenis last_prologue_pc = next_pc;
1309b725ae77Skettenis }
1310b725ae77Skettenis else if (qp == 0 && 32 <= indirect && indirect < 40 &&
1311b725ae77Skettenis !instores[indirect-32])
1312b725ae77Skettenis {
1313b725ae77Skettenis /* Allow an indirect store of an input register. */
1314b725ae77Skettenis instores[indirect-32] = 1;
1315b725ae77Skettenis last_prologue_pc = next_pc;
1316b725ae77Skettenis }
1317b725ae77Skettenis }
1318b725ae77Skettenis else if (it == M && ((instr & 0x1ff08000000LL) == 0x08c00000000LL))
1319b725ae77Skettenis {
1320b725ae77Skettenis /* One of
1321b725ae77Skettenis st1 [rN] = rM
1322b725ae77Skettenis st2 [rN] = rM
1323b725ae77Skettenis st4 [rN] = rM
1324b725ae77Skettenis st8 [rN] = rM
1325b725ae77Skettenis Note that the st8 case is handled in the clause above.
1326b725ae77Skettenis
1327b725ae77Skettenis Advance over stores of input registers. One store per input
1328b725ae77Skettenis register is permitted. */
1329b725ae77Skettenis int rM = (int) ((instr & 0x000000fe000LL) >> 13);
1330b725ae77Skettenis int qp = (int) (instr & 0x0000000003fLL);
1331b725ae77Skettenis int indirect = rM < 256 ? reg_contents[rM] : 0;
1332b725ae77Skettenis if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
1333b725ae77Skettenis {
1334b725ae77Skettenis instores[rM-32] = 1;
1335b725ae77Skettenis last_prologue_pc = next_pc;
1336b725ae77Skettenis }
1337b725ae77Skettenis else if (qp == 0 && 32 <= indirect && indirect < 40 &&
1338b725ae77Skettenis !instores[indirect-32])
1339b725ae77Skettenis {
1340b725ae77Skettenis /* Allow an indirect store of an input register. */
1341b725ae77Skettenis instores[indirect-32] = 1;
1342b725ae77Skettenis last_prologue_pc = next_pc;
1343b725ae77Skettenis }
1344b725ae77Skettenis }
1345b725ae77Skettenis else if (it == M && ((instr & 0x1ff88000000LL) == 0x0cc80000000LL))
1346b725ae77Skettenis {
1347b725ae77Skettenis /* Either
1348b725ae77Skettenis stfs [rN] = fM
1349b725ae77Skettenis or
1350b725ae77Skettenis stfd [rN] = fM
1351b725ae77Skettenis
1352b725ae77Skettenis Advance over stores of floating point input registers. Again
1353b725ae77Skettenis one store per register is permitted */
1354b725ae77Skettenis int fM = (int) ((instr & 0x000000fe000LL) >> 13);
1355b725ae77Skettenis int qp = (int) (instr & 0x0000000003fLL);
1356b725ae77Skettenis if (qp == 0 && 8 <= fM && fM < 16 && !infpstores[fM - 8])
1357b725ae77Skettenis {
1358b725ae77Skettenis infpstores[fM-8] = 1;
1359b725ae77Skettenis last_prologue_pc = next_pc;
1360b725ae77Skettenis }
1361b725ae77Skettenis }
1362b725ae77Skettenis else if (it == M
1363b725ae77Skettenis && ( ((instr & 0x1ffc8000000LL) == 0x08ec0000000LL)
1364b725ae77Skettenis || ((instr & 0x1efc0000000LL) == 0x0aec0000000LL)))
1365b725ae77Skettenis {
1366b725ae77Skettenis /* st8.spill [rN] = rM
1367b725ae77Skettenis or
1368b725ae77Skettenis st8.spill [rN] = rM, imm9 */
1369b725ae77Skettenis int rN = (int) ((instr & 0x00007f00000LL) >> 20);
1370b725ae77Skettenis int rM = (int) ((instr & 0x000000fe000LL) >> 13);
1371b725ae77Skettenis int qp = (int) (instr & 0x0000000003fLL);
1372b725ae77Skettenis if (qp == 0 && rN == spill_reg && 4 <= rM && rM <= 7)
1373b725ae77Skettenis {
1374b725ae77Skettenis /* We've found a spill of one of the preserved general purpose
1375b725ae77Skettenis regs. Record the spill address and advance the spill
1376b725ae77Skettenis register if appropriate. */
1377b725ae77Skettenis cache->saved_regs[IA64_GR0_REGNUM + rM] = spill_addr;
1378b725ae77Skettenis if ((instr & 0x1efc0000000LL) == 0x0aec0000000LL)
1379b725ae77Skettenis /* st8.spill [rN] = rM, imm9 */
1380b725ae77Skettenis spill_addr += imm9(instr);
1381b725ae77Skettenis else
1382b725ae77Skettenis spill_addr = 0; /* Done spilling */
1383b725ae77Skettenis last_prologue_pc = next_pc;
1384b725ae77Skettenis }
1385b725ae77Skettenis }
1386b725ae77Skettenis
1387b725ae77Skettenis pc = next_pc;
1388b725ae77Skettenis }
1389b725ae77Skettenis
1390b725ae77Skettenis /* If not frameless and we aren't called by skip_prologue, then we need to calculate
1391b725ae77Skettenis registers for the previous frame which will be needed later. */
1392b725ae77Skettenis
1393b725ae77Skettenis if (!frameless && next_frame)
1394b725ae77Skettenis {
1395b725ae77Skettenis /* Extract the size of the rotating portion of the stack
1396b725ae77Skettenis frame and the register rename base from the current
1397b725ae77Skettenis frame marker. */
1398b725ae77Skettenis cfm = cache->cfm;
1399b725ae77Skettenis sor = cache->sor;
1400b725ae77Skettenis sof = cache->sof;
1401b725ae77Skettenis sol = cache->sol;
1402b725ae77Skettenis rrb_gr = (cfm >> 18) & 0x7f;
1403b725ae77Skettenis
1404b725ae77Skettenis /* Find the bof (beginning of frame). */
1405b725ae77Skettenis bof = rse_address_add (cache->bsp, -sof);
1406b725ae77Skettenis
1407b725ae77Skettenis for (i = 0, addr = bof;
1408b725ae77Skettenis i < sof;
1409b725ae77Skettenis i++, addr += 8)
1410b725ae77Skettenis {
1411b725ae77Skettenis if (IS_NaT_COLLECTION_ADDR (addr))
1412b725ae77Skettenis {
1413b725ae77Skettenis addr += 8;
1414b725ae77Skettenis }
1415b725ae77Skettenis if (i+32 == cfm_reg)
1416b725ae77Skettenis cache->saved_regs[IA64_CFM_REGNUM] = addr;
1417b725ae77Skettenis if (i+32 == ret_reg)
1418b725ae77Skettenis cache->saved_regs[IA64_VRAP_REGNUM] = addr;
1419b725ae77Skettenis if (i+32 == fp_reg)
1420b725ae77Skettenis cache->saved_regs[IA64_VFP_REGNUM] = addr;
1421b725ae77Skettenis }
1422b725ae77Skettenis
1423b725ae77Skettenis /* For the previous argument registers we require the previous bof.
1424b725ae77Skettenis If we can't find the previous cfm, then we can do nothing. */
1425b725ae77Skettenis cfm = 0;
1426b725ae77Skettenis if (cache->saved_regs[IA64_CFM_REGNUM] != 0)
1427b725ae77Skettenis {
1428b725ae77Skettenis cfm = read_memory_integer (cache->saved_regs[IA64_CFM_REGNUM], 8);
1429b725ae77Skettenis }
1430b725ae77Skettenis else if (cfm_reg != 0)
1431b725ae77Skettenis {
1432b725ae77Skettenis frame_unwind_register (next_frame, cfm_reg, buf);
1433b725ae77Skettenis cfm = extract_unsigned_integer (buf, 8);
1434b725ae77Skettenis }
1435b725ae77Skettenis cache->prev_cfm = cfm;
1436b725ae77Skettenis
1437b725ae77Skettenis if (cfm != 0)
1438b725ae77Skettenis {
1439b725ae77Skettenis sor = ((cfm >> 14) & 0xf) * 8;
1440b725ae77Skettenis sof = (cfm & 0x7f);
1441b725ae77Skettenis sol = (cfm >> 7) & 0x7f;
1442b725ae77Skettenis rrb_gr = (cfm >> 18) & 0x7f;
1443b725ae77Skettenis
1444b725ae77Skettenis /* The previous bof only requires subtraction of the sol (size of locals)
1445b725ae77Skettenis due to the overlap between output and input of subsequent frames. */
1446b725ae77Skettenis bof = rse_address_add (bof, -sol);
1447b725ae77Skettenis
1448b725ae77Skettenis for (i = 0, addr = bof;
1449b725ae77Skettenis i < sof;
1450b725ae77Skettenis i++, addr += 8)
1451b725ae77Skettenis {
1452b725ae77Skettenis if (IS_NaT_COLLECTION_ADDR (addr))
1453b725ae77Skettenis {
1454b725ae77Skettenis addr += 8;
1455b725ae77Skettenis }
1456b725ae77Skettenis if (i < sor)
1457b725ae77Skettenis cache->saved_regs[IA64_GR32_REGNUM + ((i + (sor - rrb_gr)) % sor)]
1458b725ae77Skettenis = addr;
1459b725ae77Skettenis else
1460b725ae77Skettenis cache->saved_regs[IA64_GR32_REGNUM + i] = addr;
1461b725ae77Skettenis }
1462b725ae77Skettenis
1463b725ae77Skettenis }
1464b725ae77Skettenis }
1465b725ae77Skettenis
1466b725ae77Skettenis /* Try and trust the lim_pc value whenever possible. */
1467b725ae77Skettenis if (trust_limit && lim_pc >= last_prologue_pc)
1468b725ae77Skettenis last_prologue_pc = lim_pc;
1469b725ae77Skettenis
1470b725ae77Skettenis cache->frameless = frameless;
1471b725ae77Skettenis cache->after_prologue = last_prologue_pc;
1472b725ae77Skettenis cache->mem_stack_frame_size = mem_stack_frame_size;
1473b725ae77Skettenis cache->fp_reg = fp_reg;
1474b725ae77Skettenis
1475b725ae77Skettenis return last_prologue_pc;
1476b725ae77Skettenis }
1477b725ae77Skettenis
1478b725ae77Skettenis CORE_ADDR
ia64_skip_prologue(CORE_ADDR pc)1479b725ae77Skettenis ia64_skip_prologue (CORE_ADDR pc)
1480b725ae77Skettenis {
1481b725ae77Skettenis struct ia64_frame_cache cache;
1482b725ae77Skettenis cache.base = 0;
1483b725ae77Skettenis cache.after_prologue = 0;
1484b725ae77Skettenis cache.cfm = 0;
1485b725ae77Skettenis cache.bsp = 0;
1486b725ae77Skettenis
1487b725ae77Skettenis /* Call examine_prologue with - as third argument since we don't have a next frame pointer to send. */
1488b725ae77Skettenis return examine_prologue (pc, pc+1024, 0, &cache);
1489b725ae77Skettenis }
1490b725ae77Skettenis
1491b725ae77Skettenis
1492b725ae77Skettenis /* Normal frames. */
1493b725ae77Skettenis
1494b725ae77Skettenis static struct ia64_frame_cache *
ia64_frame_cache(struct frame_info * next_frame,void ** this_cache)1495b725ae77Skettenis ia64_frame_cache (struct frame_info *next_frame, void **this_cache)
1496b725ae77Skettenis {
1497b725ae77Skettenis struct ia64_frame_cache *cache;
1498b725ae77Skettenis char buf[8];
1499b725ae77Skettenis CORE_ADDR cfm, sof, sol, bsp, psr;
1500b725ae77Skettenis int i;
1501b725ae77Skettenis
1502b725ae77Skettenis if (*this_cache)
1503b725ae77Skettenis return *this_cache;
1504b725ae77Skettenis
1505b725ae77Skettenis cache = ia64_alloc_frame_cache ();
1506b725ae77Skettenis *this_cache = cache;
1507b725ae77Skettenis
1508b725ae77Skettenis frame_unwind_register (next_frame, sp_regnum, buf);
1509b725ae77Skettenis cache->saved_sp = extract_unsigned_integer (buf, 8);
1510b725ae77Skettenis
1511b725ae77Skettenis /* We always want the bsp to point to the end of frame.
1512b725ae77Skettenis This way, we can always get the beginning of frame (bof)
1513b725ae77Skettenis by subtracting frame size. */
1514b725ae77Skettenis frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
1515b725ae77Skettenis cache->bsp = extract_unsigned_integer (buf, 8);
1516b725ae77Skettenis
1517b725ae77Skettenis frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
1518b725ae77Skettenis psr = extract_unsigned_integer (buf, 8);
1519b725ae77Skettenis
1520b725ae77Skettenis frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
1521b725ae77Skettenis cfm = extract_unsigned_integer (buf, 8);
1522b725ae77Skettenis
1523b725ae77Skettenis cache->sof = (cfm & 0x7f);
1524b725ae77Skettenis cache->sol = (cfm >> 7) & 0x7f;
1525b725ae77Skettenis cache->sor = ((cfm >> 14) & 0xf) * 8;
1526b725ae77Skettenis
1527b725ae77Skettenis cache->cfm = cfm;
1528b725ae77Skettenis
1529b725ae77Skettenis cache->pc = frame_func_unwind (next_frame);
1530b725ae77Skettenis
1531b725ae77Skettenis if (cache->pc != 0)
1532b725ae77Skettenis examine_prologue (cache->pc, frame_pc_unwind (next_frame), next_frame, cache);
1533b725ae77Skettenis
1534b725ae77Skettenis cache->base = cache->saved_sp + cache->mem_stack_frame_size;
1535b725ae77Skettenis
1536b725ae77Skettenis return cache;
1537b725ae77Skettenis }
1538b725ae77Skettenis
1539b725ae77Skettenis static void
ia64_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)1540b725ae77Skettenis ia64_frame_this_id (struct frame_info *next_frame, void **this_cache,
1541b725ae77Skettenis struct frame_id *this_id)
1542b725ae77Skettenis {
1543b725ae77Skettenis struct ia64_frame_cache *cache =
1544b725ae77Skettenis ia64_frame_cache (next_frame, this_cache);
1545b725ae77Skettenis
1546b725ae77Skettenis /* This marks the outermost frame. */
1547b725ae77Skettenis if (cache->base == 0)
1548b725ae77Skettenis return;
1549b725ae77Skettenis
1550b725ae77Skettenis (*this_id) = frame_id_build_special (cache->base, cache->pc, cache->bsp);
1551b725ae77Skettenis if (gdbarch_debug >= 1)
1552b725ae77Skettenis fprintf_unfiltered (gdb_stdlog,
1553b725ae77Skettenis "regular frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
1554b725ae77Skettenis paddr_nz (this_id->code_addr),
1555b725ae77Skettenis paddr_nz (this_id->stack_addr),
1556b725ae77Skettenis paddr_nz (cache->bsp), next_frame);
1557b725ae77Skettenis }
1558b725ae77Skettenis
1559b725ae77Skettenis static void
ia64_frame_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)1560b725ae77Skettenis ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
1561b725ae77Skettenis int regnum, int *optimizedp,
1562b725ae77Skettenis enum lval_type *lvalp, CORE_ADDR *addrp,
1563b725ae77Skettenis int *realnump, void *valuep)
1564b725ae77Skettenis {
1565b725ae77Skettenis struct ia64_frame_cache *cache =
1566b725ae77Skettenis ia64_frame_cache (next_frame, this_cache);
1567b725ae77Skettenis char dummy_valp[MAX_REGISTER_SIZE];
1568b725ae77Skettenis char buf[8];
1569b725ae77Skettenis
1570b725ae77Skettenis gdb_assert (regnum >= 0);
1571b725ae77Skettenis
1572b725ae77Skettenis if (!target_has_registers)
1573b725ae77Skettenis error ("No registers.");
1574b725ae77Skettenis
1575b725ae77Skettenis *optimizedp = 0;
1576b725ae77Skettenis *addrp = 0;
1577b725ae77Skettenis *lvalp = not_lval;
1578b725ae77Skettenis *realnump = -1;
1579b725ae77Skettenis
1580b725ae77Skettenis /* Rather than check each time if valuep is non-null, supply a dummy buffer
1581b725ae77Skettenis when valuep is not supplied. */
1582b725ae77Skettenis if (!valuep)
1583b725ae77Skettenis valuep = dummy_valp;
1584b725ae77Skettenis
1585b725ae77Skettenis memset (valuep, 0, register_size (current_gdbarch, regnum));
1586b725ae77Skettenis
1587b725ae77Skettenis if (regnum == SP_REGNUM)
1588b725ae77Skettenis {
1589b725ae77Skettenis /* Handle SP values for all frames but the topmost. */
1590b725ae77Skettenis store_unsigned_integer (valuep, register_size (current_gdbarch, regnum),
1591b725ae77Skettenis cache->base);
1592b725ae77Skettenis }
1593b725ae77Skettenis else if (regnum == IA64_BSP_REGNUM)
1594b725ae77Skettenis {
1595b725ae77Skettenis char cfm_valuep[MAX_REGISTER_SIZE];
1596b725ae77Skettenis int cfm_optim;
1597b725ae77Skettenis int cfm_realnum;
1598b725ae77Skettenis enum lval_type cfm_lval;
1599b725ae77Skettenis CORE_ADDR cfm_addr;
1600b725ae77Skettenis CORE_ADDR bsp, prev_cfm, prev_bsp;
1601b725ae77Skettenis
1602b725ae77Skettenis /* We want to calculate the previous bsp as the end of the previous register stack frame.
1603b725ae77Skettenis This corresponds to what the hardware bsp register will be if we pop the frame
1604b725ae77Skettenis back which is why we might have been called. We know the beginning of the current
1605b725ae77Skettenis frame is cache->bsp - cache->sof. This value in the previous frame points to
1606b725ae77Skettenis the start of the output registers. We can calculate the end of that frame by adding
1607b725ae77Skettenis the size of output (sof (size of frame) - sol (size of locals)). */
1608b725ae77Skettenis ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
1609b725ae77Skettenis &cfm_optim, &cfm_lval, &cfm_addr, &cfm_realnum, cfm_valuep);
1610b725ae77Skettenis prev_cfm = extract_unsigned_integer (cfm_valuep, 8);
1611b725ae77Skettenis
1612b725ae77Skettenis bsp = rse_address_add (cache->bsp, -(cache->sof));
1613b725ae77Skettenis prev_bsp = rse_address_add (bsp, (prev_cfm & 0x7f) - ((prev_cfm >> 7) & 0x7f));
1614b725ae77Skettenis
1615b725ae77Skettenis store_unsigned_integer (valuep, register_size (current_gdbarch, regnum),
1616b725ae77Skettenis prev_bsp);
1617b725ae77Skettenis }
1618b725ae77Skettenis else if (regnum == IA64_CFM_REGNUM)
1619b725ae77Skettenis {
1620b725ae77Skettenis CORE_ADDR addr = cache->saved_regs[IA64_CFM_REGNUM];
1621b725ae77Skettenis
1622b725ae77Skettenis if (addr != 0)
1623b725ae77Skettenis {
1624b725ae77Skettenis *lvalp = lval_memory;
1625b725ae77Skettenis *addrp = addr;
1626b725ae77Skettenis read_memory (addr, valuep, register_size (current_gdbarch, regnum));
1627b725ae77Skettenis }
1628b725ae77Skettenis else if (cache->prev_cfm)
1629b725ae77Skettenis store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), cache->prev_cfm);
1630b725ae77Skettenis else if (cache->frameless)
1631b725ae77Skettenis {
1632b725ae77Skettenis CORE_ADDR cfm = 0;
1633b725ae77Skettenis frame_unwind_register (next_frame, IA64_PFS_REGNUM, valuep);
1634b725ae77Skettenis }
1635b725ae77Skettenis }
1636b725ae77Skettenis else if (regnum == IA64_VFP_REGNUM)
1637b725ae77Skettenis {
1638b725ae77Skettenis /* If the function in question uses an automatic register (r32-r127)
1639b725ae77Skettenis for the frame pointer, it'll be found by ia64_find_saved_register()
1640b725ae77Skettenis above. If the function lacks one of these frame pointers, we can
1641b725ae77Skettenis still provide a value since we know the size of the frame. */
1642b725ae77Skettenis CORE_ADDR vfp = cache->base;
1643b725ae77Skettenis store_unsigned_integer (valuep, register_size (current_gdbarch, IA64_VFP_REGNUM), vfp);
1644b725ae77Skettenis }
1645b725ae77Skettenis else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
1646b725ae77Skettenis {
1647b725ae77Skettenis char pr_valuep[MAX_REGISTER_SIZE];
1648b725ae77Skettenis int pr_optim;
1649b725ae77Skettenis int pr_realnum;
1650b725ae77Skettenis enum lval_type pr_lval;
1651b725ae77Skettenis CORE_ADDR pr_addr;
1652b725ae77Skettenis ULONGEST prN_val;
1653b725ae77Skettenis ia64_frame_prev_register (next_frame, this_cache, IA64_PR_REGNUM,
1654b725ae77Skettenis &pr_optim, &pr_lval, &pr_addr, &pr_realnum, pr_valuep);
1655b725ae77Skettenis if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
1656b725ae77Skettenis {
1657b725ae77Skettenis /* Fetch predicate register rename base from current frame
1658b725ae77Skettenis marker for this frame. */
1659b725ae77Skettenis int rrb_pr = (cache->cfm >> 32) & 0x3f;
1660b725ae77Skettenis
1661b725ae77Skettenis /* Adjust the register number to account for register rotation. */
1662b725ae77Skettenis regnum = VP16_REGNUM
1663b725ae77Skettenis + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
1664b725ae77Skettenis }
1665b725ae77Skettenis prN_val = extract_bit_field ((unsigned char *) pr_valuep,
1666b725ae77Skettenis regnum - VP0_REGNUM, 1);
1667b725ae77Skettenis store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), prN_val);
1668b725ae77Skettenis }
1669b725ae77Skettenis else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
1670b725ae77Skettenis {
1671b725ae77Skettenis char unat_valuep[MAX_REGISTER_SIZE];
1672b725ae77Skettenis int unat_optim;
1673b725ae77Skettenis int unat_realnum;
1674b725ae77Skettenis enum lval_type unat_lval;
1675b725ae77Skettenis CORE_ADDR unat_addr;
1676b725ae77Skettenis ULONGEST unatN_val;
1677b725ae77Skettenis ia64_frame_prev_register (next_frame, this_cache, IA64_UNAT_REGNUM,
1678b725ae77Skettenis &unat_optim, &unat_lval, &unat_addr, &unat_realnum, unat_valuep);
1679b725ae77Skettenis unatN_val = extract_bit_field ((unsigned char *) unat_valuep,
1680b725ae77Skettenis regnum - IA64_NAT0_REGNUM, 1);
1681b725ae77Skettenis store_unsigned_integer (valuep, register_size (current_gdbarch, regnum),
1682b725ae77Skettenis unatN_val);
1683b725ae77Skettenis }
1684b725ae77Skettenis else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
1685b725ae77Skettenis {
1686b725ae77Skettenis int natval = 0;
1687b725ae77Skettenis /* Find address of general register corresponding to nat bit we're
1688b725ae77Skettenis interested in. */
1689b725ae77Skettenis CORE_ADDR gr_addr;
1690b725ae77Skettenis
1691b725ae77Skettenis gr_addr = cache->saved_regs[regnum - IA64_NAT0_REGNUM
1692b725ae77Skettenis + IA64_GR0_REGNUM];
1693b725ae77Skettenis if (gr_addr != 0)
1694b725ae77Skettenis {
1695b725ae77Skettenis /* Compute address of nat collection bits. */
1696b725ae77Skettenis CORE_ADDR nat_addr = gr_addr | 0x1f8;
1697b725ae77Skettenis CORE_ADDR bsp;
1698b725ae77Skettenis CORE_ADDR nat_collection;
1699b725ae77Skettenis int nat_bit;
1700b725ae77Skettenis /* If our nat collection address is bigger than bsp, we have to get
1701b725ae77Skettenis the nat collection from rnat. Otherwise, we fetch the nat
1702b725ae77Skettenis collection from the computed address. */
1703b725ae77Skettenis frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
1704b725ae77Skettenis bsp = extract_unsigned_integer (buf, 8);
1705b725ae77Skettenis if (nat_addr >= bsp)
1706b725ae77Skettenis {
1707b725ae77Skettenis frame_unwind_register (next_frame, IA64_RNAT_REGNUM, buf);
1708b725ae77Skettenis nat_collection = extract_unsigned_integer (buf, 8);
1709b725ae77Skettenis }
1710b725ae77Skettenis else
1711b725ae77Skettenis nat_collection = read_memory_integer (nat_addr, 8);
1712b725ae77Skettenis nat_bit = (gr_addr >> 3) & 0x3f;
1713b725ae77Skettenis natval = (nat_collection >> nat_bit) & 1;
1714b725ae77Skettenis }
1715b725ae77Skettenis
1716b725ae77Skettenis store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), natval);
1717b725ae77Skettenis }
1718b725ae77Skettenis else if (regnum == IA64_IP_REGNUM)
1719b725ae77Skettenis {
1720b725ae77Skettenis CORE_ADDR pc = 0;
1721b725ae77Skettenis CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
1722b725ae77Skettenis
1723b725ae77Skettenis if (addr != 0)
1724b725ae77Skettenis {
1725b725ae77Skettenis *lvalp = lval_memory;
1726b725ae77Skettenis *addrp = addr;
1727b725ae77Skettenis read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
1728b725ae77Skettenis pc = extract_unsigned_integer (buf, 8);
1729b725ae77Skettenis }
1730b725ae77Skettenis else if (cache->frameless)
1731b725ae77Skettenis {
1732b725ae77Skettenis frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
1733b725ae77Skettenis pc = extract_unsigned_integer (buf, 8);
1734b725ae77Skettenis }
1735b725ae77Skettenis pc &= ~0xf;
1736b725ae77Skettenis store_unsigned_integer (valuep, 8, pc);
1737b725ae77Skettenis }
1738b725ae77Skettenis else if (regnum == IA64_PSR_REGNUM)
1739b725ae77Skettenis {
1740b725ae77Skettenis /* We don't know how to get the complete previous PSR, but we need it for
1741b725ae77Skettenis the slot information when we unwind the pc (pc is formed of IP register
1742b725ae77Skettenis plus slot information from PSR). To get the previous slot information,
1743b725ae77Skettenis we mask it off the return address. */
1744b725ae77Skettenis ULONGEST slot_num = 0;
1745b725ae77Skettenis CORE_ADDR pc= 0;
1746b725ae77Skettenis CORE_ADDR psr = 0;
1747b725ae77Skettenis CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
1748b725ae77Skettenis
1749b725ae77Skettenis frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
1750b725ae77Skettenis psr = extract_unsigned_integer (buf, 8);
1751b725ae77Skettenis
1752b725ae77Skettenis if (addr != 0)
1753b725ae77Skettenis {
1754b725ae77Skettenis *lvalp = lval_memory;
1755b725ae77Skettenis *addrp = addr;
1756b725ae77Skettenis read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
1757b725ae77Skettenis pc = extract_unsigned_integer (buf, 8);
1758b725ae77Skettenis }
1759b725ae77Skettenis else if (cache->frameless)
1760b725ae77Skettenis {
1761b725ae77Skettenis CORE_ADDR pc;
1762b725ae77Skettenis frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
1763b725ae77Skettenis pc = extract_unsigned_integer (buf, 8);
1764b725ae77Skettenis }
1765b725ae77Skettenis psr &= ~(3LL << 41);
1766b725ae77Skettenis slot_num = pc & 0x3LL;
1767b725ae77Skettenis psr |= (CORE_ADDR)slot_num << 41;
1768b725ae77Skettenis store_unsigned_integer (valuep, 8, psr);
1769b725ae77Skettenis }
1770b725ae77Skettenis else if (regnum == IA64_BR0_REGNUM)
1771b725ae77Skettenis {
1772b725ae77Skettenis CORE_ADDR br0 = 0;
1773b725ae77Skettenis CORE_ADDR addr = cache->saved_regs[IA64_BR0_REGNUM];
1774b725ae77Skettenis if (addr != 0)
1775b725ae77Skettenis {
1776b725ae77Skettenis *lvalp = lval_memory;
1777b725ae77Skettenis *addrp = addr;
1778b725ae77Skettenis read_memory (addr, buf, register_size (current_gdbarch, IA64_BR0_REGNUM));
1779b725ae77Skettenis br0 = extract_unsigned_integer (buf, 8);
1780b725ae77Skettenis }
1781b725ae77Skettenis store_unsigned_integer (valuep, 8, br0);
1782b725ae77Skettenis }
1783b725ae77Skettenis else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
1784b725ae77Skettenis (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
1785b725ae77Skettenis {
1786b725ae77Skettenis CORE_ADDR addr = 0;
1787b725ae77Skettenis if (regnum >= V32_REGNUM)
1788b725ae77Skettenis regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
1789b725ae77Skettenis addr = cache->saved_regs[regnum];
1790b725ae77Skettenis if (addr != 0)
1791b725ae77Skettenis {
1792b725ae77Skettenis *lvalp = lval_memory;
1793b725ae77Skettenis *addrp = addr;
1794b725ae77Skettenis read_memory (addr, valuep, register_size (current_gdbarch, regnum));
1795b725ae77Skettenis }
1796b725ae77Skettenis else if (cache->frameless)
1797b725ae77Skettenis {
1798b725ae77Skettenis char r_valuep[MAX_REGISTER_SIZE];
1799b725ae77Skettenis int r_optim;
1800b725ae77Skettenis int r_realnum;
1801b725ae77Skettenis enum lval_type r_lval;
1802b725ae77Skettenis CORE_ADDR r_addr;
1803b725ae77Skettenis CORE_ADDR prev_cfm, prev_bsp, prev_bof;
1804b725ae77Skettenis CORE_ADDR addr = 0;
1805b725ae77Skettenis if (regnum >= V32_REGNUM)
1806b725ae77Skettenis regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
1807b725ae77Skettenis ia64_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
1808b725ae77Skettenis &r_optim, &r_lval, &r_addr, &r_realnum, r_valuep);
1809b725ae77Skettenis prev_cfm = extract_unsigned_integer (r_valuep, 8);
1810b725ae77Skettenis ia64_frame_prev_register (next_frame, this_cache, IA64_BSP_REGNUM,
1811b725ae77Skettenis &r_optim, &r_lval, &r_addr, &r_realnum, r_valuep);
1812b725ae77Skettenis prev_bsp = extract_unsigned_integer (r_valuep, 8);
1813b725ae77Skettenis prev_bof = rse_address_add (prev_bsp, -(prev_cfm & 0x7f));
1814b725ae77Skettenis
1815b725ae77Skettenis addr = rse_address_add (prev_bof, (regnum - IA64_GR32_REGNUM));
1816b725ae77Skettenis *lvalp = lval_memory;
1817b725ae77Skettenis *addrp = addr;
1818b725ae77Skettenis read_memory (addr, valuep, register_size (current_gdbarch, regnum));
1819b725ae77Skettenis }
1820b725ae77Skettenis }
1821b725ae77Skettenis else
1822b725ae77Skettenis {
1823b725ae77Skettenis CORE_ADDR addr = 0;
1824b725ae77Skettenis if (IA64_FR32_REGNUM <= regnum && regnum <= IA64_FR127_REGNUM)
1825b725ae77Skettenis {
1826b725ae77Skettenis /* Fetch floating point register rename base from current
1827b725ae77Skettenis frame marker for this frame. */
1828b725ae77Skettenis int rrb_fr = (cache->cfm >> 25) & 0x7f;
1829b725ae77Skettenis
1830b725ae77Skettenis /* Adjust the floating point register number to account for
1831b725ae77Skettenis register rotation. */
1832b725ae77Skettenis regnum = IA64_FR32_REGNUM
1833b725ae77Skettenis + ((regnum - IA64_FR32_REGNUM) + rrb_fr) % 96;
1834b725ae77Skettenis }
1835b725ae77Skettenis
1836b725ae77Skettenis /* If we have stored a memory address, access the register. */
1837b725ae77Skettenis addr = cache->saved_regs[regnum];
1838b725ae77Skettenis if (addr != 0)
1839b725ae77Skettenis {
1840b725ae77Skettenis *lvalp = lval_memory;
1841b725ae77Skettenis *addrp = addr;
1842b725ae77Skettenis read_memory (addr, valuep, register_size (current_gdbarch, regnum));
1843b725ae77Skettenis }
1844b725ae77Skettenis /* Otherwise, punt and get the current value of the register. */
1845b725ae77Skettenis else
1846b725ae77Skettenis frame_unwind_register (next_frame, regnum, valuep);
1847b725ae77Skettenis }
1848b725ae77Skettenis
1849b725ae77Skettenis if (gdbarch_debug >= 1)
1850b725ae77Skettenis fprintf_unfiltered (gdb_stdlog,
1851b725ae77Skettenis "regular prev register <%d> <%s> is 0x%s\n", regnum,
1852b725ae77Skettenis (((unsigned) regnum <= IA64_NAT127_REGNUM)
1853b725ae77Skettenis ? ia64_register_names[regnum] : "r??"),
1854b725ae77Skettenis paddr_nz (extract_unsigned_integer (valuep, 8)));
1855b725ae77Skettenis }
1856b725ae77Skettenis
1857b725ae77Skettenis static const struct frame_unwind ia64_frame_unwind =
1858b725ae77Skettenis {
1859b725ae77Skettenis NORMAL_FRAME,
1860b725ae77Skettenis &ia64_frame_this_id,
1861b725ae77Skettenis &ia64_frame_prev_register
1862b725ae77Skettenis };
1863b725ae77Skettenis
1864b725ae77Skettenis static const struct frame_unwind *
ia64_frame_sniffer(struct frame_info * next_frame)1865b725ae77Skettenis ia64_frame_sniffer (struct frame_info *next_frame)
1866b725ae77Skettenis {
1867b725ae77Skettenis return &ia64_frame_unwind;
1868b725ae77Skettenis }
1869b725ae77Skettenis
1870b725ae77Skettenis /* Signal trampolines. */
1871b725ae77Skettenis
1872b725ae77Skettenis static void
ia64_sigtramp_frame_init_saved_regs(struct ia64_frame_cache * cache)1873b725ae77Skettenis ia64_sigtramp_frame_init_saved_regs (struct ia64_frame_cache *cache)
1874b725ae77Skettenis {
1875b725ae77Skettenis if (SIGCONTEXT_REGISTER_ADDRESS)
1876b725ae77Skettenis {
1877b725ae77Skettenis int regno;
1878b725ae77Skettenis
1879b725ae77Skettenis cache->saved_regs[IA64_VRAP_REGNUM] =
1880b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_IP_REGNUM);
1881b725ae77Skettenis cache->saved_regs[IA64_CFM_REGNUM] =
1882b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_CFM_REGNUM);
1883b725ae77Skettenis cache->saved_regs[IA64_PSR_REGNUM] =
1884b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_PSR_REGNUM);
1885b725ae77Skettenis cache->saved_regs[IA64_BSP_REGNUM] =
1886b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_BSP_REGNUM);
1887b725ae77Skettenis cache->saved_regs[IA64_RNAT_REGNUM] =
1888b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_RNAT_REGNUM);
1889b725ae77Skettenis cache->saved_regs[IA64_CCV_REGNUM] =
1890b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_CCV_REGNUM);
1891b725ae77Skettenis cache->saved_regs[IA64_UNAT_REGNUM] =
1892b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_UNAT_REGNUM);
1893b725ae77Skettenis cache->saved_regs[IA64_FPSR_REGNUM] =
1894b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_FPSR_REGNUM);
1895b725ae77Skettenis cache->saved_regs[IA64_PFS_REGNUM] =
1896b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_PFS_REGNUM);
1897b725ae77Skettenis cache->saved_regs[IA64_LC_REGNUM] =
1898b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_LC_REGNUM);
1899b725ae77Skettenis for (regno = IA64_GR1_REGNUM; regno <= IA64_GR31_REGNUM; regno++)
1900b725ae77Skettenis cache->saved_regs[regno] =
1901b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
1902b725ae77Skettenis for (regno = IA64_BR0_REGNUM; regno <= IA64_BR7_REGNUM; regno++)
1903b725ae77Skettenis cache->saved_regs[regno] =
1904b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
1905b725ae77Skettenis for (regno = IA64_FR2_REGNUM; regno <= IA64_FR31_REGNUM; regno++)
1906b725ae77Skettenis cache->saved_regs[regno] =
1907b725ae77Skettenis SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
1908b725ae77Skettenis }
1909b725ae77Skettenis }
1910b725ae77Skettenis
1911b725ae77Skettenis static struct ia64_frame_cache *
ia64_sigtramp_frame_cache(struct frame_info * next_frame,void ** this_cache)1912b725ae77Skettenis ia64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
1913b725ae77Skettenis {
1914b725ae77Skettenis struct ia64_frame_cache *cache;
1915b725ae77Skettenis CORE_ADDR addr;
1916b725ae77Skettenis char buf[8];
1917b725ae77Skettenis int i;
1918b725ae77Skettenis
1919b725ae77Skettenis if (*this_cache)
1920b725ae77Skettenis return *this_cache;
1921b725ae77Skettenis
1922b725ae77Skettenis cache = ia64_alloc_frame_cache ();
1923b725ae77Skettenis
1924b725ae77Skettenis frame_unwind_register (next_frame, sp_regnum, buf);
1925b725ae77Skettenis /* Note that frame size is hard-coded below. We cannot calculate it
1926b725ae77Skettenis via prologue examination. */
1927b725ae77Skettenis cache->base = extract_unsigned_integer (buf, 8) + 16;
1928b725ae77Skettenis
1929b725ae77Skettenis frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
1930b725ae77Skettenis cache->bsp = extract_unsigned_integer (buf, 8);
1931b725ae77Skettenis
1932b725ae77Skettenis frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
1933b725ae77Skettenis cache->cfm = extract_unsigned_integer (buf, 8);
1934b725ae77Skettenis cache->sof = cache->cfm & 0x7f;
1935b725ae77Skettenis
1936b725ae77Skettenis ia64_sigtramp_frame_init_saved_regs (cache);
1937b725ae77Skettenis
1938b725ae77Skettenis *this_cache = cache;
1939b725ae77Skettenis return cache;
1940b725ae77Skettenis }
1941b725ae77Skettenis
1942b725ae77Skettenis static void
ia64_sigtramp_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)1943b725ae77Skettenis ia64_sigtramp_frame_this_id (struct frame_info *next_frame,
1944b725ae77Skettenis void **this_cache, struct frame_id *this_id)
1945b725ae77Skettenis {
1946b725ae77Skettenis struct ia64_frame_cache *cache =
1947b725ae77Skettenis ia64_sigtramp_frame_cache (next_frame, this_cache);
1948b725ae77Skettenis
1949b725ae77Skettenis (*this_id) = frame_id_build_special (cache->base, frame_pc_unwind (next_frame), cache->bsp);
1950b725ae77Skettenis if (gdbarch_debug >= 1)
1951b725ae77Skettenis fprintf_unfiltered (gdb_stdlog,
1952b725ae77Skettenis "sigtramp frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
1953b725ae77Skettenis paddr_nz (this_id->code_addr),
1954b725ae77Skettenis paddr_nz (this_id->stack_addr),
1955b725ae77Skettenis paddr_nz (cache->bsp), next_frame);
1956b725ae77Skettenis }
1957b725ae77Skettenis
1958b725ae77Skettenis static void
ia64_sigtramp_frame_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)1959b725ae77Skettenis ia64_sigtramp_frame_prev_register (struct frame_info *next_frame,
1960b725ae77Skettenis void **this_cache,
1961b725ae77Skettenis int regnum, int *optimizedp,
1962b725ae77Skettenis enum lval_type *lvalp, CORE_ADDR *addrp,
1963b725ae77Skettenis int *realnump, void *valuep)
1964b725ae77Skettenis {
1965b725ae77Skettenis char dummy_valp[MAX_REGISTER_SIZE];
1966b725ae77Skettenis char buf[MAX_REGISTER_SIZE];
1967b725ae77Skettenis
1968b725ae77Skettenis struct ia64_frame_cache *cache =
1969b725ae77Skettenis ia64_sigtramp_frame_cache (next_frame, this_cache);
1970b725ae77Skettenis
1971b725ae77Skettenis gdb_assert (regnum >= 0);
1972b725ae77Skettenis
1973b725ae77Skettenis if (!target_has_registers)
1974b725ae77Skettenis error ("No registers.");
1975b725ae77Skettenis
1976b725ae77Skettenis *optimizedp = 0;
1977b725ae77Skettenis *addrp = 0;
1978b725ae77Skettenis *lvalp = not_lval;
1979b725ae77Skettenis *realnump = -1;
1980b725ae77Skettenis
1981b725ae77Skettenis /* Rather than check each time if valuep is non-null, supply a dummy buffer
1982b725ae77Skettenis when valuep is not supplied. */
1983b725ae77Skettenis if (!valuep)
1984b725ae77Skettenis valuep = dummy_valp;
1985b725ae77Skettenis
1986b725ae77Skettenis memset (valuep, 0, register_size (current_gdbarch, regnum));
1987b725ae77Skettenis
1988b725ae77Skettenis if (regnum == IA64_IP_REGNUM)
1989b725ae77Skettenis {
1990b725ae77Skettenis CORE_ADDR pc = 0;
1991b725ae77Skettenis CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
1992b725ae77Skettenis
1993b725ae77Skettenis if (addr != 0)
1994b725ae77Skettenis {
1995b725ae77Skettenis *lvalp = lval_memory;
1996b725ae77Skettenis *addrp = addr;
1997b725ae77Skettenis read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
1998b725ae77Skettenis pc = extract_unsigned_integer (buf, 8);
1999b725ae77Skettenis }
2000b725ae77Skettenis pc &= ~0xf;
2001b725ae77Skettenis store_unsigned_integer (valuep, 8, pc);
2002b725ae77Skettenis }
2003b725ae77Skettenis else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
2004b725ae77Skettenis (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
2005b725ae77Skettenis {
2006b725ae77Skettenis CORE_ADDR addr = 0;
2007b725ae77Skettenis if (regnum >= V32_REGNUM)
2008b725ae77Skettenis regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
2009b725ae77Skettenis addr = cache->saved_regs[regnum];
2010b725ae77Skettenis if (addr != 0)
2011b725ae77Skettenis {
2012b725ae77Skettenis *lvalp = lval_memory;
2013b725ae77Skettenis *addrp = addr;
2014b725ae77Skettenis read_memory (addr, valuep, register_size (current_gdbarch, regnum));
2015b725ae77Skettenis }
2016b725ae77Skettenis }
2017b725ae77Skettenis else
2018b725ae77Skettenis {
2019b725ae77Skettenis /* All other registers not listed above. */
2020b725ae77Skettenis CORE_ADDR addr = cache->saved_regs[regnum];
2021b725ae77Skettenis if (addr != 0)
2022b725ae77Skettenis {
2023b725ae77Skettenis *lvalp = lval_memory;
2024b725ae77Skettenis *addrp = addr;
2025b725ae77Skettenis read_memory (addr, valuep, register_size (current_gdbarch, regnum));
2026b725ae77Skettenis }
2027b725ae77Skettenis }
2028b725ae77Skettenis
2029b725ae77Skettenis if (gdbarch_debug >= 1)
2030b725ae77Skettenis fprintf_unfiltered (gdb_stdlog,
2031b725ae77Skettenis "sigtramp prev register <%s> is 0x%s\n",
2032b725ae77Skettenis (((unsigned) regnum <= IA64_NAT127_REGNUM)
2033b725ae77Skettenis ? ia64_register_names[regnum] : "r??"),
2034b725ae77Skettenis paddr_nz (extract_unsigned_integer (valuep, 8)));
2035b725ae77Skettenis }
2036b725ae77Skettenis
2037b725ae77Skettenis static const struct frame_unwind ia64_sigtramp_frame_unwind =
2038b725ae77Skettenis {
2039b725ae77Skettenis SIGTRAMP_FRAME,
2040b725ae77Skettenis ia64_sigtramp_frame_this_id,
2041b725ae77Skettenis ia64_sigtramp_frame_prev_register
2042b725ae77Skettenis };
2043b725ae77Skettenis
2044b725ae77Skettenis static const struct frame_unwind *
ia64_sigtramp_frame_sniffer(struct frame_info * next_frame)2045b725ae77Skettenis ia64_sigtramp_frame_sniffer (struct frame_info *next_frame)
2046b725ae77Skettenis {
2047b725ae77Skettenis char *name;
2048b725ae77Skettenis CORE_ADDR pc = frame_pc_unwind (next_frame);
2049b725ae77Skettenis
2050b725ae77Skettenis find_pc_partial_function (pc, &name, NULL, NULL);
2051*11efff7fSkettenis if (legacy_pc_in_sigtramp (pc, name))
2052b725ae77Skettenis return &ia64_sigtramp_frame_unwind;
2053b725ae77Skettenis
2054b725ae77Skettenis return NULL;
2055b725ae77Skettenis }
2056b725ae77Skettenis
2057b725ae77Skettenis
2058b725ae77Skettenis static CORE_ADDR
ia64_frame_base_address(struct frame_info * next_frame,void ** this_cache)2059b725ae77Skettenis ia64_frame_base_address (struct frame_info *next_frame, void **this_cache)
2060b725ae77Skettenis {
2061b725ae77Skettenis struct ia64_frame_cache *cache =
2062b725ae77Skettenis ia64_frame_cache (next_frame, this_cache);
2063b725ae77Skettenis
2064b725ae77Skettenis return cache->base;
2065b725ae77Skettenis }
2066b725ae77Skettenis
2067b725ae77Skettenis static const struct frame_base ia64_frame_base =
2068b725ae77Skettenis {
2069b725ae77Skettenis &ia64_frame_unwind,
2070b725ae77Skettenis ia64_frame_base_address,
2071b725ae77Skettenis ia64_frame_base_address,
2072b725ae77Skettenis ia64_frame_base_address
2073b725ae77Skettenis };
2074b725ae77Skettenis
2075b725ae77Skettenis #ifdef HAVE_LIBUNWIND_IA64_H
2076b725ae77Skettenis
2077b725ae77Skettenis struct ia64_unwind_table_entry
2078b725ae77Skettenis {
2079b725ae77Skettenis unw_word_t start_offset;
2080b725ae77Skettenis unw_word_t end_offset;
2081b725ae77Skettenis unw_word_t info_offset;
2082b725ae77Skettenis };
2083b725ae77Skettenis
2084b725ae77Skettenis static __inline__ uint64_t
ia64_rse_slot_num(uint64_t addr)2085b725ae77Skettenis ia64_rse_slot_num (uint64_t addr)
2086b725ae77Skettenis {
2087b725ae77Skettenis return (addr >> 3) & 0x3f;
2088b725ae77Skettenis }
2089b725ae77Skettenis
2090b725ae77Skettenis /* Skip over a designated number of registers in the backing
2091b725ae77Skettenis store, remembering every 64th position is for NAT. */
2092b725ae77Skettenis static __inline__ uint64_t
ia64_rse_skip_regs(uint64_t addr,long num_regs)2093b725ae77Skettenis ia64_rse_skip_regs (uint64_t addr, long num_regs)
2094b725ae77Skettenis {
2095b725ae77Skettenis long delta = ia64_rse_slot_num(addr) + num_regs;
2096b725ae77Skettenis
2097b725ae77Skettenis if (num_regs < 0)
2098b725ae77Skettenis delta -= 0x3e;
2099b725ae77Skettenis return addr + ((num_regs + delta/0x3f) << 3);
2100b725ae77Skettenis }
2101b725ae77Skettenis
2102b725ae77Skettenis /* Gdb libunwind-frame callback function to convert from an ia64 gdb register
2103b725ae77Skettenis number to a libunwind register number. */
2104b725ae77Skettenis static int
ia64_gdb2uw_regnum(int regnum)2105b725ae77Skettenis ia64_gdb2uw_regnum (int regnum)
2106b725ae77Skettenis {
2107b725ae77Skettenis if (regnum == sp_regnum)
2108b725ae77Skettenis return UNW_IA64_SP;
2109b725ae77Skettenis else if (regnum == IA64_BSP_REGNUM)
2110b725ae77Skettenis return UNW_IA64_BSP;
2111b725ae77Skettenis else if ((unsigned) (regnum - IA64_GR0_REGNUM) < 128)
2112b725ae77Skettenis return UNW_IA64_GR + (regnum - IA64_GR0_REGNUM);
2113b725ae77Skettenis else if ((unsigned) (regnum - V32_REGNUM) < 95)
2114b725ae77Skettenis return UNW_IA64_GR + 32 + (regnum - V32_REGNUM);
2115b725ae77Skettenis else if ((unsigned) (regnum - IA64_FR0_REGNUM) < 128)
2116b725ae77Skettenis return UNW_IA64_FR + (regnum - IA64_FR0_REGNUM);
2117b725ae77Skettenis else if ((unsigned) (regnum - IA64_PR0_REGNUM) < 64)
2118b725ae77Skettenis return -1;
2119b725ae77Skettenis else if ((unsigned) (regnum - IA64_BR0_REGNUM) < 8)
2120b725ae77Skettenis return UNW_IA64_BR + (regnum - IA64_BR0_REGNUM);
2121b725ae77Skettenis else if (regnum == IA64_PR_REGNUM)
2122b725ae77Skettenis return UNW_IA64_PR;
2123b725ae77Skettenis else if (regnum == IA64_IP_REGNUM)
2124b725ae77Skettenis return UNW_REG_IP;
2125b725ae77Skettenis else if (regnum == IA64_CFM_REGNUM)
2126b725ae77Skettenis return UNW_IA64_CFM;
2127b725ae77Skettenis else if ((unsigned) (regnum - IA64_AR0_REGNUM) < 128)
2128b725ae77Skettenis return UNW_IA64_AR + (regnum - IA64_AR0_REGNUM);
2129b725ae77Skettenis else if ((unsigned) (regnum - IA64_NAT0_REGNUM) < 128)
2130b725ae77Skettenis return UNW_IA64_NAT + (regnum - IA64_NAT0_REGNUM);
2131b725ae77Skettenis else
2132b725ae77Skettenis return -1;
2133b725ae77Skettenis }
2134b725ae77Skettenis
2135b725ae77Skettenis /* Gdb libunwind-frame callback function to convert from a libunwind register
2136b725ae77Skettenis number to a ia64 gdb register number. */
2137b725ae77Skettenis static int
ia64_uw2gdb_regnum(int uw_regnum)2138b725ae77Skettenis ia64_uw2gdb_regnum (int uw_regnum)
2139b725ae77Skettenis {
2140b725ae77Skettenis if (uw_regnum == UNW_IA64_SP)
2141b725ae77Skettenis return sp_regnum;
2142b725ae77Skettenis else if (uw_regnum == UNW_IA64_BSP)
2143b725ae77Skettenis return IA64_BSP_REGNUM;
2144b725ae77Skettenis else if ((unsigned) (uw_regnum - UNW_IA64_GR) < 32)
2145b725ae77Skettenis return IA64_GR0_REGNUM + (uw_regnum - UNW_IA64_GR);
2146b725ae77Skettenis else if ((unsigned) (uw_regnum - UNW_IA64_GR) < 128)
2147b725ae77Skettenis return V32_REGNUM + (uw_regnum - (IA64_GR0_REGNUM + 32));
2148b725ae77Skettenis else if ((unsigned) (uw_regnum - UNW_IA64_FR) < 128)
2149b725ae77Skettenis return IA64_FR0_REGNUM + (uw_regnum - UNW_IA64_FR);
2150b725ae77Skettenis else if ((unsigned) (uw_regnum - UNW_IA64_BR) < 8)
2151b725ae77Skettenis return IA64_BR0_REGNUM + (uw_regnum - UNW_IA64_BR);
2152b725ae77Skettenis else if (uw_regnum == UNW_IA64_PR)
2153b725ae77Skettenis return IA64_PR_REGNUM;
2154b725ae77Skettenis else if (uw_regnum == UNW_REG_IP)
2155b725ae77Skettenis return IA64_IP_REGNUM;
2156b725ae77Skettenis else if (uw_regnum == UNW_IA64_CFM)
2157b725ae77Skettenis return IA64_CFM_REGNUM;
2158b725ae77Skettenis else if ((unsigned) (uw_regnum - UNW_IA64_AR) < 128)
2159b725ae77Skettenis return IA64_AR0_REGNUM + (uw_regnum - UNW_IA64_AR);
2160b725ae77Skettenis else if ((unsigned) (uw_regnum - UNW_IA64_NAT) < 128)
2161b725ae77Skettenis return IA64_NAT0_REGNUM + (uw_regnum - UNW_IA64_NAT);
2162b725ae77Skettenis else
2163b725ae77Skettenis return -1;
2164b725ae77Skettenis }
2165b725ae77Skettenis
2166b725ae77Skettenis /* Gdb libunwind-frame callback function to reveal if register is a float
2167b725ae77Skettenis register or not. */
2168b725ae77Skettenis static int
ia64_is_fpreg(int uw_regnum)2169b725ae77Skettenis ia64_is_fpreg (int uw_regnum)
2170b725ae77Skettenis {
2171b725ae77Skettenis return unw_is_fpreg (uw_regnum);
2172b725ae77Skettenis }
2173b725ae77Skettenis
2174b725ae77Skettenis /* Libunwind callback accessor function for general registers. */
2175b725ae77Skettenis static int
ia64_access_reg(unw_addr_space_t as,unw_regnum_t uw_regnum,unw_word_t * val,int write,void * arg)2176b725ae77Skettenis ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
2177b725ae77Skettenis int write, void *arg)
2178b725ae77Skettenis {
2179b725ae77Skettenis int regnum = ia64_uw2gdb_regnum (uw_regnum);
2180b725ae77Skettenis unw_word_t bsp, sof, sol, cfm, psr, ip;
2181b725ae77Skettenis struct frame_info *next_frame = arg;
2182b725ae77Skettenis long new_sof, old_sof;
2183b725ae77Skettenis char buf[MAX_REGISTER_SIZE];
2184b725ae77Skettenis
2185b725ae77Skettenis if (write)
2186b725ae77Skettenis {
2187b725ae77Skettenis if (regnum < 0)
2188b725ae77Skettenis /* ignore writes to pseudo-registers such as UNW_IA64_PROC_STARTI. */
2189b725ae77Skettenis return 0;
2190b725ae77Skettenis
2191b725ae77Skettenis switch (uw_regnum)
2192b725ae77Skettenis {
2193b725ae77Skettenis case UNW_REG_IP:
2194b725ae77Skettenis ia64_write_pc (*val, inferior_ptid);
2195b725ae77Skettenis break;
2196b725ae77Skettenis
2197b725ae77Skettenis case UNW_IA64_AR_BSPSTORE:
2198b725ae77Skettenis write_register (IA64_BSP_REGNUM, *val);
2199b725ae77Skettenis break;
2200b725ae77Skettenis
2201b725ae77Skettenis case UNW_IA64_AR_BSP:
2202b725ae77Skettenis case UNW_IA64_BSP:
2203b725ae77Skettenis /* Account for the fact that ptrace() expects bsp to point
2204b725ae77Skettenis after the current register frame. */
2205b725ae77Skettenis cfm = read_register (IA64_CFM_REGNUM);
2206b725ae77Skettenis sof = (cfm & 0x7f);
2207b725ae77Skettenis bsp = ia64_rse_skip_regs (*val, sof);
2208b725ae77Skettenis write_register (IA64_BSP_REGNUM, bsp);
2209b725ae77Skettenis break;
2210b725ae77Skettenis
2211b725ae77Skettenis case UNW_IA64_CFM:
2212b725ae77Skettenis /* If we change CFM, we need to adjust ptrace's notion of
2213b725ae77Skettenis bsp accordingly, so that the real bsp remains
2214b725ae77Skettenis unchanged. */
2215b725ae77Skettenis bsp = read_register (IA64_BSP_REGNUM);
2216b725ae77Skettenis cfm = read_register (IA64_CFM_REGNUM);
2217b725ae77Skettenis old_sof = (cfm & 0x7f);
2218b725ae77Skettenis new_sof = (*val & 0x7f);
2219b725ae77Skettenis if (old_sof != new_sof)
2220b725ae77Skettenis {
2221b725ae77Skettenis bsp = ia64_rse_skip_regs (bsp, -old_sof + new_sof);
2222b725ae77Skettenis write_register (IA64_BSP_REGNUM, bsp);
2223b725ae77Skettenis }
2224b725ae77Skettenis write_register (IA64_CFM_REGNUM, *val);
2225b725ae77Skettenis break;
2226b725ae77Skettenis
2227b725ae77Skettenis default:
2228b725ae77Skettenis write_register (regnum, *val);
2229b725ae77Skettenis break;
2230b725ae77Skettenis }
2231b725ae77Skettenis if (gdbarch_debug >= 1)
2232b725ae77Skettenis fprintf_unfiltered (gdb_stdlog,
2233b725ae77Skettenis " access_reg: to cache: %4s=0x%s\n",
2234b725ae77Skettenis (((unsigned) regnum <= IA64_NAT127_REGNUM)
2235b725ae77Skettenis ? ia64_register_names[regnum] : "r??"),
2236b725ae77Skettenis paddr_nz (*val));
2237b725ae77Skettenis }
2238b725ae77Skettenis else
2239b725ae77Skettenis {
2240b725ae77Skettenis switch (uw_regnum)
2241b725ae77Skettenis {
2242b725ae77Skettenis case UNW_REG_IP:
2243b725ae77Skettenis /* Libunwind expects to see the pc value which means the slot number
2244b725ae77Skettenis from the psr must be merged with the ip word address. */
2245b725ae77Skettenis frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
2246b725ae77Skettenis ip = extract_unsigned_integer (buf, 8);
2247b725ae77Skettenis frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
2248b725ae77Skettenis psr = extract_unsigned_integer (buf, 8);
2249b725ae77Skettenis *val = ip | ((psr >> 41) & 0x3);
2250b725ae77Skettenis break;
2251b725ae77Skettenis
2252b725ae77Skettenis case UNW_IA64_AR_BSP:
2253b725ae77Skettenis /* Libunwind expects to see the beginning of the current register
2254b725ae77Skettenis frame so we must account for the fact that ptrace() will return a value
2255b725ae77Skettenis for bsp that points *after* the current register frame. */
2256b725ae77Skettenis frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
2257b725ae77Skettenis bsp = extract_unsigned_integer (buf, 8);
2258b725ae77Skettenis frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
2259b725ae77Skettenis cfm = extract_unsigned_integer (buf, 8);
2260b725ae77Skettenis sof = (cfm & 0x7f);
2261b725ae77Skettenis *val = ia64_rse_skip_regs (bsp, -sof);
2262b725ae77Skettenis break;
2263b725ae77Skettenis
2264b725ae77Skettenis case UNW_IA64_AR_BSPSTORE:
2265b725ae77Skettenis /* Libunwind wants bspstore to be after the current register frame.
2266b725ae77Skettenis This is what ptrace() and gdb treats as the regular bsp value. */
2267b725ae77Skettenis frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
2268b725ae77Skettenis *val = extract_unsigned_integer (buf, 8);
2269b725ae77Skettenis break;
2270b725ae77Skettenis
2271b725ae77Skettenis default:
2272b725ae77Skettenis /* For all other registers, just unwind the value directly. */
2273b725ae77Skettenis frame_unwind_register (next_frame, regnum, buf);
2274b725ae77Skettenis *val = extract_unsigned_integer (buf, 8);
2275b725ae77Skettenis break;
2276b725ae77Skettenis }
2277b725ae77Skettenis
2278b725ae77Skettenis if (gdbarch_debug >= 1)
2279b725ae77Skettenis fprintf_unfiltered (gdb_stdlog,
2280b725ae77Skettenis " access_reg: from cache: %4s=0x%s\n",
2281b725ae77Skettenis (((unsigned) regnum <= IA64_NAT127_REGNUM)
2282b725ae77Skettenis ? ia64_register_names[regnum] : "r??"),
2283b725ae77Skettenis paddr_nz (*val));
2284b725ae77Skettenis }
2285b725ae77Skettenis return 0;
2286b725ae77Skettenis }
2287b725ae77Skettenis
2288b725ae77Skettenis /* Libunwind callback accessor function for floating-point registers. */
2289b725ae77Skettenis static int
ia64_access_fpreg(unw_addr_space_t as,unw_regnum_t uw_regnum,unw_fpreg_t * val,int write,void * arg)2290b725ae77Skettenis ia64_access_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_fpreg_t *val,
2291b725ae77Skettenis int write, void *arg)
2292b725ae77Skettenis {
2293b725ae77Skettenis int regnum = ia64_uw2gdb_regnum (uw_regnum);
2294b725ae77Skettenis
2295b725ae77Skettenis if (write)
2296b725ae77Skettenis regcache_cooked_write (current_regcache, regnum, (char *) val);
2297b725ae77Skettenis else
2298b725ae77Skettenis regcache_cooked_read (current_regcache, regnum, (char *) val);
2299b725ae77Skettenis return 0;
2300b725ae77Skettenis }
2301b725ae77Skettenis
2302b725ae77Skettenis /* Libunwind callback accessor function for accessing memory. */
2303b725ae77Skettenis static int
ia64_access_mem(unw_addr_space_t as,unw_word_t addr,unw_word_t * val,int write,void * arg)2304b725ae77Skettenis ia64_access_mem (unw_addr_space_t as,
2305b725ae77Skettenis unw_word_t addr, unw_word_t *val,
2306b725ae77Skettenis int write, void *arg)
2307b725ae77Skettenis {
2308b725ae77Skettenis /* XXX do we need to normalize byte-order here? */
2309b725ae77Skettenis if (write)
2310b725ae77Skettenis return target_write_memory (addr, (char *) val, sizeof (unw_word_t));
2311b725ae77Skettenis else
2312b725ae77Skettenis return target_read_memory (addr, (char *) val, sizeof (unw_word_t));
2313b725ae77Skettenis }
2314b725ae77Skettenis
2315b725ae77Skettenis /* Call low-level function to access the kernel unwind table. */
2316b725ae77Skettenis static int
getunwind_table(void * buf,size_t len)2317b725ae77Skettenis getunwind_table (void *buf, size_t len)
2318b725ae77Skettenis {
2319b725ae77Skettenis LONGEST x;
2320b725ae77Skettenis x = target_read_partial (¤t_target, TARGET_OBJECT_UNWIND_TABLE, NULL,
2321b725ae77Skettenis buf, 0, len);
2322b725ae77Skettenis
2323b725ae77Skettenis return (int)x;
2324b725ae77Skettenis }
2325b725ae77Skettenis
2326b725ae77Skettenis /* Get the kernel unwind table. */
2327b725ae77Skettenis static int
get_kernel_table(unw_word_t ip,unw_dyn_info_t * di)2328b725ae77Skettenis get_kernel_table (unw_word_t ip, unw_dyn_info_t *di)
2329b725ae77Skettenis {
2330b725ae77Skettenis size_t size;
2331b725ae77Skettenis struct ia64_table_entry
2332b725ae77Skettenis {
2333b725ae77Skettenis uint64_t start_offset;
2334b725ae77Skettenis uint64_t end_offset;
2335b725ae77Skettenis uint64_t info_offset;
2336b725ae77Skettenis };
2337b725ae77Skettenis static struct ia64_table_entry *ktab = NULL, *etab;
2338b725ae77Skettenis
2339b725ae77Skettenis if (!ktab)
2340b725ae77Skettenis {
2341b725ae77Skettenis size = getunwind_table (NULL, 0);
2342b725ae77Skettenis if ((int)size < 0)
2343b725ae77Skettenis return -UNW_ENOINFO;
2344b725ae77Skettenis ktab = xmalloc (size);
2345b725ae77Skettenis getunwind_table (ktab, size);
2346b725ae77Skettenis
2347b725ae77Skettenis /* Determine length of kernel's unwind table and relocate
2348b725ae77Skettenis it's entries. */
2349b725ae77Skettenis for (etab = ktab; etab->start_offset; ++etab)
2350b725ae77Skettenis etab->info_offset += (uint64_t) ktab;
2351b725ae77Skettenis }
2352b725ae77Skettenis
2353b725ae77Skettenis if (ip < ktab[0].start_offset || ip >= etab[-1].end_offset)
2354b725ae77Skettenis return -UNW_ENOINFO;
2355b725ae77Skettenis
2356b725ae77Skettenis di->format = UNW_INFO_FORMAT_TABLE;
2357b725ae77Skettenis di->gp = 0;
2358b725ae77Skettenis di->start_ip = ktab[0].start_offset;
2359b725ae77Skettenis di->end_ip = etab[-1].end_offset;
2360b725ae77Skettenis di->u.ti.name_ptr = (unw_word_t) "<kernel>";
2361b725ae77Skettenis di->u.ti.segbase = 0;
2362b725ae77Skettenis di->u.ti.table_len = ((char *) etab - (char *) ktab) / sizeof (unw_word_t);
2363b725ae77Skettenis di->u.ti.table_data = (unw_word_t *) ktab;
2364b725ae77Skettenis
2365b725ae77Skettenis if (gdbarch_debug >= 1)
2366b725ae77Skettenis fprintf_unfiltered (gdb_stdlog, "get_kernel_table: found table `%s': "
2367b725ae77Skettenis "segbase=0x%s, length=%s, gp=0x%s\n",
2368b725ae77Skettenis (char *) di->u.ti.name_ptr,
2369b725ae77Skettenis paddr_nz (di->u.ti.segbase),
2370b725ae77Skettenis paddr_u (di->u.ti.table_len),
2371b725ae77Skettenis paddr_nz (di->gp));
2372b725ae77Skettenis return 0;
2373b725ae77Skettenis }
2374b725ae77Skettenis
2375b725ae77Skettenis /* Find the unwind table entry for a specified address. */
2376b725ae77Skettenis static int
ia64_find_unwind_table(struct objfile * objfile,unw_word_t ip,unw_dyn_info_t * dip,void ** buf)2377b725ae77Skettenis ia64_find_unwind_table (struct objfile *objfile, unw_word_t ip,
2378b725ae77Skettenis unw_dyn_info_t *dip, void **buf)
2379b725ae77Skettenis {
2380b725ae77Skettenis Elf_Internal_Phdr *phdr, *p_text = NULL, *p_unwind = NULL;
2381b725ae77Skettenis Elf_Internal_Ehdr *ehdr;
2382b725ae77Skettenis unw_word_t segbase = 0;
2383b725ae77Skettenis CORE_ADDR load_base;
2384b725ae77Skettenis bfd *bfd;
2385b725ae77Skettenis int i;
2386b725ae77Skettenis
2387b725ae77Skettenis bfd = objfile->obfd;
2388b725ae77Skettenis
2389b725ae77Skettenis ehdr = elf_tdata (bfd)->elf_header;
2390b725ae77Skettenis phdr = elf_tdata (bfd)->phdr;
2391b725ae77Skettenis
2392b725ae77Skettenis load_base = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
2393b725ae77Skettenis
2394b725ae77Skettenis for (i = 0; i < ehdr->e_phnum; ++i)
2395b725ae77Skettenis {
2396b725ae77Skettenis switch (phdr[i].p_type)
2397b725ae77Skettenis {
2398b725ae77Skettenis case PT_LOAD:
2399b725ae77Skettenis if ((unw_word_t) (ip - load_base - phdr[i].p_vaddr)
2400b725ae77Skettenis < phdr[i].p_memsz)
2401b725ae77Skettenis p_text = phdr + i;
2402b725ae77Skettenis break;
2403b725ae77Skettenis
2404b725ae77Skettenis case PT_IA_64_UNWIND:
2405b725ae77Skettenis p_unwind = phdr + i;
2406b725ae77Skettenis break;
2407b725ae77Skettenis
2408b725ae77Skettenis default:
2409b725ae77Skettenis break;
2410b725ae77Skettenis }
2411b725ae77Skettenis }
2412b725ae77Skettenis
2413b725ae77Skettenis if (!p_text || !p_unwind
2414b725ae77Skettenis /* Verify that the segment that contains the IP also contains
2415b725ae77Skettenis the static unwind table. If not, we are dealing with
2416b725ae77Skettenis runtime-generated code, for which we have no info here. */
2417b725ae77Skettenis || (p_unwind->p_vaddr - p_text->p_vaddr) >= p_text->p_memsz)
2418b725ae77Skettenis return -UNW_ENOINFO;
2419b725ae77Skettenis
2420b725ae77Skettenis segbase = p_text->p_vaddr + load_base;
2421b725ae77Skettenis
2422b725ae77Skettenis dip->start_ip = segbase;
2423b725ae77Skettenis dip->end_ip = dip->start_ip + p_text->p_memsz;
2424b725ae77Skettenis dip->gp = FIND_GLOBAL_POINTER (ip);
2425b725ae77Skettenis dip->format = UNW_INFO_FORMAT_REMOTE_TABLE;
2426b725ae77Skettenis dip->u.rti.name_ptr = (unw_word_t) bfd_get_filename (bfd);
2427b725ae77Skettenis dip->u.rti.segbase = segbase;
2428b725ae77Skettenis dip->u.rti.table_len = p_unwind->p_memsz / sizeof (unw_word_t);
2429b725ae77Skettenis dip->u.rti.table_data = p_unwind->p_vaddr + load_base;
2430b725ae77Skettenis
2431b725ae77Skettenis return 0;
2432b725ae77Skettenis }
2433b725ae77Skettenis
2434b725ae77Skettenis /* Libunwind callback accessor function to acquire procedure unwind-info. */
2435b725ae77Skettenis static int
ia64_find_proc_info_x(unw_addr_space_t as,unw_word_t ip,unw_proc_info_t * pi,int need_unwind_info,void * arg)2436b725ae77Skettenis ia64_find_proc_info_x (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
2437b725ae77Skettenis int need_unwind_info, void *arg)
2438b725ae77Skettenis {
2439b725ae77Skettenis struct obj_section *sec = find_pc_section (ip);
2440b725ae77Skettenis unw_dyn_info_t di;
2441b725ae77Skettenis int ret;
2442b725ae77Skettenis void *buf = NULL;
2443b725ae77Skettenis
2444b725ae77Skettenis if (!sec)
2445b725ae77Skettenis {
2446b725ae77Skettenis /* XXX This only works if the host and the target architecture are
2447b725ae77Skettenis both ia64 and if the have (more or less) the same kernel
2448b725ae77Skettenis version. */
2449b725ae77Skettenis if (get_kernel_table (ip, &di) < 0)
2450b725ae77Skettenis return -UNW_ENOINFO;
2451b725ae77Skettenis
2452b725ae77Skettenis if (gdbarch_debug >= 1)
2453b725ae77Skettenis fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: 0x%s -> "
2454b725ae77Skettenis "(name=`%s',segbase=0x%s,start=0x%s,end=0x%s,gp=0x%s,"
2455b725ae77Skettenis "length=%s,data=0x%s)\n",
2456b725ae77Skettenis paddr_nz (ip), (char *)di.u.ti.name_ptr,
2457b725ae77Skettenis paddr_nz (di.u.ti.segbase),
2458b725ae77Skettenis paddr_nz (di.start_ip), paddr_nz (di.end_ip),
2459b725ae77Skettenis paddr_nz (di.gp),
2460b725ae77Skettenis paddr_u (di.u.ti.table_len),
2461b725ae77Skettenis paddr_nz ((CORE_ADDR)di.u.ti.table_data));
2462b725ae77Skettenis }
2463b725ae77Skettenis else
2464b725ae77Skettenis {
2465b725ae77Skettenis ret = ia64_find_unwind_table (sec->objfile, ip, &di, &buf);
2466b725ae77Skettenis if (ret < 0)
2467b725ae77Skettenis return ret;
2468b725ae77Skettenis
2469b725ae77Skettenis if (gdbarch_debug >= 1)
2470b725ae77Skettenis fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: 0x%s -> "
2471b725ae77Skettenis "(name=`%s',segbase=0x%s,start=0x%s,end=0x%s,gp=0x%s,"
2472b725ae77Skettenis "length=%s,data=0x%s)\n",
2473b725ae77Skettenis paddr_nz (ip), (char *)di.u.rti.name_ptr,
2474b725ae77Skettenis paddr_nz (di.u.rti.segbase),
2475b725ae77Skettenis paddr_nz (di.start_ip), paddr_nz (di.end_ip),
2476b725ae77Skettenis paddr_nz (di.gp),
2477b725ae77Skettenis paddr_u (di.u.rti.table_len),
2478b725ae77Skettenis paddr_nz (di.u.rti.table_data));
2479b725ae77Skettenis }
2480b725ae77Skettenis
2481b725ae77Skettenis ret = libunwind_search_unwind_table (&as, ip, &di, pi, need_unwind_info,
2482b725ae77Skettenis arg);
2483b725ae77Skettenis
2484b725ae77Skettenis /* We no longer need the dyn info storage so free it. */
2485b725ae77Skettenis xfree (buf);
2486b725ae77Skettenis
2487b725ae77Skettenis return ret;
2488b725ae77Skettenis }
2489b725ae77Skettenis
2490b725ae77Skettenis /* Libunwind callback accessor function for cleanup. */
2491b725ae77Skettenis static void
ia64_put_unwind_info(unw_addr_space_t as,unw_proc_info_t * pip,void * arg)2492b725ae77Skettenis ia64_put_unwind_info (unw_addr_space_t as,
2493b725ae77Skettenis unw_proc_info_t *pip, void *arg)
2494b725ae77Skettenis {
2495b725ae77Skettenis /* Nothing required for now. */
2496b725ae77Skettenis }
2497b725ae77Skettenis
2498b725ae77Skettenis /* Libunwind callback accessor function to get head of the dynamic
2499b725ae77Skettenis unwind-info registration list. */
2500b725ae77Skettenis static int
ia64_get_dyn_info_list(unw_addr_space_t as,unw_word_t * dilap,void * arg)2501b725ae77Skettenis ia64_get_dyn_info_list (unw_addr_space_t as,
2502b725ae77Skettenis unw_word_t *dilap, void *arg)
2503b725ae77Skettenis {
2504b725ae77Skettenis struct obj_section *text_sec;
2505b725ae77Skettenis struct objfile *objfile;
2506b725ae77Skettenis unw_word_t ip, addr;
2507b725ae77Skettenis unw_dyn_info_t di;
2508b725ae77Skettenis int ret;
2509b725ae77Skettenis
2510b725ae77Skettenis if (!libunwind_is_initialized ())
2511b725ae77Skettenis return -UNW_ENOINFO;
2512b725ae77Skettenis
2513b725ae77Skettenis for (objfile = object_files; objfile; objfile = objfile->next)
2514b725ae77Skettenis {
2515b725ae77Skettenis void *buf = NULL;
2516b725ae77Skettenis
2517b725ae77Skettenis text_sec = objfile->sections + SECT_OFF_TEXT (objfile);
2518b725ae77Skettenis ip = text_sec->addr;
2519b725ae77Skettenis ret = ia64_find_unwind_table (objfile, ip, &di, &buf);
2520b725ae77Skettenis if (ret >= 0)
2521b725ae77Skettenis {
2522b725ae77Skettenis addr = libunwind_find_dyn_list (as, &di, arg);
2523b725ae77Skettenis /* We no longer need the dyn info storage so free it. */
2524b725ae77Skettenis xfree (buf);
2525b725ae77Skettenis
2526b725ae77Skettenis if (addr)
2527b725ae77Skettenis {
2528b725ae77Skettenis if (gdbarch_debug >= 1)
2529b725ae77Skettenis fprintf_unfiltered (gdb_stdlog,
2530b725ae77Skettenis "dynamic unwind table in objfile %s "
2531b725ae77Skettenis "at 0x%s (gp=0x%s)\n",
2532b725ae77Skettenis bfd_get_filename (objfile->obfd),
2533b725ae77Skettenis paddr_nz (addr), paddr_nz (di.gp));
2534b725ae77Skettenis *dilap = addr;
2535b725ae77Skettenis return 0;
2536b725ae77Skettenis }
2537b725ae77Skettenis }
2538b725ae77Skettenis }
2539b725ae77Skettenis return -UNW_ENOINFO;
2540b725ae77Skettenis }
2541b725ae77Skettenis
2542b725ae77Skettenis
2543b725ae77Skettenis /* Frame interface functions for libunwind. */
2544b725ae77Skettenis
2545b725ae77Skettenis static void
ia64_libunwind_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)2546b725ae77Skettenis ia64_libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
2547b725ae77Skettenis struct frame_id *this_id)
2548b725ae77Skettenis {
2549b725ae77Skettenis char buf[8];
2550b725ae77Skettenis CORE_ADDR bsp;
2551b725ae77Skettenis struct frame_id id;
2552b725ae77Skettenis
2553b725ae77Skettenis libunwind_frame_this_id (next_frame, this_cache, &id);
2554b725ae77Skettenis
2555b725ae77Skettenis /* We must add the bsp as the special address for frame comparison purposes. */
2556b725ae77Skettenis frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
2557b725ae77Skettenis bsp = extract_unsigned_integer (buf, 8);
2558b725ae77Skettenis
2559b725ae77Skettenis (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
2560b725ae77Skettenis
2561b725ae77Skettenis if (gdbarch_debug >= 1)
2562b725ae77Skettenis fprintf_unfiltered (gdb_stdlog,
2563b725ae77Skettenis "libunwind frame id: code 0x%s, stack 0x%s, special 0x%s, next_frame %p\n",
2564b725ae77Skettenis paddr_nz (id.code_addr), paddr_nz (id.stack_addr),
2565b725ae77Skettenis paddr_nz (bsp), next_frame);
2566b725ae77Skettenis }
2567b725ae77Skettenis
2568b725ae77Skettenis static void
ia64_libunwind_frame_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)2569b725ae77Skettenis ia64_libunwind_frame_prev_register (struct frame_info *next_frame,
2570b725ae77Skettenis void **this_cache,
2571b725ae77Skettenis int regnum, int *optimizedp,
2572b725ae77Skettenis enum lval_type *lvalp, CORE_ADDR *addrp,
2573b725ae77Skettenis int *realnump, void *valuep)
2574b725ae77Skettenis {
2575b725ae77Skettenis int reg = regnum;
2576b725ae77Skettenis
2577b725ae77Skettenis if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
2578b725ae77Skettenis reg = IA64_PR_REGNUM;
2579b725ae77Skettenis else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
2580b725ae77Skettenis reg = IA64_UNAT_REGNUM;
2581b725ae77Skettenis
2582b725ae77Skettenis /* Let libunwind do most of the work. */
2583b725ae77Skettenis libunwind_frame_prev_register (next_frame, this_cache, reg,
2584b725ae77Skettenis optimizedp, lvalp, addrp, realnump, valuep);
2585b725ae77Skettenis
2586*11efff7fSkettenis /* No more to do if the value is not supposed to be supplied. */
2587*11efff7fSkettenis if (!valuep)
2588*11efff7fSkettenis return;
2589*11efff7fSkettenis
2590b725ae77Skettenis if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
2591b725ae77Skettenis {
2592b725ae77Skettenis ULONGEST prN_val;
2593b725ae77Skettenis
2594b725ae77Skettenis if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
2595b725ae77Skettenis {
2596b725ae77Skettenis int rrb_pr = 0;
2597b725ae77Skettenis ULONGEST cfm;
2598b725ae77Skettenis unsigned char buf[MAX_REGISTER_SIZE];
2599b725ae77Skettenis
2600b725ae77Skettenis /* Fetch predicate register rename base from current frame
2601b725ae77Skettenis marker for this frame. */
2602b725ae77Skettenis frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
2603b725ae77Skettenis cfm = extract_unsigned_integer (buf, 8);
2604b725ae77Skettenis rrb_pr = (cfm >> 32) & 0x3f;
2605b725ae77Skettenis
2606b725ae77Skettenis /* Adjust the register number to account for register rotation. */
2607b725ae77Skettenis regnum = VP16_REGNUM
2608b725ae77Skettenis + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
2609b725ae77Skettenis }
2610b725ae77Skettenis prN_val = extract_bit_field ((unsigned char *) valuep,
2611b725ae77Skettenis regnum - VP0_REGNUM, 1);
2612b725ae77Skettenis store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), prN_val);
2613b725ae77Skettenis }
2614b725ae77Skettenis else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
2615b725ae77Skettenis {
2616b725ae77Skettenis ULONGEST unatN_val;
2617b725ae77Skettenis
2618b725ae77Skettenis unatN_val = extract_bit_field ((unsigned char *) valuep,
2619b725ae77Skettenis regnum - IA64_NAT0_REGNUM, 1);
2620b725ae77Skettenis store_unsigned_integer (valuep, register_size (current_gdbarch, regnum),
2621b725ae77Skettenis unatN_val);
2622b725ae77Skettenis }
2623b725ae77Skettenis else if (regnum == IA64_BSP_REGNUM)
2624b725ae77Skettenis {
2625b725ae77Skettenis char cfm_valuep[MAX_REGISTER_SIZE];
2626b725ae77Skettenis int cfm_optim;
2627b725ae77Skettenis int cfm_realnum;
2628b725ae77Skettenis enum lval_type cfm_lval;
2629b725ae77Skettenis CORE_ADDR cfm_addr;
2630b725ae77Skettenis CORE_ADDR bsp, prev_cfm, prev_bsp;
2631b725ae77Skettenis
2632b725ae77Skettenis /* We want to calculate the previous bsp as the end of the previous register stack frame.
2633b725ae77Skettenis This corresponds to what the hardware bsp register will be if we pop the frame
2634b725ae77Skettenis back which is why we might have been called. We know that libunwind will pass us back
2635b725ae77Skettenis the beginning of the current frame so we should just add sof to it. */
2636b725ae77Skettenis prev_bsp = extract_unsigned_integer (valuep, 8);
2637b725ae77Skettenis libunwind_frame_prev_register (next_frame, this_cache, IA64_CFM_REGNUM,
2638b725ae77Skettenis &cfm_optim, &cfm_lval, &cfm_addr, &cfm_realnum, cfm_valuep);
2639b725ae77Skettenis prev_cfm = extract_unsigned_integer (cfm_valuep, 8);
2640b725ae77Skettenis prev_bsp = rse_address_add (prev_bsp, (prev_cfm & 0x7f));
2641b725ae77Skettenis
2642b725ae77Skettenis store_unsigned_integer (valuep, register_size (current_gdbarch, regnum),
2643b725ae77Skettenis prev_bsp);
2644b725ae77Skettenis }
2645b725ae77Skettenis
2646b725ae77Skettenis if (gdbarch_debug >= 1)
2647b725ae77Skettenis fprintf_unfiltered (gdb_stdlog,
2648b725ae77Skettenis "libunwind prev register <%s> is 0x%s\n",
2649b725ae77Skettenis (((unsigned) regnum <= IA64_NAT127_REGNUM)
2650b725ae77Skettenis ? ia64_register_names[regnum] : "r??"),
2651b725ae77Skettenis paddr_nz (extract_unsigned_integer (valuep, 8)));
2652b725ae77Skettenis }
2653b725ae77Skettenis
2654b725ae77Skettenis static const struct frame_unwind ia64_libunwind_frame_unwind =
2655b725ae77Skettenis {
2656b725ae77Skettenis NORMAL_FRAME,
2657b725ae77Skettenis ia64_libunwind_frame_this_id,
2658b725ae77Skettenis ia64_libunwind_frame_prev_register
2659b725ae77Skettenis };
2660b725ae77Skettenis
2661b725ae77Skettenis static const struct frame_unwind *
ia64_libunwind_frame_sniffer(struct frame_info * next_frame)2662b725ae77Skettenis ia64_libunwind_frame_sniffer (struct frame_info *next_frame)
2663b725ae77Skettenis {
2664b725ae77Skettenis if (libunwind_is_initialized () && libunwind_frame_sniffer (next_frame))
2665b725ae77Skettenis return &ia64_libunwind_frame_unwind;
2666b725ae77Skettenis
2667b725ae77Skettenis return NULL;
2668b725ae77Skettenis }
2669b725ae77Skettenis
2670b725ae77Skettenis /* Set of libunwind callback acccessor functions. */
2671b725ae77Skettenis static unw_accessors_t ia64_unw_accessors =
2672b725ae77Skettenis {
2673b725ae77Skettenis ia64_find_proc_info_x,
2674b725ae77Skettenis ia64_put_unwind_info,
2675b725ae77Skettenis ia64_get_dyn_info_list,
2676b725ae77Skettenis ia64_access_mem,
2677b725ae77Skettenis ia64_access_reg,
2678b725ae77Skettenis ia64_access_fpreg,
2679b725ae77Skettenis /* resume */
2680b725ae77Skettenis /* get_proc_name */
2681b725ae77Skettenis };
2682b725ae77Skettenis
2683b725ae77Skettenis /* Set of ia64 gdb libunwind-frame callbacks and data for generic libunwind-frame code to use. */
2684b725ae77Skettenis static struct libunwind_descr ia64_libunwind_descr =
2685b725ae77Skettenis {
2686b725ae77Skettenis ia64_gdb2uw_regnum,
2687b725ae77Skettenis ia64_uw2gdb_regnum,
2688b725ae77Skettenis ia64_is_fpreg,
2689b725ae77Skettenis &ia64_unw_accessors,
2690b725ae77Skettenis };
2691b725ae77Skettenis
2692b725ae77Skettenis #endif /* HAVE_LIBUNWIND_IA64_H */
2693b725ae77Skettenis
2694b725ae77Skettenis /* Should we use DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS instead of
2695b725ae77Skettenis EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc and TYPE
2696b725ae77Skettenis is the type (which is known to be struct, union or array). */
2697b725ae77Skettenis int
ia64_use_struct_convention(int gcc_p,struct type * type)2698b725ae77Skettenis ia64_use_struct_convention (int gcc_p, struct type *type)
2699b725ae77Skettenis {
2700b725ae77Skettenis struct type *float_elt_type;
2701b725ae77Skettenis
2702b725ae77Skettenis /* HFAs are structures (or arrays) consisting entirely of floating
2703b725ae77Skettenis point values of the same length. Up to 8 of these are returned
2704b725ae77Skettenis in registers. Don't use the struct convention when this is the
2705b725ae77Skettenis case. */
2706b725ae77Skettenis float_elt_type = is_float_or_hfa_type (type);
2707b725ae77Skettenis if (float_elt_type != NULL
2708b725ae77Skettenis && TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type) <= 8)
2709b725ae77Skettenis return 0;
2710b725ae77Skettenis
2711b725ae77Skettenis /* Other structs of length 32 or less are returned in r8-r11.
2712b725ae77Skettenis Don't use the struct convention for those either. */
2713b725ae77Skettenis return TYPE_LENGTH (type) > 32;
2714b725ae77Skettenis }
2715b725ae77Skettenis
2716b725ae77Skettenis void
ia64_extract_return_value(struct type * type,struct regcache * regcache,void * valbuf)2717b725ae77Skettenis ia64_extract_return_value (struct type *type, struct regcache *regcache, void *valbuf)
2718b725ae77Skettenis {
2719b725ae77Skettenis struct type *float_elt_type;
2720b725ae77Skettenis
2721b725ae77Skettenis float_elt_type = is_float_or_hfa_type (type);
2722b725ae77Skettenis if (float_elt_type != NULL)
2723b725ae77Skettenis {
2724b725ae77Skettenis char from[MAX_REGISTER_SIZE];
2725b725ae77Skettenis int offset = 0;
2726b725ae77Skettenis int regnum = IA64_FR8_REGNUM;
2727b725ae77Skettenis int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
2728b725ae77Skettenis
2729b725ae77Skettenis while (n-- > 0)
2730b725ae77Skettenis {
2731b725ae77Skettenis regcache_cooked_read (regcache, regnum, from);
2732b725ae77Skettenis convert_typed_floating (from, builtin_type_ia64_ext,
2733b725ae77Skettenis (char *)valbuf + offset, float_elt_type);
2734b725ae77Skettenis offset += TYPE_LENGTH (float_elt_type);
2735b725ae77Skettenis regnum++;
2736b725ae77Skettenis }
2737b725ae77Skettenis }
2738b725ae77Skettenis else
2739b725ae77Skettenis {
2740b725ae77Skettenis ULONGEST val;
2741b725ae77Skettenis int offset = 0;
2742b725ae77Skettenis int regnum = IA64_GR8_REGNUM;
2743b725ae77Skettenis int reglen = TYPE_LENGTH (ia64_register_type (NULL, IA64_GR8_REGNUM));
2744b725ae77Skettenis int n = TYPE_LENGTH (type) / reglen;
2745b725ae77Skettenis int m = TYPE_LENGTH (type) % reglen;
2746b725ae77Skettenis
2747b725ae77Skettenis while (n-- > 0)
2748b725ae77Skettenis {
2749b725ae77Skettenis ULONGEST val;
2750b725ae77Skettenis regcache_cooked_read_unsigned (regcache, regnum, &val);
2751b725ae77Skettenis memcpy ((char *)valbuf + offset, &val, reglen);
2752b725ae77Skettenis offset += reglen;
2753b725ae77Skettenis regnum++;
2754b725ae77Skettenis }
2755b725ae77Skettenis
2756b725ae77Skettenis if (m)
2757b725ae77Skettenis {
2758b725ae77Skettenis regcache_cooked_read_unsigned (regcache, regnum, &val);
2759b725ae77Skettenis memcpy ((char *)valbuf + offset, &val, m);
2760b725ae77Skettenis }
2761b725ae77Skettenis }
2762b725ae77Skettenis }
2763b725ae77Skettenis
2764b725ae77Skettenis CORE_ADDR
ia64_extract_struct_value_address(struct regcache * regcache)2765b725ae77Skettenis ia64_extract_struct_value_address (struct regcache *regcache)
2766b725ae77Skettenis {
2767b725ae77Skettenis error ("ia64_extract_struct_value_address called and cannot get struct value address");
2768b725ae77Skettenis return 0;
2769b725ae77Skettenis }
2770b725ae77Skettenis
2771b725ae77Skettenis
2772b725ae77Skettenis static int
is_float_or_hfa_type_recurse(struct type * t,struct type ** etp)2773b725ae77Skettenis is_float_or_hfa_type_recurse (struct type *t, struct type **etp)
2774b725ae77Skettenis {
2775b725ae77Skettenis switch (TYPE_CODE (t))
2776b725ae77Skettenis {
2777b725ae77Skettenis case TYPE_CODE_FLT:
2778b725ae77Skettenis if (*etp)
2779b725ae77Skettenis return TYPE_LENGTH (*etp) == TYPE_LENGTH (t);
2780b725ae77Skettenis else
2781b725ae77Skettenis {
2782b725ae77Skettenis *etp = t;
2783b725ae77Skettenis return 1;
2784b725ae77Skettenis }
2785b725ae77Skettenis break;
2786b725ae77Skettenis case TYPE_CODE_ARRAY:
2787b725ae77Skettenis return
2788b725ae77Skettenis is_float_or_hfa_type_recurse (check_typedef (TYPE_TARGET_TYPE (t)),
2789b725ae77Skettenis etp);
2790b725ae77Skettenis break;
2791b725ae77Skettenis case TYPE_CODE_STRUCT:
2792b725ae77Skettenis {
2793b725ae77Skettenis int i;
2794b725ae77Skettenis
2795b725ae77Skettenis for (i = 0; i < TYPE_NFIELDS (t); i++)
2796b725ae77Skettenis if (!is_float_or_hfa_type_recurse
2797b725ae77Skettenis (check_typedef (TYPE_FIELD_TYPE (t, i)), etp))
2798b725ae77Skettenis return 0;
2799b725ae77Skettenis return 1;
2800b725ae77Skettenis }
2801b725ae77Skettenis break;
2802b725ae77Skettenis default:
2803b725ae77Skettenis return 0;
2804b725ae77Skettenis break;
2805b725ae77Skettenis }
2806b725ae77Skettenis }
2807b725ae77Skettenis
2808b725ae77Skettenis /* Determine if the given type is one of the floating point types or
2809b725ae77Skettenis and HFA (which is a struct, array, or combination thereof whose
2810b725ae77Skettenis bottom-most elements are all of the same floating point type). */
2811b725ae77Skettenis
2812b725ae77Skettenis static struct type *
is_float_or_hfa_type(struct type * t)2813b725ae77Skettenis is_float_or_hfa_type (struct type *t)
2814b725ae77Skettenis {
2815b725ae77Skettenis struct type *et = 0;
2816b725ae77Skettenis
2817b725ae77Skettenis return is_float_or_hfa_type_recurse (t, &et) ? et : 0;
2818b725ae77Skettenis }
2819b725ae77Skettenis
2820b725ae77Skettenis
2821b725ae77Skettenis /* Return 1 if the alignment of T is such that the next even slot
2822b725ae77Skettenis should be used. Return 0, if the next available slot should
2823b725ae77Skettenis be used. (See section 8.5.1 of the IA-64 Software Conventions
2824b725ae77Skettenis and Runtime manual). */
2825b725ae77Skettenis
2826b725ae77Skettenis static int
slot_alignment_is_next_even(struct type * t)2827b725ae77Skettenis slot_alignment_is_next_even (struct type *t)
2828b725ae77Skettenis {
2829b725ae77Skettenis switch (TYPE_CODE (t))
2830b725ae77Skettenis {
2831b725ae77Skettenis case TYPE_CODE_INT:
2832b725ae77Skettenis case TYPE_CODE_FLT:
2833b725ae77Skettenis if (TYPE_LENGTH (t) > 8)
2834b725ae77Skettenis return 1;
2835b725ae77Skettenis else
2836b725ae77Skettenis return 0;
2837b725ae77Skettenis case TYPE_CODE_ARRAY:
2838b725ae77Skettenis return
2839b725ae77Skettenis slot_alignment_is_next_even (check_typedef (TYPE_TARGET_TYPE (t)));
2840b725ae77Skettenis case TYPE_CODE_STRUCT:
2841b725ae77Skettenis {
2842b725ae77Skettenis int i;
2843b725ae77Skettenis
2844b725ae77Skettenis for (i = 0; i < TYPE_NFIELDS (t); i++)
2845b725ae77Skettenis if (slot_alignment_is_next_even
2846b725ae77Skettenis (check_typedef (TYPE_FIELD_TYPE (t, i))))
2847b725ae77Skettenis return 1;
2848b725ae77Skettenis return 0;
2849b725ae77Skettenis }
2850b725ae77Skettenis default:
2851b725ae77Skettenis return 0;
2852b725ae77Skettenis }
2853b725ae77Skettenis }
2854b725ae77Skettenis
2855b725ae77Skettenis /* Attempt to find (and return) the global pointer for the given
2856b725ae77Skettenis function.
2857b725ae77Skettenis
2858b725ae77Skettenis This is a rather nasty bit of code searchs for the .dynamic section
2859b725ae77Skettenis in the objfile corresponding to the pc of the function we're trying
2860b725ae77Skettenis to call. Once it finds the addresses at which the .dynamic section
2861b725ae77Skettenis lives in the child process, it scans the Elf64_Dyn entries for a
2862b725ae77Skettenis DT_PLTGOT tag. If it finds one of these, the corresponding
2863b725ae77Skettenis d_un.d_ptr value is the global pointer. */
2864b725ae77Skettenis
2865b725ae77Skettenis static CORE_ADDR
generic_elf_find_global_pointer(CORE_ADDR faddr)2866b725ae77Skettenis generic_elf_find_global_pointer (CORE_ADDR faddr)
2867b725ae77Skettenis {
2868b725ae77Skettenis struct obj_section *faddr_sect;
2869b725ae77Skettenis
2870b725ae77Skettenis faddr_sect = find_pc_section (faddr);
2871b725ae77Skettenis if (faddr_sect != NULL)
2872b725ae77Skettenis {
2873b725ae77Skettenis struct obj_section *osect;
2874b725ae77Skettenis
2875b725ae77Skettenis ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
2876b725ae77Skettenis {
2877b725ae77Skettenis if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
2878b725ae77Skettenis break;
2879b725ae77Skettenis }
2880b725ae77Skettenis
2881b725ae77Skettenis if (osect < faddr_sect->objfile->sections_end)
2882b725ae77Skettenis {
2883b725ae77Skettenis CORE_ADDR addr;
2884b725ae77Skettenis
2885b725ae77Skettenis addr = osect->addr;
2886b725ae77Skettenis while (addr < osect->endaddr)
2887b725ae77Skettenis {
2888b725ae77Skettenis int status;
2889b725ae77Skettenis LONGEST tag;
2890b725ae77Skettenis char buf[8];
2891b725ae77Skettenis
2892b725ae77Skettenis status = target_read_memory (addr, buf, sizeof (buf));
2893b725ae77Skettenis if (status != 0)
2894b725ae77Skettenis break;
2895b725ae77Skettenis tag = extract_signed_integer (buf, sizeof (buf));
2896b725ae77Skettenis
2897b725ae77Skettenis if (tag == DT_PLTGOT)
2898b725ae77Skettenis {
2899b725ae77Skettenis CORE_ADDR global_pointer;
2900b725ae77Skettenis
2901b725ae77Skettenis status = target_read_memory (addr + 8, buf, sizeof (buf));
2902b725ae77Skettenis if (status != 0)
2903b725ae77Skettenis break;
2904b725ae77Skettenis global_pointer = extract_unsigned_integer (buf, sizeof (buf));
2905b725ae77Skettenis
2906b725ae77Skettenis /* The payoff... */
2907b725ae77Skettenis return global_pointer;
2908b725ae77Skettenis }
2909b725ae77Skettenis
2910b725ae77Skettenis if (tag == DT_NULL)
2911b725ae77Skettenis break;
2912b725ae77Skettenis
2913b725ae77Skettenis addr += 16;
2914b725ae77Skettenis }
2915b725ae77Skettenis }
2916b725ae77Skettenis }
2917b725ae77Skettenis return 0;
2918b725ae77Skettenis }
2919b725ae77Skettenis
2920b725ae77Skettenis /* Given a function's address, attempt to find (and return) the
2921b725ae77Skettenis corresponding (canonical) function descriptor. Return 0 if
2922b725ae77Skettenis not found. */
2923b725ae77Skettenis static CORE_ADDR
find_extant_func_descr(CORE_ADDR faddr)2924b725ae77Skettenis find_extant_func_descr (CORE_ADDR faddr)
2925b725ae77Skettenis {
2926b725ae77Skettenis struct obj_section *faddr_sect;
2927b725ae77Skettenis
2928b725ae77Skettenis /* Return early if faddr is already a function descriptor. */
2929b725ae77Skettenis faddr_sect = find_pc_section (faddr);
2930b725ae77Skettenis if (faddr_sect && strcmp (faddr_sect->the_bfd_section->name, ".opd") == 0)
2931b725ae77Skettenis return faddr;
2932b725ae77Skettenis
2933b725ae77Skettenis if (faddr_sect != NULL)
2934b725ae77Skettenis {
2935b725ae77Skettenis struct obj_section *osect;
2936b725ae77Skettenis ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
2937b725ae77Skettenis {
2938b725ae77Skettenis if (strcmp (osect->the_bfd_section->name, ".opd") == 0)
2939b725ae77Skettenis break;
2940b725ae77Skettenis }
2941b725ae77Skettenis
2942b725ae77Skettenis if (osect < faddr_sect->objfile->sections_end)
2943b725ae77Skettenis {
2944b725ae77Skettenis CORE_ADDR addr;
2945b725ae77Skettenis
2946b725ae77Skettenis addr = osect->addr;
2947b725ae77Skettenis while (addr < osect->endaddr)
2948b725ae77Skettenis {
2949b725ae77Skettenis int status;
2950b725ae77Skettenis LONGEST faddr2;
2951b725ae77Skettenis char buf[8];
2952b725ae77Skettenis
2953b725ae77Skettenis status = target_read_memory (addr, buf, sizeof (buf));
2954b725ae77Skettenis if (status != 0)
2955b725ae77Skettenis break;
2956b725ae77Skettenis faddr2 = extract_signed_integer (buf, sizeof (buf));
2957b725ae77Skettenis
2958b725ae77Skettenis if (faddr == faddr2)
2959b725ae77Skettenis return addr;
2960b725ae77Skettenis
2961b725ae77Skettenis addr += 16;
2962b725ae77Skettenis }
2963b725ae77Skettenis }
2964b725ae77Skettenis }
2965b725ae77Skettenis return 0;
2966b725ae77Skettenis }
2967b725ae77Skettenis
2968b725ae77Skettenis /* Attempt to find a function descriptor corresponding to the
2969b725ae77Skettenis given address. If none is found, construct one on the
2970b725ae77Skettenis stack using the address at fdaptr. */
2971b725ae77Skettenis
2972b725ae77Skettenis static CORE_ADDR
find_func_descr(CORE_ADDR faddr,CORE_ADDR * fdaptr)2973b725ae77Skettenis find_func_descr (CORE_ADDR faddr, CORE_ADDR *fdaptr)
2974b725ae77Skettenis {
2975b725ae77Skettenis CORE_ADDR fdesc;
2976b725ae77Skettenis
2977b725ae77Skettenis fdesc = find_extant_func_descr (faddr);
2978b725ae77Skettenis
2979b725ae77Skettenis if (fdesc == 0)
2980b725ae77Skettenis {
2981b725ae77Skettenis CORE_ADDR global_pointer;
2982b725ae77Skettenis char buf[16];
2983b725ae77Skettenis
2984b725ae77Skettenis fdesc = *fdaptr;
2985b725ae77Skettenis *fdaptr += 16;
2986b725ae77Skettenis
2987b725ae77Skettenis global_pointer = FIND_GLOBAL_POINTER (faddr);
2988b725ae77Skettenis
2989b725ae77Skettenis if (global_pointer == 0)
2990b725ae77Skettenis global_pointer = read_register (IA64_GR1_REGNUM);
2991b725ae77Skettenis
2992b725ae77Skettenis store_unsigned_integer (buf, 8, faddr);
2993b725ae77Skettenis store_unsigned_integer (buf + 8, 8, global_pointer);
2994b725ae77Skettenis
2995b725ae77Skettenis write_memory (fdesc, buf, 16);
2996b725ae77Skettenis }
2997b725ae77Skettenis
2998b725ae77Skettenis return fdesc;
2999b725ae77Skettenis }
3000b725ae77Skettenis
3001b725ae77Skettenis /* Use the following routine when printing out function pointers
3002b725ae77Skettenis so the user can see the function address rather than just the
3003b725ae77Skettenis function descriptor. */
3004b725ae77Skettenis static CORE_ADDR
ia64_convert_from_func_ptr_addr(struct gdbarch * gdbarch,CORE_ADDR addr,struct target_ops * targ)3005b725ae77Skettenis ia64_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr,
3006b725ae77Skettenis struct target_ops *targ)
3007b725ae77Skettenis {
3008b725ae77Skettenis struct obj_section *s;
3009b725ae77Skettenis
3010b725ae77Skettenis s = find_pc_section (addr);
3011b725ae77Skettenis
3012b725ae77Skettenis /* check if ADDR points to a function descriptor. */
3013b725ae77Skettenis if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
3014b725ae77Skettenis return read_memory_unsigned_integer (addr, 8);
3015b725ae77Skettenis
3016b725ae77Skettenis return addr;
3017b725ae77Skettenis }
3018b725ae77Skettenis
3019b725ae77Skettenis static CORE_ADDR
ia64_frame_align(struct gdbarch * gdbarch,CORE_ADDR sp)3020b725ae77Skettenis ia64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
3021b725ae77Skettenis {
3022b725ae77Skettenis return sp & ~0xfLL;
3023b725ae77Skettenis }
3024b725ae77Skettenis
3025b725ae77Skettenis static CORE_ADDR
ia64_push_dummy_call(struct gdbarch * gdbarch,struct value * function,struct regcache * regcache,CORE_ADDR bp_addr,int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)3026*11efff7fSkettenis ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
3027b725ae77Skettenis struct regcache *regcache, CORE_ADDR bp_addr,
3028b725ae77Skettenis int nargs, struct value **args, CORE_ADDR sp,
3029b725ae77Skettenis int struct_return, CORE_ADDR struct_addr)
3030b725ae77Skettenis {
3031b725ae77Skettenis int argno;
3032b725ae77Skettenis struct value *arg;
3033b725ae77Skettenis struct type *type;
3034b725ae77Skettenis int len, argoffset;
3035b725ae77Skettenis int nslots, rseslots, memslots, slotnum, nfuncargs;
3036b725ae77Skettenis int floatreg;
3037b725ae77Skettenis CORE_ADDR bsp, cfm, pfs, new_bsp, funcdescaddr, pc, global_pointer;
3038*11efff7fSkettenis CORE_ADDR func_addr = find_function_addr (function, NULL);
3039b725ae77Skettenis
3040b725ae77Skettenis nslots = 0;
3041b725ae77Skettenis nfuncargs = 0;
3042b725ae77Skettenis /* Count the number of slots needed for the arguments. */
3043b725ae77Skettenis for (argno = 0; argno < nargs; argno++)
3044b725ae77Skettenis {
3045b725ae77Skettenis arg = args[argno];
3046b725ae77Skettenis type = check_typedef (VALUE_TYPE (arg));
3047b725ae77Skettenis len = TYPE_LENGTH (type);
3048b725ae77Skettenis
3049b725ae77Skettenis if ((nslots & 1) && slot_alignment_is_next_even (type))
3050b725ae77Skettenis nslots++;
3051b725ae77Skettenis
3052b725ae77Skettenis if (TYPE_CODE (type) == TYPE_CODE_FUNC)
3053b725ae77Skettenis nfuncargs++;
3054b725ae77Skettenis
3055b725ae77Skettenis nslots += (len + 7) / 8;
3056b725ae77Skettenis }
3057b725ae77Skettenis
3058b725ae77Skettenis /* Divvy up the slots between the RSE and the memory stack. */
3059b725ae77Skettenis rseslots = (nslots > 8) ? 8 : nslots;
3060b725ae77Skettenis memslots = nslots - rseslots;
3061b725ae77Skettenis
3062b725ae77Skettenis /* Allocate a new RSE frame. */
3063b725ae77Skettenis cfm = read_register (IA64_CFM_REGNUM);
3064b725ae77Skettenis
3065b725ae77Skettenis bsp = read_register (IA64_BSP_REGNUM);
3066b725ae77Skettenis new_bsp = rse_address_add (bsp, rseslots);
3067b725ae77Skettenis write_register (IA64_BSP_REGNUM, new_bsp);
3068b725ae77Skettenis
3069b725ae77Skettenis pfs = read_register (IA64_PFS_REGNUM);
3070b725ae77Skettenis pfs &= 0xc000000000000000LL;
3071b725ae77Skettenis pfs |= (cfm & 0xffffffffffffLL);
3072b725ae77Skettenis write_register (IA64_PFS_REGNUM, pfs);
3073b725ae77Skettenis
3074b725ae77Skettenis cfm &= 0xc000000000000000LL;
3075b725ae77Skettenis cfm |= rseslots;
3076b725ae77Skettenis write_register (IA64_CFM_REGNUM, cfm);
3077b725ae77Skettenis
3078b725ae77Skettenis /* We will attempt to find function descriptors in the .opd segment,
3079b725ae77Skettenis but if we can't we'll construct them ourselves. That being the
3080b725ae77Skettenis case, we'll need to reserve space on the stack for them. */
3081b725ae77Skettenis funcdescaddr = sp - nfuncargs * 16;
3082b725ae77Skettenis funcdescaddr &= ~0xfLL;
3083b725ae77Skettenis
3084b725ae77Skettenis /* Adjust the stack pointer to it's new value. The calling conventions
3085b725ae77Skettenis require us to have 16 bytes of scratch, plus whatever space is
3086b725ae77Skettenis necessary for the memory slots and our function descriptors. */
3087b725ae77Skettenis sp = sp - 16 - (memslots + nfuncargs) * 8;
3088b725ae77Skettenis sp &= ~0xfLL; /* Maintain 16 byte alignment. */
3089b725ae77Skettenis
3090b725ae77Skettenis /* Place the arguments where they belong. The arguments will be
3091b725ae77Skettenis either placed in the RSE backing store or on the memory stack.
3092b725ae77Skettenis In addition, floating point arguments or HFAs are placed in
3093b725ae77Skettenis floating point registers. */
3094b725ae77Skettenis slotnum = 0;
3095b725ae77Skettenis floatreg = IA64_FR8_REGNUM;
3096b725ae77Skettenis for (argno = 0; argno < nargs; argno++)
3097b725ae77Skettenis {
3098b725ae77Skettenis struct type *float_elt_type;
3099b725ae77Skettenis
3100b725ae77Skettenis arg = args[argno];
3101b725ae77Skettenis type = check_typedef (VALUE_TYPE (arg));
3102b725ae77Skettenis len = TYPE_LENGTH (type);
3103b725ae77Skettenis
3104b725ae77Skettenis /* Special handling for function parameters. */
3105b725ae77Skettenis if (len == 8
3106b725ae77Skettenis && TYPE_CODE (type) == TYPE_CODE_PTR
3107b725ae77Skettenis && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)
3108b725ae77Skettenis {
3109b725ae77Skettenis char val_buf[8];
3110b725ae77Skettenis
3111b725ae77Skettenis store_unsigned_integer (val_buf, 8,
3112b725ae77Skettenis find_func_descr (extract_unsigned_integer (VALUE_CONTENTS (arg), 8),
3113b725ae77Skettenis &funcdescaddr));
3114b725ae77Skettenis if (slotnum < rseslots)
3115b725ae77Skettenis write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
3116b725ae77Skettenis else
3117b725ae77Skettenis write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
3118b725ae77Skettenis slotnum++;
3119b725ae77Skettenis continue;
3120b725ae77Skettenis }
3121b725ae77Skettenis
3122b725ae77Skettenis /* Normal slots. */
3123b725ae77Skettenis
3124b725ae77Skettenis /* Skip odd slot if necessary... */
3125b725ae77Skettenis if ((slotnum & 1) && slot_alignment_is_next_even (type))
3126b725ae77Skettenis slotnum++;
3127b725ae77Skettenis
3128b725ae77Skettenis argoffset = 0;
3129b725ae77Skettenis while (len > 0)
3130b725ae77Skettenis {
3131b725ae77Skettenis char val_buf[8];
3132b725ae77Skettenis
3133b725ae77Skettenis memset (val_buf, 0, 8);
3134b725ae77Skettenis memcpy (val_buf, VALUE_CONTENTS (arg) + argoffset, (len > 8) ? 8 : len);
3135b725ae77Skettenis
3136b725ae77Skettenis if (slotnum < rseslots)
3137b725ae77Skettenis write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
3138b725ae77Skettenis else
3139b725ae77Skettenis write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
3140b725ae77Skettenis
3141b725ae77Skettenis argoffset += 8;
3142b725ae77Skettenis len -= 8;
3143b725ae77Skettenis slotnum++;
3144b725ae77Skettenis }
3145b725ae77Skettenis
3146b725ae77Skettenis /* Handle floating point types (including HFAs). */
3147b725ae77Skettenis float_elt_type = is_float_or_hfa_type (type);
3148b725ae77Skettenis if (float_elt_type != NULL)
3149b725ae77Skettenis {
3150b725ae77Skettenis argoffset = 0;
3151b725ae77Skettenis len = TYPE_LENGTH (type);
3152b725ae77Skettenis while (len > 0 && floatreg < IA64_FR16_REGNUM)
3153b725ae77Skettenis {
3154b725ae77Skettenis char to[MAX_REGISTER_SIZE];
3155b725ae77Skettenis convert_typed_floating (VALUE_CONTENTS (arg) + argoffset, float_elt_type,
3156b725ae77Skettenis to, builtin_type_ia64_ext);
3157b725ae77Skettenis regcache_cooked_write (regcache, floatreg, (void *)to);
3158b725ae77Skettenis floatreg++;
3159b725ae77Skettenis argoffset += TYPE_LENGTH (float_elt_type);
3160b725ae77Skettenis len -= TYPE_LENGTH (float_elt_type);
3161b725ae77Skettenis }
3162b725ae77Skettenis }
3163b725ae77Skettenis }
3164b725ae77Skettenis
3165b725ae77Skettenis /* Store the struct return value in r8 if necessary. */
3166b725ae77Skettenis if (struct_return)
3167b725ae77Skettenis {
3168b725ae77Skettenis regcache_cooked_write_unsigned (regcache, IA64_GR8_REGNUM, (ULONGEST)struct_addr);
3169b725ae77Skettenis }
3170b725ae77Skettenis
3171b725ae77Skettenis global_pointer = FIND_GLOBAL_POINTER (func_addr);
3172b725ae77Skettenis
3173b725ae77Skettenis if (global_pointer != 0)
3174b725ae77Skettenis write_register (IA64_GR1_REGNUM, global_pointer);
3175b725ae77Skettenis
3176b725ae77Skettenis write_register (IA64_BR0_REGNUM, bp_addr);
3177b725ae77Skettenis
3178b725ae77Skettenis write_register (sp_regnum, sp);
3179b725ae77Skettenis
3180b725ae77Skettenis return sp;
3181b725ae77Skettenis }
3182b725ae77Skettenis
3183b725ae77Skettenis static struct frame_id
ia64_unwind_dummy_id(struct gdbarch * gdbarch,struct frame_info * next_frame)3184b725ae77Skettenis ia64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
3185b725ae77Skettenis {
3186b725ae77Skettenis char buf[8];
3187b725ae77Skettenis CORE_ADDR sp, bsp;
3188b725ae77Skettenis
3189b725ae77Skettenis frame_unwind_register (next_frame, sp_regnum, buf);
3190b725ae77Skettenis sp = extract_unsigned_integer (buf, 8);
3191b725ae77Skettenis
3192b725ae77Skettenis frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
3193b725ae77Skettenis bsp = extract_unsigned_integer (buf, 8);
3194b725ae77Skettenis
3195b725ae77Skettenis if (gdbarch_debug >= 1)
3196b725ae77Skettenis fprintf_unfiltered (gdb_stdlog,
3197b725ae77Skettenis "dummy frame id: code 0x%s, stack 0x%s, special 0x%s\n",
3198b725ae77Skettenis paddr_nz (frame_pc_unwind (next_frame)),
3199b725ae77Skettenis paddr_nz (sp), paddr_nz (bsp));
3200b725ae77Skettenis
3201b725ae77Skettenis return frame_id_build_special (sp, frame_pc_unwind (next_frame), bsp);
3202b725ae77Skettenis }
3203b725ae77Skettenis
3204b725ae77Skettenis static CORE_ADDR
ia64_unwind_pc(struct gdbarch * gdbarch,struct frame_info * next_frame)3205b725ae77Skettenis ia64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
3206b725ae77Skettenis {
3207b725ae77Skettenis char buf[8];
3208b725ae77Skettenis CORE_ADDR ip, psr, pc;
3209b725ae77Skettenis
3210b725ae77Skettenis frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
3211b725ae77Skettenis ip = extract_unsigned_integer (buf, 8);
3212b725ae77Skettenis frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
3213b725ae77Skettenis psr = extract_unsigned_integer (buf, 8);
3214b725ae77Skettenis
3215b725ae77Skettenis pc = (ip & ~0xf) | ((psr >> 41) & 3);
3216b725ae77Skettenis return pc;
3217b725ae77Skettenis }
3218b725ae77Skettenis
3219b725ae77Skettenis static void
ia64_store_return_value(struct type * type,struct regcache * regcache,const void * valbuf)3220b725ae77Skettenis ia64_store_return_value (struct type *type, struct regcache *regcache, const void *valbuf)
3221b725ae77Skettenis {
3222b725ae77Skettenis if (TYPE_CODE (type) == TYPE_CODE_FLT)
3223b725ae77Skettenis {
3224b725ae77Skettenis char to[MAX_REGISTER_SIZE];
3225b725ae77Skettenis convert_typed_floating (valbuf, type, to, builtin_type_ia64_ext);
3226b725ae77Skettenis regcache_cooked_write (regcache, IA64_FR8_REGNUM, (void *)to);
3227b725ae77Skettenis target_store_registers (IA64_FR8_REGNUM);
3228b725ae77Skettenis }
3229b725ae77Skettenis else
3230b725ae77Skettenis regcache_cooked_write (regcache, IA64_GR8_REGNUM, valbuf);
3231b725ae77Skettenis }
3232b725ae77Skettenis
3233b725ae77Skettenis static void
ia64_remote_translate_xfer_address(struct gdbarch * gdbarch,struct regcache * regcache,CORE_ADDR memaddr,int nr_bytes,CORE_ADDR * targ_addr,int * targ_len)3234b725ae77Skettenis ia64_remote_translate_xfer_address (struct gdbarch *gdbarch,
3235b725ae77Skettenis struct regcache *regcache,
3236b725ae77Skettenis CORE_ADDR memaddr, int nr_bytes,
3237b725ae77Skettenis CORE_ADDR *targ_addr, int *targ_len)
3238b725ae77Skettenis {
3239b725ae77Skettenis *targ_addr = memaddr;
3240b725ae77Skettenis *targ_len = nr_bytes;
3241b725ae77Skettenis }
3242b725ae77Skettenis
3243b725ae77Skettenis static int
ia64_print_insn(bfd_vma memaddr,struct disassemble_info * info)3244b725ae77Skettenis ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
3245b725ae77Skettenis {
3246b725ae77Skettenis info->bytes_per_line = SLOT_MULTIPLIER;
3247b725ae77Skettenis return print_insn_ia64 (memaddr, info);
3248b725ae77Skettenis }
3249b725ae77Skettenis
3250b725ae77Skettenis static struct gdbarch *
ia64_gdbarch_init(struct gdbarch_info info,struct gdbarch_list * arches)3251b725ae77Skettenis ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
3252b725ae77Skettenis {
3253b725ae77Skettenis struct gdbarch *gdbarch;
3254b725ae77Skettenis struct gdbarch_tdep *tdep;
3255b725ae77Skettenis
3256b725ae77Skettenis /* If there is already a candidate, use it. */
3257b725ae77Skettenis arches = gdbarch_list_lookup_by_info (arches, &info);
3258b725ae77Skettenis if (arches != NULL)
3259b725ae77Skettenis return arches->gdbarch;
3260b725ae77Skettenis
3261b725ae77Skettenis tdep = xmalloc (sizeof (struct gdbarch_tdep));
3262b725ae77Skettenis gdbarch = gdbarch_alloc (&info, tdep);
3263b725ae77Skettenis
3264b725ae77Skettenis /* Set the method of obtaining the sigcontext addresses at which
3265b725ae77Skettenis registers are saved. The method of checking to see if
3266b725ae77Skettenis native_find_global_pointer is nonzero to indicate that we're
3267b725ae77Skettenis on AIX is kind of hokey, but I can't think of a better way
3268b725ae77Skettenis to do it. */
3269b725ae77Skettenis if (info.osabi == GDB_OSABI_LINUX)
3270b725ae77Skettenis tdep->sigcontext_register_address = ia64_linux_sigcontext_register_address;
3271b725ae77Skettenis else if (native_find_global_pointer != 0)
3272b725ae77Skettenis tdep->sigcontext_register_address = ia64_aix_sigcontext_register_address;
3273b725ae77Skettenis else
3274b725ae77Skettenis tdep->sigcontext_register_address = 0;
3275b725ae77Skettenis
3276b725ae77Skettenis /* We know that GNU/Linux won't have to resort to the
3277b725ae77Skettenis native_find_global_pointer hackery. But that's the only one we
3278b725ae77Skettenis know about so far, so if native_find_global_pointer is set to
3279b725ae77Skettenis something non-zero, then use it. Otherwise fall back to using
3280b725ae77Skettenis generic_elf_find_global_pointer. This arrangement should (in
3281b725ae77Skettenis theory) allow us to cross debug GNU/Linux binaries from an AIX
3282b725ae77Skettenis machine. */
3283b725ae77Skettenis if (info.osabi == GDB_OSABI_LINUX)
3284b725ae77Skettenis tdep->find_global_pointer = generic_elf_find_global_pointer;
3285b725ae77Skettenis else if (native_find_global_pointer != 0)
3286b725ae77Skettenis tdep->find_global_pointer = native_find_global_pointer;
3287b725ae77Skettenis else
3288b725ae77Skettenis tdep->find_global_pointer = generic_elf_find_global_pointer;
3289b725ae77Skettenis
3290b725ae77Skettenis /* Define the ia64 floating-point format to gdb. */
3291b725ae77Skettenis builtin_type_ia64_ext =
3292b725ae77Skettenis init_type (TYPE_CODE_FLT, 128 / 8,
3293b725ae77Skettenis 0, "builtin_type_ia64_ext", NULL);
3294b725ae77Skettenis TYPE_FLOATFORMAT (builtin_type_ia64_ext) = &floatformat_ia64_ext;
3295b725ae77Skettenis
3296b725ae77Skettenis /* According to the ia64 specs, instructions that store long double
3297b725ae77Skettenis floats in memory use a long-double format different than that
3298b725ae77Skettenis used in the floating registers. The memory format matches the
3299b725ae77Skettenis x86 extended float format which is 80 bits. An OS may choose to
3300b725ae77Skettenis use this format (e.g. GNU/Linux) or choose to use a different
3301b725ae77Skettenis format for storing long doubles (e.g. HPUX). In the latter case,
3302b725ae77Skettenis the setting of the format may be moved/overridden in an
3303b725ae77Skettenis OS-specific tdep file. */
3304b725ae77Skettenis set_gdbarch_long_double_format (gdbarch, &floatformat_i387_ext);
3305b725ae77Skettenis
3306b725ae77Skettenis set_gdbarch_short_bit (gdbarch, 16);
3307b725ae77Skettenis set_gdbarch_int_bit (gdbarch, 32);
3308b725ae77Skettenis set_gdbarch_long_bit (gdbarch, 64);
3309b725ae77Skettenis set_gdbarch_long_long_bit (gdbarch, 64);
3310b725ae77Skettenis set_gdbarch_float_bit (gdbarch, 32);
3311b725ae77Skettenis set_gdbarch_double_bit (gdbarch, 64);
3312b725ae77Skettenis set_gdbarch_long_double_bit (gdbarch, 128);
3313b725ae77Skettenis set_gdbarch_ptr_bit (gdbarch, 64);
3314b725ae77Skettenis
3315b725ae77Skettenis set_gdbarch_num_regs (gdbarch, NUM_IA64_RAW_REGS);
3316b725ae77Skettenis set_gdbarch_num_pseudo_regs (gdbarch, LAST_PSEUDO_REGNUM - FIRST_PSEUDO_REGNUM);
3317b725ae77Skettenis set_gdbarch_sp_regnum (gdbarch, sp_regnum);
3318b725ae77Skettenis set_gdbarch_fp0_regnum (gdbarch, IA64_FR0_REGNUM);
3319b725ae77Skettenis
3320b725ae77Skettenis set_gdbarch_register_name (gdbarch, ia64_register_name);
3321b725ae77Skettenis /* FIXME: Following interface should not be needed, however, without it recurse.exp
3322b725ae77Skettenis gets a number of extra failures. */
3323b725ae77Skettenis set_gdbarch_deprecated_register_size (gdbarch, 8);
3324b725ae77Skettenis set_gdbarch_register_type (gdbarch, ia64_register_type);
3325b725ae77Skettenis
3326b725ae77Skettenis set_gdbarch_pseudo_register_read (gdbarch, ia64_pseudo_register_read);
3327b725ae77Skettenis set_gdbarch_pseudo_register_write (gdbarch, ia64_pseudo_register_write);
3328b725ae77Skettenis set_gdbarch_dwarf2_reg_to_regnum (gdbarch, ia64_dwarf_reg_to_regnum);
3329b725ae77Skettenis set_gdbarch_register_reggroup_p (gdbarch, ia64_register_reggroup_p);
3330b725ae77Skettenis set_gdbarch_convert_register_p (gdbarch, ia64_convert_register_p);
3331b725ae77Skettenis set_gdbarch_register_to_value (gdbarch, ia64_register_to_value);
3332b725ae77Skettenis set_gdbarch_value_to_register (gdbarch, ia64_value_to_register);
3333b725ae77Skettenis
3334b725ae77Skettenis set_gdbarch_skip_prologue (gdbarch, ia64_skip_prologue);
3335b725ae77Skettenis
3336*11efff7fSkettenis set_gdbarch_deprecated_use_struct_convention (gdbarch, ia64_use_struct_convention);
3337b725ae77Skettenis set_gdbarch_extract_return_value (gdbarch, ia64_extract_return_value);
3338b725ae77Skettenis
3339b725ae77Skettenis set_gdbarch_store_return_value (gdbarch, ia64_store_return_value);
3340b725ae77Skettenis set_gdbarch_deprecated_extract_struct_value_address (gdbarch, ia64_extract_struct_value_address);
3341b725ae77Skettenis
3342b725ae77Skettenis set_gdbarch_memory_insert_breakpoint (gdbarch, ia64_memory_insert_breakpoint);
3343b725ae77Skettenis set_gdbarch_memory_remove_breakpoint (gdbarch, ia64_memory_remove_breakpoint);
3344b725ae77Skettenis set_gdbarch_breakpoint_from_pc (gdbarch, ia64_breakpoint_from_pc);
3345b725ae77Skettenis set_gdbarch_read_pc (gdbarch, ia64_read_pc);
3346b725ae77Skettenis if (info.osabi == GDB_OSABI_LINUX)
3347b725ae77Skettenis set_gdbarch_write_pc (gdbarch, ia64_linux_write_pc);
3348b725ae77Skettenis else
3349b725ae77Skettenis set_gdbarch_write_pc (gdbarch, ia64_write_pc);
3350b725ae77Skettenis
3351b725ae77Skettenis /* Settings for calling functions in the inferior. */
3352b725ae77Skettenis set_gdbarch_push_dummy_call (gdbarch, ia64_push_dummy_call);
3353b725ae77Skettenis set_gdbarch_frame_align (gdbarch, ia64_frame_align);
3354b725ae77Skettenis set_gdbarch_unwind_dummy_id (gdbarch, ia64_unwind_dummy_id);
3355b725ae77Skettenis
3356b725ae77Skettenis set_gdbarch_unwind_pc (gdbarch, ia64_unwind_pc);
3357b725ae77Skettenis frame_unwind_append_sniffer (gdbarch, ia64_sigtramp_frame_sniffer);
3358b725ae77Skettenis #ifdef HAVE_LIBUNWIND_IA64_H
3359b725ae77Skettenis frame_unwind_append_sniffer (gdbarch, ia64_libunwind_frame_sniffer);
3360b725ae77Skettenis libunwind_frame_set_descr (gdbarch, &ia64_libunwind_descr);
3361b725ae77Skettenis #endif
3362b725ae77Skettenis frame_unwind_append_sniffer (gdbarch, ia64_frame_sniffer);
3363b725ae77Skettenis frame_base_set_default (gdbarch, &ia64_frame_base);
3364b725ae77Skettenis
3365b725ae77Skettenis /* Settings that should be unnecessary. */
3366b725ae77Skettenis set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
3367b725ae77Skettenis
3368b725ae77Skettenis set_gdbarch_remote_translate_xfer_address (
3369b725ae77Skettenis gdbarch, ia64_remote_translate_xfer_address);
3370b725ae77Skettenis
3371b725ae77Skettenis set_gdbarch_print_insn (gdbarch, ia64_print_insn);
3372b725ae77Skettenis set_gdbarch_convert_from_func_ptr_addr (gdbarch, ia64_convert_from_func_ptr_addr);
3373b725ae77Skettenis
3374b725ae77Skettenis return gdbarch;
3375b725ae77Skettenis }
3376b725ae77Skettenis
3377b725ae77Skettenis extern initialize_file_ftype _initialize_ia64_tdep; /* -Wmissing-prototypes */
3378b725ae77Skettenis
3379b725ae77Skettenis void
_initialize_ia64_tdep(void)3380b725ae77Skettenis _initialize_ia64_tdep (void)
3381b725ae77Skettenis {
3382b725ae77Skettenis register_gdbarch_init (bfd_arch_ia64, ia64_gdbarch_init);
3383b725ae77Skettenis }
3384