1 /* Sequent Symmetry target interface, for GDB when running under Unix.
2 Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* many 387-specific items of use taken from i386-dep.c */
28 #include <sys/param.h>
31 #include <sys/ioctl.h>
36 static long i386_get_frame_setup ();
37 static i386_follow_jump ();
40 #define TERMINAL struct sgttyb
42 /* rounds 'one' up to divide evenly by 'two' */
46 register int one, two;
58 static CORE_ADDR codestream_next_addr;
59 static CORE_ADDR codestream_addr;
60 static unsigned char codestream_buf[sizeof (int)];
61 static int codestream_off;
62 static int codestream_cnt;
64 #define codestream_tell() (codestream_addr + codestream_off)
65 #define codestream_peek() (codestream_cnt == 0 ? \
66 codestream_fill(1): codestream_buf[codestream_off])
67 #define codestream_get() (codestream_cnt-- == 0 ? \
68 codestream_fill(0) : codestream_buf[codestream_off++])
72 codestream_fill (peek_flag)
74 codestream_addr = codestream_next_addr;
75 codestream_next_addr += sizeof (int);
77 codestream_cnt = sizeof (int);
78 read_memory (codestream_addr,
79 (unsigned char *)codestream_buf,
83 return (codestream_peek());
85 return (codestream_get());
89 codestream_seek (place)
91 codestream_next_addr = place & -sizeof (int);
94 while (codestream_tell() != place)
99 codestream_read (buf, count)
105 for (i = 0; i < count; i++)
106 *p++ = codestream_get ();
110 * Following macro translates i386 opcode register numbers to Symmetry
111 * register numbers. This is used by FRAME_FIND_SAVED_REGS.
113 * %eax %ecx %edx %ebx %esp %ebp %esi %edi
114 * i386 0 1 2 3 4 5 6 7
115 * Symmetry 0 2 1 5 14 15 6 7
118 #define I386_REGNO_TO_SYMMETRY(n) \
119 ((n)==0?0 :(n)==1?2 :(n)==2?1 :(n)==3?5 :(n)==4?14 :(n)==5?15 :(n))
121 /* from i386-dep.c */
122 i386_frame_find_saved_regs (fip, fsrp)
123 struct frame_info *fip;
124 struct frame_saved_regs *fsrp;
126 unsigned long locals;
129 CORE_ADDR dummy_bottom;
133 memset (fsrp, 0, sizeof *fsrp);
135 /* if frame is the end of a dummy, compute where the
138 dummy_bottom = fip->frame - 4 - NUM_REGS*4 - CALL_DUMMY_LENGTH;
140 /* check if the PC is in the stack, in a dummy frame */
141 if (dummy_bottom <= fip->pc && fip->pc <= fip->frame)
143 /* all regs were saved by push_call_dummy () */
144 adr = fip->frame - 4;
145 for (i = 0; i < NUM_REGS; i++)
153 locals = i386_get_frame_setup (get_pc_function_start (fip->pc));
157 adr = fip->frame - 4 - locals;
158 for (i = 0; i < 8; i++)
160 op = codestream_get ();
161 if (op < 0x50 || op > 0x57)
163 fsrp->regs[I386_REGNO_TO_SYMMETRY(op - 0x50)] = adr;
168 fsrp->regs[PC_REGNUM] = fip->frame + 4;
169 fsrp->regs[FP_REGNUM] = fip->frame;
173 i386_get_frame_setup (pc)
177 codestream_seek (pc);
181 op = codestream_get ();
183 if (op == 0x58) /* popl %eax */
186 * this function must start with
189 * xchgl %eax, (%esp) 0x87 0x04 0x24
190 * or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00
192 * (the system 5 compiler puts out the second xchg
193 * inst, and the assembler doesn't try to optimize it,
194 * so the 'sib' form gets generated)
196 * this sequence is used to get the address of the return
197 * buffer for a function that returns a structure
200 unsigned char buf[4];
201 static unsigned char proto1[3] = { 0x87,0x04,0x24 };
202 static unsigned char proto2[4] = { 0x87,0x44,0x24,0x00 };
203 pos = codestream_tell ();
204 codestream_read (buf, 4);
205 if (memcmp (buf, proto1, 3) == 0)
207 else if (memcmp (buf, proto2, 4) == 0)
210 codestream_seek (pos);
211 op = codestream_get (); /* update next opcode */
214 if (op == 0x55) /* pushl %esp */
216 if (codestream_get () != 0x8b) /* movl %esp, %ebp (2bytes) */
218 if (codestream_get () != 0xec)
221 * check for stack adjustment
225 * note: you can't subtract a 16 bit immediate
226 * from a 32 bit reg, so we don't have to worry
227 * about a data16 prefix
229 op = codestream_peek ();
230 if (op == 0x83) /* subl with 8 bit immed */
233 if (codestream_get () != 0xec)
235 /* subl with signed byte immediate
236 * (though it wouldn't make sense to be negative)
238 return (codestream_get());
240 else if (op == 0x81) /* subl with 32 bit immed */
243 if (codestream_get () != 0xec)
245 /* subl with 32 bit immediate */
246 codestream_read ((unsigned char *)&locals, 4);
256 /* enter instruction: arg is 16 unsigned immed */
257 unsigned short slocals;
258 codestream_read ((unsigned char *)&slocals, 2);
259 codestream_get (); /* flush final byte of enter instruction */
265 /* next instruction is a jump, move to target */
275 pos = codestream_tell ();
278 if (codestream_peek () == 0x66)
284 switch (codestream_get ())
287 /* relative jump: if data16 == 0, disp32, else disp16 */
290 codestream_read ((unsigned char *)&short_delta, 2);
291 pos += short_delta + 3; /* include size of jmp inst */
295 codestream_read ((unsigned char *)&long_delta, 4);
296 pos += long_delta + 5;
300 /* relative jump, disp8 (ignore data16) */
301 codestream_read ((unsigned char *)&byte_delta, 1);
302 pos += byte_delta + 2;
305 codestream_seek (pos + data16);
308 /* return pc of first real instruction */
309 /* from i386-dep.c */
311 i386_skip_prologue (pc)
316 if (i386_get_frame_setup (pc) < 0)
319 /* found valid frame setup - codestream now points to
320 * start of push instructions for saving registers
323 /* skip over register saves */
324 for (i = 0; i < 8; i++)
326 op = codestream_peek ();
327 /* break if not pushl inst */
328 if (op < 0x50 || op > 0x57)
335 return (codestream_tell ());
339 symmetry_extract_return_value(type, regbuf, valbuf)
348 struct minimal_symbol *msymbol;
351 if (TYPE_CODE_FLT == TYPE_CODE(type)) {
352 msymbol = lookup_minimal_symbol ("1167_flt", (struct objfile *) NULL);
353 if (msymbol != NULL) {
354 /* found "1167_flt" means 1167, %fp2-%fp3 */
355 /* float & double; 19= %fp2, 20= %fp3 */
356 /* no single precision on 1167 */
357 xd.l[1] = *((int *)®buf[REGISTER_BYTE(19)]);
358 xd.l[0] = *((int *)®buf[REGISTER_BYTE(20)]);
359 switch (TYPE_LENGTH(type)) {
361 /* FIXME: broken for cross-debugging. */
363 memcpy (valbuf, &f, TYPE_LENGTH(type));
366 /* FIXME: broken for cross-debugging. */
367 memcpy (valbuf, &xd.d, TYPE_LENGTH(type));
370 error("Unknown floating point size");
374 /* 387 %st(0), gcc uses this */
375 i387_to_double(((int *)®buf[REGISTER_BYTE(3)]),
377 switch (TYPE_LENGTH(type)) {
380 /* FIXME: broken for cross-debugging. */
381 memcpy (valbuf, &f, 4);
384 /* FIXME: broken for cross-debugging. */
385 memcpy (valbuf, &xd.d, 8);
388 error("Unknown floating point size");
393 memcpy (valbuf, regbuf, TYPE_LENGTH (type));
397 #ifdef _SEQUENT_ /* ptx, not dynix */
399 * Convert compiler register number to gdb internal
400 * register number. The PTX C compiler only really
401 * puts things in %edi, %esi and %ebx, but it can't hurt
402 * to be complete here.
405 ptx_coff_regno_to_gdb(regno)
408 return I386_REGNO_TO_SYMMETRY(regno);
411 /* For ptx, the value in blockend will be meaningless. This function
412 merely returns the proper offset given the register number. This
413 is much easier, because under ptx, the upage is set up with the
414 user struct on "top", and the registers "beneath" it (and thus defines
415 TRAD_CORE_USER_OFFSET in bfd). */
417 /* The following table is for ptx 1.3. In theory it should not change with
418 the OS version, but if it does we should (if possible) figure out a way
419 to accept both the old and the new formats. */
421 static unsigned int reg_offsets[NUM_REGS] = {
423 * u.u_ar0 = 0xfffff8d0
424 * VA_UBLOCK = 0xffffe000
425 * VA_UAREA = 0xfffff8e8
426 * struct user at ublock offset 0x18e8
427 * registers at ublock offset 0x18d0
481 register_addr (regno, blockend)
484 if ((regno < 0) || (regno >= NUM_REGS)) {
485 error("Invalid register number %d.", regno);
487 return reg_offsets[regno];
489 #endif /* _SEQUENT_ */