xref: /openbsd-src/gnu/usr.bin/binutils/gdb/m68k-tdep.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /* Target dependent code for the Motorola 68000 series.
2    Copyright (C) 1990, 1992 Free Software Foundation, Inc.
3 
4 This file is part of GDB.
5 
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.
10 
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.
15 
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19 
20 #include "defs.h"
21 #include "frame.h"
22 #include "gdbcore.h"
23 #include "symtab.h"
24 
25 
26 /* Push an empty stack frame, to record the current PC, etc.  */
27 
28 void
29 m68k_push_dummy_frame ()
30 {
31   register CORE_ADDR sp = read_register (SP_REGNUM);
32   register int regnum;
33   char raw_buffer[12];
34 
35   sp = push_word (sp, read_register (PC_REGNUM));
36   sp = push_word (sp, read_register (FP_REGNUM));
37   write_register (FP_REGNUM, sp);
38 
39   /* Always save the floating-point registers, whether they exist on
40      this target or not.  */
41   for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
42     {
43       read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
44       sp = push_bytes (sp, raw_buffer, 12);
45     }
46 
47   for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
48     {
49       sp = push_word (sp, read_register (regnum));
50     }
51   sp = push_word (sp, read_register (PS_REGNUM));
52   write_register (SP_REGNUM, sp);
53 }
54 
55 /* Discard from the stack the innermost frame,
56    restoring all saved registers.  */
57 
58 void
59 m68k_pop_frame ()
60 {
61   register struct frame_info *frame = get_current_frame ();
62   register CORE_ADDR fp;
63   register int regnum;
64   struct frame_saved_regs fsr;
65   struct frame_info *fi;
66   char raw_buffer[12];
67 
68   fp = FRAME_FP (frame);
69   get_frame_saved_regs (frame, &fsr);
70   for (regnum = FP0_REGNUM + 7 ; regnum >= FP0_REGNUM ; regnum--)
71     {
72       if (fsr.regs[regnum])
73 	{
74 	  read_memory (fsr.regs[regnum], raw_buffer, 12);
75 	  write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
76 	}
77     }
78   for (regnum = FP_REGNUM - 1 ; regnum >= 0 ; regnum--)
79     {
80       if (fsr.regs[regnum])
81 	{
82 	  write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
83 	}
84     }
85   if (fsr.regs[PS_REGNUM])
86     {
87       write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4));
88     }
89   write_register (FP_REGNUM, read_memory_integer (fp, 4));
90   write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
91   write_register (SP_REGNUM, fp + 8);
92   flush_cached_frames ();
93 }
94 
95 
96 /* Given an ip value corresponding to the start of a function,
97    return the ip of the first instruction after the function
98    prologue.  This is the generic m68k support.  Machines which
99    require something different can override the SKIP_PROLOGUE
100    macro to point elsewhere.
101 
102    Some instructions which typically may appear in a function
103    prologue include:
104 
105    A link instruction, word form:
106 
107 	link.w	%a6,&0			4e56  XXXX
108 
109    A link instruction, long form:
110 
111 	link.l  %fp,&F%1		480e  XXXX  XXXX
112 
113    A movm instruction to preserve integer regs:
114 
115 	movm.l  &M%1,(4,%sp)		48ef  XXXX  XXXX
116 
117    A fmovm instruction to preserve float regs:
118 
119 	fmovm   &FPM%1,(FPO%1,%sp)	f237  XXXX  XXXX  XXXX  XXXX
120 
121    Some profiling setup code (FIXME, not recognized yet):
122 
123 	lea.l   (.L3,%pc),%a1		43fb  XXXX  XXXX  XXXX
124 	bsr     _mcount			61ff  XXXX  XXXX
125 
126   */
127 
128 #define P_LINK_L	0x480e
129 #define P_LINK_W	0x4e56
130 #define P_MOV_L		0x207c
131 #define P_JSR		0x4eb9
132 #define P_BSR		0x61ff
133 #define P_LEA_L		0x43fb
134 #define P_MOVM_L	0x48ef
135 #define P_FMOVM		0xf237
136 #define P_TRAP		0x4e40
137 
138 CORE_ADDR
139 m68k_skip_prologue (ip)
140 CORE_ADDR ip;
141 {
142   register CORE_ADDR limit;
143   struct symtab_and_line sal;
144   register int op;
145 
146   /* Find out if there is a known limit for the extent of the prologue.
147      If so, ensure we don't go past it.  If not, assume "infinity". */
148 
149   sal = find_pc_line (ip, 0);
150   limit = (sal.end) ? sal.end : (CORE_ADDR) ~0;
151 
152   while (ip < limit)
153     {
154       op = read_memory_integer (ip, 2);
155       op &= 0xFFFF;
156 
157       if (op == P_LINK_W)
158 	{
159 	  ip += 4;	/* Skip link.w */
160 	}
161       else if (op == 0x4856)
162 	ip += 2; /* Skip pea %fp */
163       else if (op == 0x2c4f)
164 	ip += 2; /* Skip move.l %sp, %fp */
165       else if (op == P_LINK_L)
166 	{
167 	  ip += 6;	/* Skip link.l */
168 	}
169       else if (op == P_MOVM_L)
170 	{
171 	  ip += 6;	/* Skip movm.l */
172 	}
173       else if (op == P_FMOVM)
174 	{
175 	  ip += 10;	/* Skip fmovm */
176 	}
177       else
178 	{
179 	  break;	/* Found unknown code, bail out. */
180 	}
181     }
182   return (ip);
183 }
184 
185 void
186 m68k_find_saved_regs (frame_info, saved_regs)
187      struct frame_info *frame_info;
188      struct frame_saved_regs *saved_regs;
189 {
190   register int regnum;
191   register int regmask;
192   register CORE_ADDR next_addr;
193   register CORE_ADDR pc;
194 
195   /* First possible address for a pc in a call dummy for this frame.  */
196   CORE_ADDR possible_call_dummy_start =
197     (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 4 - 8*12;
198 
199   int nextinsn;
200   memset (saved_regs, 0, sizeof (*saved_regs));
201   if ((frame_info)->pc >= possible_call_dummy_start
202       && (frame_info)->pc <= (frame_info)->frame)
203     {
204 
205       /* It is a call dummy.  We could just stop now, since we know
206 	 what the call dummy saves and where.  But this code proceeds
207 	 to parse the "prologue" which is part of the call dummy.
208 	 This is needlessly complex and confusing.  FIXME.  */
209 
210       next_addr = (frame_info)->frame;
211       pc = possible_call_dummy_start;
212     }
213   else
214     {
215       pc = get_pc_function_start ((frame_info)->pc);
216 
217       if (0x4856 == read_memory_integer (pc, 2)
218 	  && 0x2c4f == read_memory_integer (pc + 2, 2))
219 	{
220 	  /*
221 	    pea %fp
222             move.l %sp, %fp */
223 
224 	  pc += 4;
225 	  next_addr = frame_info->frame;
226 	}
227       else if (044016 == read_memory_integer (pc, 2))
228 	/* link.l %fp */
229 	/* Find the address above the saved
230 	   regs using the amount of storage from the link instruction.  */
231 	next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4;
232       else if (047126 == read_memory_integer (pc, 2))
233 	/* link.w %fp */
234 	/* Find the address above the saved
235 	   regs using the amount of storage from the link instruction.  */
236 	next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2;
237       else goto lose;
238 
239       /* If have an addal #-n, sp next, adjust next_addr.  */
240       if ((0177777 & read_memory_integer (pc, 2)) == 0157774)
241 	next_addr += read_memory_integer (pc += 2, 4), pc += 4;
242     }
243   regmask = read_memory_integer (pc + 2, 2);
244 
245   /* Here can come an fmovem.  Check for it.  */
246   nextinsn = 0xffff & read_memory_integer (pc, 2);
247   if (0xf227 == nextinsn
248       && (regmask & 0xff00) == 0xe000)
249     { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */
250       for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1)
251 	if (regmask & 1)
252           saved_regs->regs[regnum] = (next_addr -= 12);
253       regmask = read_memory_integer (pc + 2, 2); }
254 
255   /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */
256   if (0044327 == read_memory_integer (pc, 2))
257     { pc += 4; /* Regmask's low bit is for register 0, the first written */
258       for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
259 	if (regmask & 1)
260           saved_regs->regs[regnum] = (next_addr += 4) - 4; }
261   else if (0044347 == read_memory_integer (pc, 2))
262     {
263       pc += 4; /* Regmask's low bit is for register 15, the first pushed */
264       for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1)
265 	if (regmask & 1)
266           saved_regs->regs[regnum] = (next_addr -= 4);
267     }
268   else if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))
269     {
270       regnum = 0xf & read_memory_integer (pc, 2); pc += 2;
271       saved_regs->regs[regnum] = (next_addr -= 4);
272       /* gcc, at least, may use a pair of movel instructions when saving
273 	 exactly 2 registers.  */
274       if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))
275 	{
276 	  regnum = 0xf & read_memory_integer (pc, 2);
277 	  pc += 2;
278 	  saved_regs->regs[regnum] = (next_addr -= 4);
279 	}
280     }
281 
282   /* fmovemx to index of sp may follow.  */
283   regmask = read_memory_integer (pc + 2, 2);
284   nextinsn = 0xffff & read_memory_integer (pc, 2);
285   if (0xf236 == nextinsn
286       && (regmask & 0xff00) == 0xf000)
287     { pc += 10; /* Regmask's low bit is for register fp0, the first written */
288       for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1)
289 	if (regmask & 1)
290           saved_regs->regs[regnum] = (next_addr += 12) - 12;
291       regmask = read_memory_integer (pc + 2, 2); }
292 
293   /* clrw -(sp); movw ccr,-(sp) may follow.  */
294   if (0x426742e7 == read_memory_integer (pc, 4))
295     saved_regs->regs[PS_REGNUM] = (next_addr -= 4);
296   lose: ;
297   saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8;
298   saved_regs->regs[FP_REGNUM] = (frame_info)->frame;
299   saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4;
300 #ifdef SIG_SP_FP_OFFSET
301   /* Adjust saved SP_REGNUM for fake _sigtramp frames.  */
302   if (frame_info->signal_handler_caller && frame_info->next)
303     saved_regs->regs[SP_REGNUM] = frame_info->next->frame + SIG_SP_FP_OFFSET;
304 #endif
305 }
306 
307 
308 #ifdef USE_PROC_FS	/* Target dependent support for /proc */
309 
310 #include <sys/procfs.h>
311 
312 /*  The /proc interface divides the target machine's register set up into
313     two different sets, the general register set (gregset) and the floating
314     point register set (fpregset).  For each set, there is an ioctl to get
315     the current register set and another ioctl to set the current values.
316 
317     The actual structure passed through the ioctl interface is, of course,
318     naturally machine dependent, and is different for each set of registers.
319     For the m68k for example, the general register set is typically defined
320     by:
321 
322 	typedef int gregset_t[18];
323 
324 	#define	R_D0	0
325 	...
326 	#define	R_PS	17
327 
328     and the floating point set by:
329 
330     	typedef	struct fpregset {
331 	  int	f_pcr;
332 	  int	f_psr;
333 	  int	f_fpiaddr;
334 	  int	f_fpregs[8][3];		(8 regs, 96 bits each)
335 	} fpregset_t;
336 
337     These routines provide the packing and unpacking of gregset_t and
338     fpregset_t formatted data.
339 
340  */
341 
342 /* Atari SVR4 has R_SR but not R_PS */
343 
344 #if !defined (R_PS) && defined (R_SR)
345 #define R_PS R_SR
346 #endif
347 
348 /*  Given a pointer to a general register set in /proc format (gregset_t *),
349     unpack the register contents and supply them as gdb's idea of the current
350     register values. */
351 
352 void
353 supply_gregset (gregsetp)
354 gregset_t *gregsetp;
355 {
356   register int regi;
357   register greg_t *regp = (greg_t *) gregsetp;
358 
359   for (regi = 0 ; regi < R_PC ; regi++)
360     {
361       supply_register (regi, (char *) (regp + regi));
362     }
363   supply_register (PS_REGNUM, (char *) (regp + R_PS));
364   supply_register (PC_REGNUM, (char *) (regp + R_PC));
365 }
366 
367 void
368 fill_gregset (gregsetp, regno)
369 gregset_t *gregsetp;
370 int regno;
371 {
372   register int regi;
373   register greg_t *regp = (greg_t *) gregsetp;
374   extern char registers[];
375 
376   for (regi = 0 ; regi < R_PC ; regi++)
377     {
378       if ((regno == -1) || (regno == regi))
379 	{
380 	  *(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
381 	}
382     }
383   if ((regno == -1) || (regno == PS_REGNUM))
384     {
385       *(regp + R_PS) = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
386     }
387   if ((regno == -1) || (regno == PC_REGNUM))
388     {
389       *(regp + R_PC) = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
390     }
391 }
392 
393 #if defined (FP0_REGNUM)
394 
395 /*  Given a pointer to a floating point register set in /proc format
396     (fpregset_t *), unpack the register contents and supply them as gdb's
397     idea of the current floating point register values. */
398 
399 void
400 supply_fpregset (fpregsetp)
401 fpregset_t *fpregsetp;
402 {
403   register int regi;
404   char *from;
405 
406   for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++)
407     {
408       from = (char *) &(fpregsetp -> f_fpregs[regi-FP0_REGNUM][0]);
409       supply_register (regi, from);
410     }
411   supply_register (FPC_REGNUM, (char *) &(fpregsetp -> f_pcr));
412   supply_register (FPS_REGNUM, (char *) &(fpregsetp -> f_psr));
413   supply_register (FPI_REGNUM, (char *) &(fpregsetp -> f_fpiaddr));
414 }
415 
416 /*  Given a pointer to a floating point register set in /proc format
417     (fpregset_t *), update the register specified by REGNO from gdb's idea
418     of the current floating point register set.  If REGNO is -1, update
419     them all. */
420 
421 void
422 fill_fpregset (fpregsetp, regno)
423 fpregset_t *fpregsetp;
424 int regno;
425 {
426   int regi;
427   char *to;
428   char *from;
429   extern char registers[];
430 
431   for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++)
432     {
433       if ((regno == -1) || (regno == regi))
434 	{
435 	  from = (char *) &registers[REGISTER_BYTE (regi)];
436 	  to = (char *) &(fpregsetp -> f_fpregs[regi-FP0_REGNUM][0]);
437 	  memcpy (to, from, REGISTER_RAW_SIZE (regi));
438 	}
439     }
440   if ((regno == -1) || (regno == FPC_REGNUM))
441     {
442       fpregsetp -> f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
443     }
444   if ((regno == -1) || (regno == FPS_REGNUM))
445     {
446       fpregsetp -> f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
447     }
448   if ((regno == -1) || (regno == FPI_REGNUM))
449     {
450       fpregsetp -> f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
451     }
452 }
453 
454 #endif	/* defined (FP0_REGNUM) */
455 
456 #endif  /* USE_PROC_FS */
457 
458 #ifdef GET_LONGJMP_TARGET
459 /* Figure out where the longjmp will land.  Slurp the args out of the stack.
460    We expect the first arg to be a pointer to the jmp_buf structure from which
461    we extract the pc (JB_PC) that we will land at.  The pc is copied into PC.
462    This routine returns true on success. */
463 
464 int
465 get_longjmp_target(pc)
466      CORE_ADDR *pc;
467 {
468   char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
469   CORE_ADDR sp, jb_addr;
470 
471   sp = read_register(SP_REGNUM);
472 
473   if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
474 			  buf,
475 			  TARGET_PTR_BIT / TARGET_CHAR_BIT))
476     return 0;
477 
478   jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
479 
480   if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
481 			  TARGET_PTR_BIT / TARGET_CHAR_BIT))
482     return 0;
483 
484   *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
485 
486   return 1;
487 }
488 #endif /* GET_LONGJMP_TARGET */
489 
490 /* Immediately after a function call, return the saved pc before the frame
491    is setup.  For sun3's, we check for the common case of being inside of a
492    system call, and if so, we know that Sun pushes the call # on the stack
493    prior to doing the trap. */
494 
495 CORE_ADDR
496 m68k_saved_pc_after_call(frame)
497      struct frame_info *frame;
498 {
499 #ifdef SYSCALL_TRAP
500   int op;
501 
502   op = read_memory_integer (frame->pc - SYSCALL_TRAP_OFFSET, 2);
503 
504   if (op == SYSCALL_TRAP)
505     return read_memory_integer (read_register (SP_REGNUM) + 4, 4);
506   else
507 #endif /* SYSCALL_TRAP */
508     return read_memory_integer (read_register (SP_REGNUM), 4);
509 }
510 
511 /* This used to be needed by tm-sun3.h but is probably not
512    used by any targets anymore.  Keep it for now anyway.
513    This works like blockframe.c:sigtramp_saved_pc() */
514 
515 #ifdef	SIG_PC_FP_OFFSET
516 CORE_ADDR
517 m68k_sigtramp_saved_pc (frame)
518      struct frame_info *frame;
519 {
520   CORE_ADDR nextfp, pc;
521 
522   if (frame->signal_handler_caller == 0)
523     abort();
524 
525   nextfp = (frame)->next ?
526     (frame)->next->frame :
527     read_register (SP_REGNUM) - 8;
528   nextfp += SIG_PC_FP_OFFSET;
529 
530   pc = read_memory_integer (nextfp, 4);
531 
532   return pc;
533 }
534 #endif	/* SIG_PC_FP_OFFSET */
535 
536 /* For Open- and NetBSD, sigtramp is 32 bytes before STACK_END_ADDR,
537    but we don't know where that is until run-time!  */
538 
539 #if defined(TM_NBSD_H) || defined(TM_OBSD_H)
540 int
541 nbsd_in_sigtramp (pc)
542      CORE_ADDR pc;
543 {
544   static CORE_ADDR stack_end_addr;
545   struct minimal_symbol *msymbol;
546   CORE_ADDR pssaddr;
547   int rv;
548 
549   if (stack_end_addr == 0) {
550     msymbol = lookup_minimal_symbol("__ps_strings", NULL, NULL);
551     if (msymbol == NULL)
552       pssaddr = 0x40a0; /* XXX return 0? */
553     else
554       pssaddr = SYMBOL_VALUE_ADDRESS(msymbol);
555     stack_end_addr = read_memory_integer (pssaddr, 4);
556     stack_end_addr = (stack_end_addr + 0xFF) & ~0xFF;
557   }
558   rv = ((pc >= (stack_end_addr - 32)) &&
559 	(pc < stack_end_addr));
560   return rv;
561 }
562 #endif	/* TM_NBSD_H || TM_OBSD_H */
563 
564 void
565 _initialize_m68k_tdep ()
566 {
567   tm_print_insn = print_insn_m68k;
568 }
569