]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/vax-tdep.c
* vaxbsd-nat.c: New file.
[thirdparty/binutils-gdb.git] / gdb / vax-tdep.c
CommitLineData
c906108c 1/* Print VAX instructions for GDB, the GNU debugger.
464e0365
AC
2
3 Copyright 1986, 1989, 1991, 1992, 1995, 1996, 1998, 1999, 2000,
4 2002, 2003, 2004 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23#include "defs.h"
24#include "symtab.h"
25#include "opcode/vax.h"
c11c3a98 26#include "gdbcore.h"
f267bd6a 27#include "inferior.h"
a33f7558 28#include "regcache.h"
c11c3a98
AC
29#include "frame.h"
30#include "value.h"
f267bd6a 31#include "arch-utils.h"
9bbe19fb 32#include "gdb_string.h"
4be87837 33#include "osabi.h"
a89aa300 34#include "dis-asm.h"
f267bd6a
JT
35
36#include "vax-tdep.h"
37
f267bd6a 38static gdbarch_skip_prologue_ftype vax_skip_prologue;
f267bd6a 39static gdbarch_frame_num_args_ftype vax_frame_num_args;
618ce49f 40static gdbarch_deprecated_frame_chain_ftype vax_frame_chain;
f267bd6a 41
26e9b323 42static gdbarch_deprecated_extract_return_value_ftype vax_extract_return_value;
f267bd6a 43
f3824013 44static gdbarch_deprecated_push_dummy_frame_ftype vax_push_dummy_frame;
c906108c 45\f
5e6b39ff
MK
46
47/* Return the name of register REGNUM. */
48
fa88f677 49static const char *
5e6b39ff 50vax_register_name (int regnum)
51eb8b08
JT
51{
52 static char *register_names[] =
53 {
5e6b39ff
MK
54 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
55 "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc",
51eb8b08
JT
56 "ps",
57 };
58
5e6b39ff
MK
59 if (regnum >= 0 && regnum < ARRAY_SIZE (register_names))
60 return register_names[regnum];
51eb8b08 61
5e6b39ff 62 return NULL;
51eb8b08
JT
63}
64
5e6b39ff
MK
65/* Return the GDB type object for the "standard" data type of data in
66 register REGNUM. */
51eb8b08 67
f267bd6a 68static struct type *
5e6b39ff 69vax_register_type (struct gdbarch *gdbarch, int regnum)
51eb8b08 70{
5e6b39ff 71 return builtin_type_int;
51eb8b08
JT
72}
73\f
f267bd6a 74static void
ab62c900
JT
75vax_frame_init_saved_regs (struct frame_info *frame)
76{
77 int regnum, regmask;
78 CORE_ADDR next_addr;
79
1b1d3794 80 if (deprecated_get_frame_saved_regs (frame))
ab62c900
JT
81 return;
82
83 frame_saved_regs_zalloc (frame);
84
1e2330ba 85 regmask = read_memory_integer (get_frame_base (frame) + 4, 4) >> 16;
ab62c900 86
1e2330ba 87 next_addr = get_frame_base (frame) + 16;
ab62c900
JT
88
89 /* regmask's low bit is for register 0, which is the first one
90 what would be pushed. */
1d049c5e 91 for (regnum = 0; regnum < VAX_AP_REGNUM; regnum++)
ab62c900
JT
92 {
93 if (regmask & (1 << regnum))
1b1d3794 94 deprecated_get_frame_saved_regs (frame)[regnum] = next_addr += 4;
ab62c900
JT
95 }
96
1b1d3794 97 deprecated_get_frame_saved_regs (frame)[SP_REGNUM] = next_addr + 4;
0ba6dca9 98 if (regmask & (1 << DEPRECATED_FP_REGNUM))
1b1d3794 99 deprecated_get_frame_saved_regs (frame)[SP_REGNUM] +=
ab62c900
JT
100 4 + (4 * read_memory_integer (next_addr + 4, 4));
101
1b1d3794
AC
102 deprecated_get_frame_saved_regs (frame)[PC_REGNUM] = get_frame_base (frame) + 16;
103 deprecated_get_frame_saved_regs (frame)[DEPRECATED_FP_REGNUM] = get_frame_base (frame) + 12;
104 deprecated_get_frame_saved_regs (frame)[VAX_AP_REGNUM] = get_frame_base (frame) + 8;
105 deprecated_get_frame_saved_regs (frame)[PS_REGNUM] = get_frame_base (frame) + 4;
ab62c900 106}
5516aa92 107
f407986f
AC
108/* Get saved user PC for sigtramp from sigcontext for BSD style sigtramp. */
109
110static CORE_ADDR
111vax_sigtramp_saved_pc (struct frame_info *frame)
112{
113 CORE_ADDR sigcontext_addr;
114 char *buf;
115 int ptrbytes = TYPE_LENGTH (builtin_type_void_func_ptr);
116 int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
117
118 buf = alloca (ptrbytes);
119 /* Get sigcontext address, it is the third parameter on the stack. */
11c02a10 120 if (get_next_frame (frame))
f407986f 121 sigcontext_addr = read_memory_typed_address
42efa47a 122 (DEPRECATED_FRAME_ARGS_ADDRESS (get_next_frame (frame))
11c02a10 123 + FRAME_ARGS_SKIP + sigcontext_offs,
f407986f
AC
124 builtin_type_void_data_ptr);
125 else
126 sigcontext_addr = read_memory_typed_address
127 (read_register (SP_REGNUM) + sigcontext_offs, builtin_type_void_data_ptr);
128
5929a910
AC
129 /* Offset to saved PC in sigcontext, from <sys/signal.h>. Don't
130 cause a memory_error when accessing sigcontext in case the stack
f407986f 131 layout has changed or the stack is corrupt. */
5929a910 132 target_read_memory (sigcontext_addr + 12, buf, ptrbytes);
f407986f
AC
133 return extract_typed_address (buf, builtin_type_void_func_ptr);
134}
135
f267bd6a 136static CORE_ADDR
5516aa92
JT
137vax_frame_saved_pc (struct frame_info *frame)
138{
5a203e44 139 if ((get_frame_type (frame) == SIGTRAMP_FRAME))
f407986f 140 return (vax_sigtramp_saved_pc (frame)); /* XXXJRT */
5516aa92 141
1e2330ba 142 return (read_memory_integer (get_frame_base (frame) + 16, 4));
5516aa92
JT
143}
144
f267bd6a 145static CORE_ADDR
5516aa92
JT
146vax_frame_args_address (struct frame_info *frame)
147{
25e3a86b
AC
148 /* In most of GDB, getting the args address is too important to just
149 say "I don't know". This is sometimes wrong for functions that
150 aren't on top of the stack, but c'est la vie. */
11c02a10
AC
151 if (get_next_frame (frame))
152 return (read_memory_integer (get_frame_base (get_next_frame (frame)) + 8, 4));
25e3a86b
AC
153 /* Cannot find the AP register value directly from the FP value.
154 Must find it saved in the frame called by this one, or in the AP
155 register for the innermost frame. However, there is no way to
156 tell the difference between the innermost frame and a frame for
157 which we just don't know the frame that it called (e.g. "info
158 frame 0x7ffec789"). For the sake of argument, suppose that the
159 stack is somewhat trashed (which is one reason that "info frame"
160 exists). So, return 0 (indicating we don't know the address of
161 the arglist) if we don't know what frame this frame calls. */
162 return 0;
5516aa92
JT
163}
164
f267bd6a 165static int
5516aa92
JT
166vax_frame_num_args (struct frame_info *fi)
167{
42efa47a 168 return (0xff & read_memory_integer (DEPRECATED_FRAME_ARGS_ADDRESS (fi), 1));
5516aa92 169}
52efde73 170
f267bd6a 171static CORE_ADDR
52efde73
JT
172vax_frame_chain (struct frame_info *frame)
173{
174 /* In the case of the VAX, the frame's nominal address is the FP value,
175 and 12 bytes later comes the saved previous FP value as a 4-byte word. */
1e2330ba 176 return (read_memory_integer (get_frame_base (frame) + 12, 4));
52efde73
JT
177}
178\f
f267bd6a 179static void
52efde73
JT
180vax_push_dummy_frame (void)
181{
182 CORE_ADDR sp = read_register (SP_REGNUM);
183 int regnum;
184
185 sp = push_word (sp, 0); /* arglist */
186 for (regnum = 11; regnum >= 0; regnum--)
187 sp = push_word (sp, read_register (regnum));
188 sp = push_word (sp, read_register (PC_REGNUM));
0ba6dca9 189 sp = push_word (sp, read_register (DEPRECATED_FP_REGNUM));
1d049c5e 190 sp = push_word (sp, read_register (VAX_AP_REGNUM));
52efde73
JT
191 sp = push_word (sp, (read_register (PS_REGNUM) & 0xffef) + 0x2fff0000);
192 sp = push_word (sp, 0);
193 write_register (SP_REGNUM, sp);
0ba6dca9 194 write_register (DEPRECATED_FP_REGNUM, sp);
1d049c5e 195 write_register (VAX_AP_REGNUM, sp + (17 * 4));
52efde73
JT
196}
197
f267bd6a 198static void
52efde73
JT
199vax_pop_frame (void)
200{
0ba6dca9 201 CORE_ADDR fp = read_register (DEPRECATED_FP_REGNUM);
52efde73
JT
202 int regnum;
203 int regmask = read_memory_integer (fp + 4, 4);
204
205 write_register (PS_REGNUM,
206 (regmask & 0xffff)
207 | (read_register (PS_REGNUM) & 0xffff0000));
208 write_register (PC_REGNUM, read_memory_integer (fp + 16, 4));
0ba6dca9 209 write_register (DEPRECATED_FP_REGNUM, read_memory_integer (fp + 12, 4));
1d049c5e 210 write_register (VAX_AP_REGNUM, read_memory_integer (fp + 8, 4));
52efde73
JT
211 fp += 16;
212 for (regnum = 0; regnum < 12; regnum++)
213 if (regmask & (0x10000 << regnum))
214 write_register (regnum, read_memory_integer (fp += 4, 4));
215 fp = fp + 4 + ((regmask >> 30) & 3);
216 if (regmask & 0x20000000)
217 {
218 regnum = read_memory_integer (fp, 4);
219 fp += (regnum + 1) * 4;
220 }
221 write_register (SP_REGNUM, fp);
222 flush_cached_frames ();
223}
a33f7558
JT
224
225/* The VAX call dummy sequence:
226
227 calls #69, @#32323232
228 bpt
229
230 It is 8 bytes long. The address and argc are patched by
231 vax_fix_call_dummy(). */
f267bd6a
JT
232static LONGEST vax_call_dummy_words[] = { 0x329f69fb, 0x03323232 };
233static int sizeof_vax_call_dummy_words = sizeof(vax_call_dummy_words);
a33f7558 234
f267bd6a 235static void
a33f7558
JT
236vax_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
237 struct value **args, struct type *type, int gcc_p)
238{
239 dummy[1] = nargs;
240 store_unsigned_integer (dummy + 3, 4, fun);
241}
ab62c900 242\f
f267bd6a 243static void
ea74468c
JT
244vax_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
245{
246 write_register (1, addr);
247}
248
f267bd6a 249static void
ea74468c
JT
250vax_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
251{
62700349 252 memcpy (valbuf, regbuf + DEPRECATED_REGISTER_BYTE (0), TYPE_LENGTH (valtype));
ea74468c
JT
253}
254
f267bd6a 255static void
ea74468c
JT
256vax_store_return_value (struct type *valtype, char *valbuf)
257{
73937e03 258 deprecated_write_register_bytes (0, valbuf, TYPE_LENGTH (valtype));
ea74468c 259}
ea74468c 260\f
5e6b39ff
MK
261
262/* Use the program counter to determine the contents and size of a
263 breakpoint instruction. Return a pointer to a string of bytes that
264 encode a breakpoint instruction, store the length of the string in
265 *LEN and optionally adjust *PC to point to the correct memory
266 location for inserting the breakpoint. */
267
1d049c5e 268static const unsigned char *
5e6b39ff 269vax_breakpoint_from_pc (CORE_ADDR *pc, int *len)
1d049c5e 270{
5e6b39ff 271 static unsigned char break_insn[] = { 3 };
1d049c5e 272
5e6b39ff
MK
273 *len = sizeof (break_insn);
274 return break_insn;
1d049c5e
JT
275}
276\f
b83266a0
SS
277/* Advance PC across any function entry prologue instructions
278 to reach some "real" code. */
279
f267bd6a 280static CORE_ADDR
fba45db2 281vax_skip_prologue (CORE_ADDR pc)
b83266a0 282{
52f0bd74 283 int op = (unsigned char) read_memory_integer (pc, 1);
b83266a0 284 if (op == 0x11)
c5aa993b 285 pc += 2; /* skip brb */
b83266a0 286 if (op == 0x31)
c5aa993b 287 pc += 3; /* skip brw */
b83266a0 288 if (op == 0xC2
c5aa993b
JM
289 && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E)
290 pc += 3; /* skip subl2 */
b83266a0 291 if (op == 0x9E
c5aa993b
JM
292 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE
293 && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E)
294 pc += 4; /* skip movab */
b83266a0 295 if (op == 0x9E
c5aa993b
JM
296 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE
297 && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E)
298 pc += 5; /* skip movab */
b83266a0 299 if (op == 0x9E
c5aa993b
JM
300 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE
301 && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E)
302 pc += 7; /* skip movab */
b83266a0
SS
303 return pc;
304}
305
f267bd6a 306static CORE_ADDR
a33f7558
JT
307vax_saved_pc_after_call (struct frame_info *frame)
308{
8bedc050 309 return (DEPRECATED_FRAME_SAVED_PC(frame));
a33f7558
JT
310}
311\f
f267bd6a
JT
312/* Initialize the current architecture based on INFO. If possible, re-use an
313 architecture from ARCHES, which is a list of architectures already created
314 during this debugging session.
315
316 Called e.g. at program startup, when reading a core file, and when reading
317 a binary file. */
318
319static struct gdbarch *
320vax_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
321{
322 struct gdbarch *gdbarch;
323
4be87837
DJ
324 /* If there is already a candidate, use it. */
325 arches = gdbarch_list_lookup_by_info (arches, &info);
326 if (arches != NULL)
327 return arches->gdbarch;
f267bd6a 328
4be87837 329 gdbarch = gdbarch_alloc (&info, NULL);
4791e091 330
a5afb99f
AC
331 /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
332 ready to unwind the PC first (see frame.c:get_prev_frame()). */
0968aa8c 333 set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
a5afb99f 334
f267bd6a
JT
335 /* Register info */
336 set_gdbarch_num_regs (gdbarch, VAX_NUM_REGS);
5e6b39ff
MK
337 set_gdbarch_register_name (gdbarch, vax_register_name);
338 set_gdbarch_register_type (gdbarch, vax_register_type);
f267bd6a 339 set_gdbarch_sp_regnum (gdbarch, VAX_SP_REGNUM);
0ba6dca9 340 set_gdbarch_deprecated_fp_regnum (gdbarch, VAX_FP_REGNUM);
f267bd6a
JT
341 set_gdbarch_pc_regnum (gdbarch, VAX_PC_REGNUM);
342 set_gdbarch_ps_regnum (gdbarch, VAX_PS_REGNUM);
343
f267bd6a
JT
344 /* Frame and stack info */
345 set_gdbarch_skip_prologue (gdbarch, vax_skip_prologue);
6913c89a 346 set_gdbarch_deprecated_saved_pc_after_call (gdbarch, vax_saved_pc_after_call);
f267bd6a
JT
347
348 set_gdbarch_frame_num_args (gdbarch, vax_frame_num_args);
f267bd6a 349
618ce49f 350 set_gdbarch_deprecated_frame_chain (gdbarch, vax_frame_chain);
8bedc050 351 set_gdbarch_deprecated_frame_saved_pc (gdbarch, vax_frame_saved_pc);
f267bd6a 352
42efa47a 353 set_gdbarch_deprecated_frame_args_address (gdbarch, vax_frame_args_address);
f267bd6a 354
f30ee0bc 355 set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, vax_frame_init_saved_regs);
f267bd6a
JT
356
357 set_gdbarch_frame_args_skip (gdbarch, 4);
358
5e6b39ff 359 /* Stack grows downward. */
f267bd6a
JT
360 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
361
362 /* Return value info */
4183d812 363 set_gdbarch_deprecated_store_struct_return (gdbarch, vax_store_struct_return);
26e9b323 364 set_gdbarch_deprecated_extract_return_value (gdbarch, vax_extract_return_value);
ebba8386 365 set_gdbarch_deprecated_store_return_value (gdbarch, vax_store_return_value);
f267bd6a
JT
366
367 /* Call dummy info */
f3824013 368 set_gdbarch_deprecated_push_dummy_frame (gdbarch, vax_push_dummy_frame);
749b82f6 369 set_gdbarch_deprecated_pop_frame (gdbarch, vax_pop_frame);
f267bd6a 370 set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
b1e29e33
AC
371 set_gdbarch_deprecated_call_dummy_words (gdbarch, vax_call_dummy_words);
372 set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, sizeof_vax_call_dummy_words);
373 set_gdbarch_deprecated_fix_call_dummy (gdbarch, vax_fix_call_dummy);
374 set_gdbarch_deprecated_call_dummy_breakpoint_offset (gdbarch, 7);
07555a72 375 set_gdbarch_deprecated_use_generic_dummy_frames (gdbarch, 0);
ae45cd16 376 set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_on_stack);
f267bd6a
JT
377
378 /* Breakpoint info */
1d049c5e 379 set_gdbarch_breakpoint_from_pc (gdbarch, vax_breakpoint_from_pc);
f267bd6a
JT
380
381 /* Misc info */
382 set_gdbarch_function_start_offset (gdbarch, 2);
1d049c5e 383 set_gdbarch_believe_pcc_promotion (gdbarch, 1);
f267bd6a 384
6c0e89ed 385 /* Should be using push_dummy_call. */
b46e02f6 386 set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
6c0e89ed 387
4791e091 388 /* Hook in ABI-specific overrides, if they have been registered. */
4be87837 389 gdbarch_init_osabi (info, gdbarch);
4791e091 390
ee2842e2
ILT
391 set_gdbarch_print_insn (gdbarch, print_insn_vax);
392
f267bd6a
JT
393 return (gdbarch);
394}
c906108c 395
a78f21af
AC
396extern initialize_file_ftype _initialize_vax_tdep; /* -Wmissing-prototypes */
397
c906108c 398void
fba45db2 399_initialize_vax_tdep (void)
c906108c 400{
4be87837 401 gdbarch_register (bfd_arch_vax, vax_gdbarch_init, NULL);
c906108c 402}