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