Back to index

cell-binutils  2.17cvs20070401
vax-dis.c
Go to the documentation of this file.
00001 /* Print VAX instructions.
00002    Copyright 1995, 1998, 2000, 2001, 2002, 2005
00003    Free Software Foundation, Inc.
00004    Contributed by Pauline Middelink <middelin@polyware.iaf.nl>
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
00019    MA 02110-1301, USA.  */
00020 
00021 #include <setjmp.h>
00022 #include <string.h>
00023 #include "sysdep.h"
00024 #include "opcode/vax.h"
00025 #include "dis-asm.h"
00026 
00027 static char *reg_names[] =
00028 {
00029   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
00030   "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc"
00031 };
00032 
00033 /* Definitions for the function entry mask bits.  */
00034 static char *entry_mask_bit[] =
00035 {
00036   /* Registers 0 and 1 shall not be saved, since they're used to pass back
00037      a function's result to its caller...  */
00038   "~r0~", "~r1~",
00039   /* Registers 2 .. 11 are normal registers.  */
00040   "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
00041   /* Registers 12 and 13 are argument and frame pointer and must not
00042      be saved by using the entry mask.  */
00043   "~ap~", "~fp~",
00044   /* Bits 14 and 15 control integer and decimal overflow.  */
00045   "IntOvfl", "DecOvfl",
00046 };
00047 
00048 /* Sign-extend an (unsigned char). */
00049 #define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
00050 
00051 /* Get a 1 byte signed integer.  */
00052 #define NEXTBYTE(p)  \
00053   (p += 1, FETCH_DATA (info, p), \
00054   COERCE_SIGNED_CHAR(p[-1]))
00055 
00056 /* Get a 2 byte signed integer.  */
00057 #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
00058 #define NEXTWORD(p)  \
00059   (p += 2, FETCH_DATA (info, p), \
00060    COERCE16 ((p[-1] << 8) + p[-2]))
00061 
00062 /* Get a 4 byte signed integer.  */
00063 #define COERCE32(x) ((int) (((x) ^ 0x80000000) - 0x80000000))
00064 #define NEXTLONG(p)  \
00065   (p += 4, FETCH_DATA (info, p), \
00066    (COERCE32 ((((((p[-1] << 8) + p[-2]) << 8) + p[-3]) << 8) + p[-4])))
00067 
00068 /* Maximum length of an instruction.  */
00069 #define MAXLEN 25
00070 
00071 struct private
00072 {
00073   /* Points to first byte not fetched.  */
00074   bfd_byte * max_fetched;
00075   bfd_byte   the_buffer[MAXLEN];
00076   bfd_vma    insn_start;
00077   jmp_buf    bailout;
00078 };
00079 
00080 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
00081    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
00082    on error.  */
00083 #define FETCH_DATA(info, addr) \
00084   ((addr) <= ((struct private *)(info->private_data))->max_fetched \
00085    ? 1 : fetch_data ((info), (addr)))
00086 
00087 static int
00088 fetch_data (struct disassemble_info *info, bfd_byte *addr)
00089 {
00090   int status;
00091   struct private *priv = (struct private *) info->private_data;
00092   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
00093 
00094   status = (*info->read_memory_func) (start,
00095                                   priv->max_fetched,
00096                                   addr - priv->max_fetched,
00097                                   info);
00098   if (status != 0)
00099     {
00100       (*info->memory_error_func) (status, start, info);
00101       longjmp (priv->bailout, 1);
00102     }
00103   else
00104     priv->max_fetched = addr;
00105 
00106   return 1;
00107 }
00108 
00109 /* Entry mask handling.  */
00110 static unsigned int  entry_addr_occupied_slots = 0;
00111 static unsigned int  entry_addr_total_slots = 0;
00112 static bfd_vma *     entry_addr = NULL;
00113 
00114 /* Parse the VAX specific disassembler options.  These contain function
00115    entry addresses, which can be useful to disassemble ROM images, since
00116    there's no symbol table.  Returns TRUE upon success, FALSE otherwise.  */
00117 
00118 static bfd_boolean
00119 parse_disassembler_options (char * options)
00120 {
00121   const char * entry_switch = "entry:";
00122 
00123   while ((options = strstr (options, entry_switch)))
00124     {
00125       options += strlen (entry_switch);
00126 
00127       /* The greater-than part of the test below is paranoia.  */
00128       if (entry_addr_occupied_slots >= entry_addr_total_slots)
00129        {
00130          /* A guesstimate of the number of entries we will have to create.  */
00131          entry_addr_total_slots +=
00132            strlen (options) / (strlen (entry_switch) + 5);
00133          
00134          entry_addr = realloc (entry_addr, sizeof (bfd_vma)
00135                             * entry_addr_total_slots);
00136        }
00137 
00138       if (entry_addr == NULL)
00139        return FALSE;
00140          
00141       entry_addr[entry_addr_occupied_slots] = bfd_scan_vma (options, NULL, 0);
00142       entry_addr_occupied_slots ++;
00143     }
00144 
00145   return TRUE;
00146 }
00147 
00148 #if 0 /* FIXME:  Ideally the disassembler should have target specific
00149         initialisation and termination function pointers.  Then
00150         parse_disassembler_options could be the init function and
00151         free_entry_array (below) could be the termination routine.
00152         Until then there is no way for the disassembler to tell us
00153         that it has finished and that we no longer need the entry
00154         array, so this routine is suppressed for now.  It does mean
00155         that we leak memory, but only to the extent that we do not
00156         free it just before the disassembler is about to terminate
00157         anyway.  */
00158 
00159 /* Free memory allocated to our entry array.  */
00160 
00161 static void
00162 free_entry_array (void)
00163 {
00164   if (entry_addr)
00165     {
00166       free (entry_addr);
00167       entry_addr = NULL;
00168       entry_addr_occupied_slots = entry_addr_total_slots = 0;
00169     }
00170 }
00171 #endif
00172 /* Check if the given address is a known function entry. Either there must
00173    be a symbol of function type at this address, or the address must be
00174    a forced entry point.  The later helps in disassembling ROM images, because
00175    there's no symbol table at all.  Forced entry points can be given by
00176    supplying several -M options to objdump: -M entry:0xffbb7730.  */
00177 
00178 static bfd_boolean
00179 is_function_entry (struct disassemble_info *info, bfd_vma addr)
00180 {
00181   unsigned int i;
00182 
00183   /* Check if there's a BSF_FUNCTION symbol at our address.  */
00184   if (info->symbols
00185       && info->symbols[0]
00186       && (info->symbols[0]->flags & BSF_FUNCTION)
00187       && addr == bfd_asymbol_value (info->symbols[0]))
00188     return TRUE;
00189 
00190   /* Check for forced function entry address.  */
00191   for (i = entry_addr_occupied_slots; i--;)
00192     if (entry_addr[i] == addr)
00193       return TRUE;
00194 
00195   return FALSE;
00196 }
00197 
00198 static int
00199 print_insn_mode (const char *d,
00200                int size,
00201                unsigned char *p0,
00202                bfd_vma addr,       /* PC for this arg to be relative to.  */
00203                disassemble_info *info)
00204 {
00205   unsigned char *p = p0;
00206   unsigned char mode, reg;
00207 
00208   /* Fetch and interpret mode byte.  */
00209   mode = (unsigned char) NEXTBYTE (p);
00210   reg = mode & 0xF;
00211   switch (mode & 0xF0)
00212     {
00213     case 0x00:
00214     case 0x10:
00215     case 0x20:
00216     case 0x30: /* Literal mode                   $number.  */
00217       if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
00218        (*info->fprintf_func) (info->stream, "$0x%x [%c-float]", mode, d[1]);
00219       else
00220         (*info->fprintf_func) (info->stream, "$0x%x", mode);
00221       break;
00222     case 0x40: /* Index:                  base-addr[Rn] */
00223       p += print_insn_mode (d, size, p0 + 1, addr + 1, info);
00224       (*info->fprintf_func) (info->stream, "[%s]", reg_names[reg]);
00225       break;
00226     case 0x50: /* Register:               Rn */
00227       (*info->fprintf_func) (info->stream, "%s", reg_names[reg]);
00228       break;
00229     case 0x60: /* Register deferred:             (Rn) */
00230       (*info->fprintf_func) (info->stream, "(%s)", reg_names[reg]);
00231       break;
00232     case 0x70: /* Autodecrement:          -(Rn) */
00233       (*info->fprintf_func) (info->stream, "-(%s)", reg_names[reg]);
00234       break;
00235     case 0x80: /* Autoincrement:          (Rn)+ */
00236       if (reg == 0xF)
00237        {      /* Immediate?  */
00238          int i;
00239 
00240          FETCH_DATA (info, p + size);
00241          (*info->fprintf_func) (info->stream, "$0x");
00242          if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
00243            {
00244              int float_word;
00245 
00246              float_word = p[0] | (p[1] << 8);
00247              if ((d[1] == 'd' || d[1] == 'f')
00248                 && (float_word & 0xff80) == 0x8000)
00249               {
00250                 (*info->fprintf_func) (info->stream, "[invalid %c-float]",
00251                                     d[1]);
00252               }
00253              else
00254               {
00255                  for (i = 0; i < size; i++)
00256                   (*info->fprintf_func) (info->stream, "%02x",
00257                                          p[size - i - 1]);
00258                  (*info->fprintf_func) (info->stream, " [%c-float]", d[1]);
00259               }
00260            }
00261          else
00262            {
00263              for (i = 0; i < size; i++)
00264                (*info->fprintf_func) (info->stream, "%02x", p[size - i - 1]);
00265            }
00266          p += size;
00267        }
00268       else
00269        (*info->fprintf_func) (info->stream, "(%s)+", reg_names[reg]);
00270       break;
00271     case 0x90: /* Autoincrement deferred: @(Rn)+ */
00272       if (reg == 0xF)
00273        (*info->fprintf_func) (info->stream, "*0x%x", NEXTLONG (p));
00274       else
00275        (*info->fprintf_func) (info->stream, "@(%s)+", reg_names[reg]);
00276       break;
00277     case 0xB0: /* Displacement byte deferred:    *displ(Rn).  */
00278       (*info->fprintf_func) (info->stream, "*");
00279     case 0xA0: /* Displacement byte:             displ(Rn).  */
00280       if (reg == 0xF)
00281        (*info->print_address_func) (addr + 2 + NEXTBYTE (p), info);
00282       else
00283        (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTBYTE (p),
00284                             reg_names[reg]);
00285       break;
00286     case 0xD0: /* Displacement word deferred:    *displ(Rn).  */
00287       (*info->fprintf_func) (info->stream, "*");
00288     case 0xC0: /* Displacement word:             displ(Rn).  */
00289       if (reg == 0xF)
00290        (*info->print_address_func) (addr + 3 + NEXTWORD (p), info);
00291       else
00292        (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTWORD (p),
00293                             reg_names[reg]);
00294       break;
00295     case 0xF0: /* Displacement long deferred:    *displ(Rn).  */
00296       (*info->fprintf_func) (info->stream, "*");
00297     case 0xE0: /* Displacement long:             displ(Rn).  */
00298       if (reg == 0xF)
00299        (*info->print_address_func) (addr + 5 + NEXTLONG (p), info);
00300       else
00301        (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTLONG (p),
00302                             reg_names[reg]);
00303       break;
00304     }
00305 
00306   return p - p0;
00307 }
00308 
00309 /* Returns number of bytes "eaten" by the operand, or return -1 if an
00310    invalid operand was found, or -2 if an opcode tabel error was
00311    found. */
00312 
00313 static int
00314 print_insn_arg (const char *d,
00315               unsigned char *p0,
00316               bfd_vma addr, /* PC for this arg to be relative to.  */
00317               disassemble_info *info)
00318 {
00319   int arg_len;
00320 
00321   /* Check validity of addressing length.  */
00322   switch (d[1])
00323     {
00324     case 'b' : arg_len = 1; break;
00325     case 'd' : arg_len = 8; break;
00326     case 'f' : arg_len = 4; break;
00327     case 'g' : arg_len = 8; break;
00328     case 'h' : arg_len = 16;       break;
00329     case 'l' : arg_len = 4; break;
00330     case 'o' : arg_len = 16;       break;
00331     case 'w' : arg_len = 2; break;
00332     case 'q' : arg_len = 8; break;
00333     default  : abort ();
00334     }
00335 
00336   /* Branches have no mode byte.  */
00337   if (d[0] == 'b')
00338     {
00339       unsigned char *p = p0;
00340 
00341       if (arg_len == 1)
00342        (*info->print_address_func) (addr + 1 + NEXTBYTE (p), info);
00343       else
00344        (*info->print_address_func) (addr + 2 + NEXTWORD (p), info);
00345 
00346       return p - p0;
00347     }
00348 
00349   return print_insn_mode (d, arg_len, p0, addr, info);
00350 }
00351 
00352 /* Print the vax instruction at address MEMADDR in debugged memory,
00353    on INFO->STREAM.  Returns length of the instruction, in bytes.  */
00354 
00355 int
00356 print_insn_vax (bfd_vma memaddr, disassemble_info *info)
00357 {
00358   static bfd_boolean parsed_disassembler_options = FALSE;
00359   const struct vot *votp;
00360   const char *argp;
00361   unsigned char *arg;
00362   struct private priv;
00363   bfd_byte *buffer = priv.the_buffer;
00364 
00365   info->private_data = & priv;
00366   priv.max_fetched = priv.the_buffer;
00367   priv.insn_start = memaddr;
00368 
00369   if (! parsed_disassembler_options
00370       && info->disassembler_options != NULL)
00371     {
00372       parse_disassembler_options (info->disassembler_options);
00373 
00374       /* To avoid repeated parsing of these options.  */
00375       parsed_disassembler_options = TRUE;
00376     }
00377 
00378   if (setjmp (priv.bailout) != 0)
00379     /* Error return.  */
00380     return -1;
00381 
00382   argp = NULL;
00383   /* Check if the info buffer has more than one byte left since
00384      the last opcode might be a single byte with no argument data.  */
00385   if (info->buffer_length - (memaddr - info->buffer_vma) > 1)
00386     {
00387       FETCH_DATA (info, buffer + 2);
00388     }
00389   else
00390     {
00391       FETCH_DATA (info, buffer + 1);
00392       buffer[1] = 0;
00393     }
00394 
00395   /* Decode function entry mask.  */
00396   if (is_function_entry (info, memaddr))
00397     {
00398       int i = 0;
00399       int register_mask = buffer[1] << 8 | buffer[0];
00400 
00401       (*info->fprintf_func) (info->stream, ".word 0x%04x # Entry mask: <",
00402                           register_mask);
00403 
00404       for (i = 15; i >= 0; i--)
00405        if (register_mask & (1 << i))
00406           (*info->fprintf_func) (info->stream, " %s", entry_mask_bit[i]);
00407 
00408       (*info->fprintf_func) (info->stream, " >");
00409 
00410       return 2;
00411     }
00412 
00413   for (votp = &votstrs[0]; votp->name[0]; votp++)
00414     {
00415       vax_opcodeT opcode = votp->detail.code;
00416 
00417       /* 2 byte codes match 2 buffer pos. */
00418       if ((bfd_byte) opcode == buffer[0]
00419          && (opcode >> 8 == 0 || opcode >> 8 == buffer[1]))
00420        {
00421          argp = votp->detail.args;
00422          break;
00423        }
00424     }
00425   if (argp == NULL)
00426     {
00427       /* Handle undefined instructions. */
00428       (*info->fprintf_func) (info->stream, ".word 0x%x",
00429                           (buffer[0] << 8) + buffer[1]);
00430       return 2;
00431     }
00432 
00433   /* Point at first byte of argument data, and at descriptor for first
00434      argument.  */
00435   arg = buffer + ((votp->detail.code >> 8) ? 2 : 1);
00436 
00437   /* Make sure we have it in mem */
00438   FETCH_DATA (info, arg);
00439 
00440   (*info->fprintf_func) (info->stream, "%s", votp->name);
00441   if (*argp)
00442     (*info->fprintf_func) (info->stream, " ");
00443 
00444   while (*argp)
00445     {
00446       arg += print_insn_arg (argp, arg, memaddr + arg - buffer, info);
00447       argp += 2;
00448       if (*argp)
00449        (*info->fprintf_func) (info->stream, ",");
00450     }
00451 
00452   return arg - buffer;
00453 }
00454