1/* Print VAX instructions.
2   Copyright 1995, 1998, 2000, 2001, 2002, 2005
3   Free Software Foundation, Inc.
4   Contributed by Pauline Middelink <middelin@polyware.iaf.nl>
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., 51 Franklin Street - Fifth Floor, Boston,
19   MA 02110-1301, USA.  */
20
21#include <setjmp.h>
22#include <string.h>
23#include "sysdep.h"
24#include "opcode/vax.h"
25#include "dis-asm.h"
26
27static char *reg_names[] =
28{
29  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
30  "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc"
31};
32
33/* Definitions for the function entry mask bits.  */
34static char *entry_mask_bit[] =
35{
36  /* Registers 0 and 1 shall not be saved, since they're used to pass back
37     a function's result to its caller...  */
38  "~r0~", "~r1~",
39  /* Registers 2 .. 11 are normal registers.  */
40  "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
41  /* Registers 12 and 13 are argument and frame pointer and must not
42     be saved by using the entry mask.  */
43  "~ap~", "~fp~",
44  /* Bits 14 and 15 control integer and decimal overflow.  */
45  "IntOvfl", "DecOvfl",
46};
47
48/* Sign-extend an (unsigned char). */
49#define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
50
51/* Get a 1 byte signed integer.  */
52#define NEXTBYTE(p)  \
53  (p += 1, FETCH_DATA (info, p), \
54  COERCE_SIGNED_CHAR(p[-1]))
55
56/* Get a 2 byte signed integer.  */
57#define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
58#define NEXTWORD(p)  \
59  (p += 2, FETCH_DATA (info, p), \
60   COERCE16 ((p[-1] << 8) + p[-2]))
61
62/* Get a 4 byte signed integer.  */
63#define COERCE32(x) ((int) (((x) ^ 0x80000000) - 0x80000000))
64#define NEXTLONG(p)  \
65  (p += 4, FETCH_DATA (info, p), \
66   (COERCE32 ((((((p[-1] << 8) + p[-2]) << 8) + p[-3]) << 8) + p[-4])))
67
68/* Maximum length of an instruction.  */
69#define MAXLEN 25
70
71struct private
72{
73  /* Points to first byte not fetched.  */
74  bfd_byte * max_fetched;
75  bfd_byte   the_buffer[MAXLEN];
76  bfd_vma    insn_start;
77  jmp_buf    bailout;
78};
79
80/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
81   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
82   on error.  */
83#define FETCH_DATA(info, addr) \
84  ((addr) <= ((struct private *)(info->private_data))->max_fetched \
85   ? 1 : fetch_data ((info), (addr)))
86
87static int
88fetch_data (struct disassemble_info *info, bfd_byte *addr)
89{
90  int status;
91  struct private *priv = (struct private *) info->private_data;
92  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
93
94  status = (*info->read_memory_func) (start,
95				      priv->max_fetched,
96				      addr - priv->max_fetched,
97				      info);
98  if (status != 0)
99    {
100      (*info->memory_error_func) (status, start, info);
101      longjmp (priv->bailout, 1);
102    }
103  else
104    priv->max_fetched = addr;
105
106  return 1;
107}
108
109/* Entry mask handling.  */
110static unsigned int  entry_addr_occupied_slots = 0;
111static unsigned int  entry_addr_total_slots = 0;
112static bfd_vma *     entry_addr = NULL;
113
114/* Parse the VAX specific disassembler options.  These contain function
115   entry addresses, which can be useful to disassemble ROM images, since
116   there's no symbol table.  Returns TRUE upon success, FALSE otherwise.  */
117
118static bfd_boolean
119parse_disassembler_options (char * options)
120{
121  const char * entry_switch = "entry:";
122
123  while ((options = strstr (options, entry_switch)))
124    {
125      options += strlen (entry_switch);
126
127      /* The greater-than part of the test below is paranoia.  */
128      if (entry_addr_occupied_slots >= entry_addr_total_slots)
129	{
130	  /* A guesstimate of the number of entries we will have to create.  */
131	  entry_addr_total_slots +=
132	    strlen (options) / (strlen (entry_switch) + 5);
133
134	  entry_addr = realloc (entry_addr, sizeof (bfd_vma)
135				* entry_addr_total_slots);
136	}
137
138      if (entry_addr == NULL)
139	return FALSE;
140
141      entry_addr[entry_addr_occupied_slots] = bfd_scan_vma (options, NULL, 0);
142      entry_addr_occupied_slots ++;
143    }
144
145  return TRUE;
146}
147
148#if 0 /* FIXME:  Ideally the disassembler should have target specific
149	 initialisation and termination function pointers.  Then
150	 parse_disassembler_options could be the init function and
151	 free_entry_array (below) could be the termination routine.
152	 Until then there is no way for the disassembler to tell us
153	 that it has finished and that we no longer need the entry
154	 array, so this routine is suppressed for now.  It does mean
155	 that we leak memory, but only to the extent that we do not
156	 free it just before the disassembler is about to terminate
157	 anyway.  */
158
159/* Free memory allocated to our entry array.  */
160
161static void
162free_entry_array (void)
163{
164  if (entry_addr)
165    {
166      free (entry_addr);
167      entry_addr = NULL;
168      entry_addr_occupied_slots = entry_addr_total_slots = 0;
169    }
170}
171#endif
172/* Check if the given address is a known function entry. Either there must
173   be a symbol of function type at this address, or the address must be
174   a forced entry point.  The later helps in disassembling ROM images, because
175   there's no symbol table at all.  Forced entry points can be given by
176   supplying several -M options to objdump: -M entry:0xffbb7730.  */
177
178static bfd_boolean
179is_function_entry (struct disassemble_info *info, bfd_vma addr)
180{
181  unsigned int i;
182
183  /* Check if there's a BSF_FUNCTION symbol at our address.  */
184  if (info->symbols
185      && info->symbols[0]
186      && (info->symbols[0]->flags & BSF_FUNCTION)
187      && addr == bfd_asymbol_value (info->symbols[0]))
188    return TRUE;
189
190  /* Check for forced function entry address.  */
191  for (i = entry_addr_occupied_slots; i--;)
192    if (entry_addr[i] == addr)
193      return TRUE;
194
195  return FALSE;
196}
197
198static int
199print_insn_mode (const char *d,
200		 int size,
201		 unsigned char *p0,
202		 bfd_vma addr,	/* PC for this arg to be relative to.  */
203		 disassemble_info *info)
204{
205  unsigned char *p = p0;
206  unsigned char mode, reg;
207
208  /* Fetch and interpret mode byte.  */
209  mode = (unsigned char) NEXTBYTE (p);
210  reg = mode & 0xF;
211  switch (mode & 0xF0)
212    {
213    case 0x00:
214    case 0x10:
215    case 0x20:
216    case 0x30: /* Literal mode			$number.  */
217      if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
218	(*info->fprintf_func) (info->stream, "$0x%x [%c-float]", mode, d[1]);
219      else
220        (*info->fprintf_func) (info->stream, "$0x%x", mode);
221      break;
222    case 0x40: /* Index:			base-addr[Rn] */
223      p += print_insn_mode (d, size, p0 + 1, addr + 1, info);
224      (*info->fprintf_func) (info->stream, "[%s]", reg_names[reg]);
225      break;
226    case 0x50: /* Register:			Rn */
227      (*info->fprintf_func) (info->stream, "%s", reg_names[reg]);
228      break;
229    case 0x60: /* Register deferred:		(Rn) */
230      (*info->fprintf_func) (info->stream, "(%s)", reg_names[reg]);
231      break;
232    case 0x70: /* Autodecrement:		-(Rn) */
233      (*info->fprintf_func) (info->stream, "-(%s)", reg_names[reg]);
234      break;
235    case 0x80: /* Autoincrement:		(Rn)+ */
236      if (reg == 0xF)
237	{	/* Immediate?  */
238	  int i;
239
240	  FETCH_DATA (info, p + size);
241	  (*info->fprintf_func) (info->stream, "$0x");
242	  if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
243	    {
244	      int float_word;
245
246	      float_word = p[0] | (p[1] << 8);
247	      if ((d[1] == 'd' || d[1] == 'f')
248		  && (float_word & 0xff80) == 0x8000)
249		{
250		  (*info->fprintf_func) (info->stream, "[invalid %c-float]",
251					 d[1]);
252		}
253	      else
254		{
255	          for (i = 0; i < size; i++)
256		    (*info->fprintf_func) (info->stream, "%02x",
257		                           p[size - i - 1]);
258	          (*info->fprintf_func) (info->stream, " [%c-float]", d[1]);
259		}
260	    }
261	  else
262	    {
263	      for (i = 0; i < size; i++)
264	        (*info->fprintf_func) (info->stream, "%02x", p[size - i - 1]);
265	    }
266	  p += size;
267	}
268      else
269	(*info->fprintf_func) (info->stream, "(%s)+", reg_names[reg]);
270      break;
271    case 0x90: /* Autoincrement deferred:	@(Rn)+ */
272      if (reg == 0xF)
273	(*info->fprintf_func) (info->stream, "*0x%x", NEXTLONG (p));
274      else
275	(*info->fprintf_func) (info->stream, "@(%s)+", reg_names[reg]);
276      break;
277    case 0xB0: /* Displacement byte deferred:	*displ(Rn).  */
278      (*info->fprintf_func) (info->stream, "*");
279    case 0xA0: /* Displacement byte:		displ(Rn).  */
280      if (reg == 0xF)
281	(*info->print_address_func) (addr + 2 + NEXTBYTE (p), info);
282      else
283	(*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTBYTE (p),
284			       reg_names[reg]);
285      break;
286    case 0xD0: /* Displacement word deferred:	*displ(Rn).  */
287      (*info->fprintf_func) (info->stream, "*");
288    case 0xC0: /* Displacement word:		displ(Rn).  */
289      if (reg == 0xF)
290	(*info->print_address_func) (addr + 3 + NEXTWORD (p), info);
291      else
292	(*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTWORD (p),
293			       reg_names[reg]);
294      break;
295    case 0xF0: /* Displacement long deferred:	*displ(Rn).  */
296      (*info->fprintf_func) (info->stream, "*");
297    case 0xE0: /* Displacement long:		displ(Rn).  */
298      if (reg == 0xF)
299	(*info->print_address_func) (addr + 5 + NEXTLONG (p), info);
300      else
301	(*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTLONG (p),
302			       reg_names[reg]);
303      break;
304    }
305
306  return p - p0;
307}
308
309/* Returns number of bytes "eaten" by the operand, or return -1 if an
310   invalid operand was found, or -2 if an opcode tabel error was
311   found. */
312
313static int
314print_insn_arg (const char *d,
315		unsigned char *p0,
316		bfd_vma addr,	/* PC for this arg to be relative to.  */
317		disassemble_info *info)
318{
319  int arg_len;
320
321  /* Check validity of addressing length.  */
322  switch (d[1])
323    {
324    case 'b' : arg_len = 1;	break;
325    case 'd' : arg_len = 8;	break;
326    case 'f' : arg_len = 4;	break;
327    case 'g' : arg_len = 8;	break;
328    case 'h' : arg_len = 16;	break;
329    case 'l' : arg_len = 4;	break;
330    case 'o' : arg_len = 16;	break;
331    case 'w' : arg_len = 2;	break;
332    case 'q' : arg_len = 8;	break;
333    default  : abort ();
334    }
335
336  /* Branches have no mode byte.  */
337  if (d[0] == 'b')
338    {
339      unsigned char *p = p0;
340
341      if (arg_len == 1)
342	(*info->print_address_func) (addr + 1 + NEXTBYTE (p), info);
343      else
344	(*info->print_address_func) (addr + 2 + NEXTWORD (p), info);
345
346      return p - p0;
347    }
348
349  return print_insn_mode (d, arg_len, p0, addr, info);
350}
351
352/* Print the vax instruction at address MEMADDR in debugged memory,
353   on INFO->STREAM.  Returns length of the instruction, in bytes.  */
354
355int
356print_insn_vax (bfd_vma memaddr, disassemble_info *info)
357{
358  static bfd_boolean parsed_disassembler_options = FALSE;
359  const struct vot *votp;
360  const char *argp;
361  unsigned char *arg;
362  struct private priv;
363  bfd_byte *buffer = priv.the_buffer;
364
365  info->private_data = & priv;
366  priv.max_fetched = priv.the_buffer;
367  priv.insn_start = memaddr;
368
369  if (! parsed_disassembler_options
370      && info->disassembler_options != NULL)
371    {
372      parse_disassembler_options (info->disassembler_options);
373
374      /* To avoid repeated parsing of these options.  */
375      parsed_disassembler_options = TRUE;
376    }
377
378  if (setjmp (priv.bailout) != 0)
379    /* Error return.  */
380    return -1;
381
382  argp = NULL;
383  /* Check if the info buffer has more than one byte left since
384     the last opcode might be a single byte with no argument data.  */
385  if (info->buffer_length - (memaddr - info->buffer_vma) > 1)
386    {
387      FETCH_DATA (info, buffer + 2);
388    }
389  else
390    {
391      FETCH_DATA (info, buffer + 1);
392      buffer[1] = 0;
393    }
394
395  /* Decode function entry mask.  */
396  if (is_function_entry (info, memaddr))
397    {
398      int i = 0;
399      int register_mask = buffer[1] << 8 | buffer[0];
400
401      (*info->fprintf_func) (info->stream, ".word 0x%04x # Entry mask: <",
402			     register_mask);
403
404      for (i = 15; i >= 0; i--)
405	if (register_mask & (1 << i))
406          (*info->fprintf_func) (info->stream, " %s", entry_mask_bit[i]);
407
408      (*info->fprintf_func) (info->stream, " >");
409
410      return 2;
411    }
412
413  for (votp = &votstrs[0]; votp->name[0]; votp++)
414    {
415      vax_opcodeT opcode = votp->detail.code;
416
417      /* 2 byte codes match 2 buffer pos. */
418      if ((bfd_byte) opcode == buffer[0]
419	  && (opcode >> 8 == 0 || opcode >> 8 == buffer[1]))
420	{
421	  argp = votp->detail.args;
422	  break;
423	}
424    }
425  if (argp == NULL)
426    {
427      /* Handle undefined instructions. */
428      (*info->fprintf_func) (info->stream, ".word 0x%x",
429			     (buffer[0] << 8) + buffer[1]);
430      return 2;
431    }
432
433  /* Point at first byte of argument data, and at descriptor for first
434     argument.  */
435  arg = buffer + ((votp->detail.code >> 8) ? 2 : 1);
436
437  /* Make sure we have it in mem */
438  FETCH_DATA (info, arg);
439
440  (*info->fprintf_func) (info->stream, "%s", votp->name);
441  if (*argp)
442    (*info->fprintf_func) (info->stream, " ");
443
444  while (*argp)
445    {
446      arg += print_insn_arg (argp, arg, memaddr + arg - buffer, info);
447      argp += 2;
448      if (*argp)
449	(*info->fprintf_func) (info->stream, ",");
450    }
451
452  return arg - buffer;
453}
454
455