Fix compile time warnings from a GCC 4.0 compiler
[external/binutils.git] / opcodes / vax-dis.c
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
27 static 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.  */
34 static 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
71 struct 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
87 static int
88 fetch_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.  */
110 static unsigned int  entry_addr_occupied_slots = 0;
111 static unsigned int  entry_addr_total_slots = 0;
112 static 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
118 static bfd_boolean
119 parse_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
161 static void
162 free_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
178 static bfd_boolean
179 is_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
198 static int
199 print_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
313 static int
314 print_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
355 int
356 print_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