gdb: fix vfork with multiple threads
[deliverable/binutils-gdb.git] / opcodes / tic30-dis.c
index 9e57050f1302bd8bf9cc3221bcb96b4c202f1256..a78a0dad218c61d269b9cb9a57c49b1460f9f080 100644 (file)
@@ -1,26 +1,28 @@
 /* Disassembly routines for TMS320C30 architecture
-   Copyright 1998, 1999, 2000, 2002, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1998-2021 Free Software Foundation, Inc.
    Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
 
-   This program is free software; you can redistribute it and/or modify
+   This file is part of the GNU opcodes library.
+
+   This library is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
 
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   It is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-   02110-1301, USA.  */
+   along with this file; see the file COPYING.  If not, write to the
+   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
+#include "sysdep.h"
 #include <errno.h>
 #include <math.h>
-#include "sysdep.h"
-#include "dis-asm.h"
+#include "disassemble.h"
 #include "opcode/tic30.h"
 
 #define NORMAL_INSN   1
@@ -62,7 +64,7 @@ static unsigned int _pc;
 struct instruction
 {
   int type;
-  template *tm;
+  insn_template *tm;
   partemplate *ptm;
 };
 
@@ -76,7 +78,7 @@ get_tic30_instruction (unsigned long insn_word, struct instruction *insn)
     case THREE_OPERAND:
       insn->type = NORMAL_INSN;
       {
-       template *current_optab = (template *) tic30_optab;
+       insn_template *current_optab = (insn_template *) tic30_optab;
 
        for (; current_optab < tic30_optab_end; current_optab++)
          {
@@ -143,7 +145,7 @@ get_tic30_instruction (unsigned long insn_word, struct instruction *insn)
     case BRANCHES:
       insn->type = NORMAL_INSN;
       {
-       template *current_optab = (template *) tic30_optab;
+       insn_template *current_optab = (insn_template *) tic30_optab;
 
        for (; current_optab < tic30_optab_end; current_optab++)
          {
@@ -186,6 +188,8 @@ get_tic30_instruction (unsigned long insn_word, struct instruction *insn)
   return 1;
 }
 
+#define OPERAND_BUFFER_LEN 15
+
 static int
 get_register_operand (unsigned char fragment, char *buffer)
 {
@@ -197,7 +201,8 @@ get_register_operand (unsigned char fragment, char *buffer)
     {
       if ((fragment & 0x1F) == current_reg->opcode)
        {
-         strcpy (buffer, current_reg->name);
+         strncpy (buffer, current_reg->name, OPERAND_BUFFER_LEN - 1);
+         buffer[OPERAND_BUFFER_LEN - 1] = 0;
          return 1;
        }
     }
@@ -248,16 +253,25 @@ get_indirect_operand (unsigned short fragment,
                int bufcnt;
 
                len = strlen (current_ind->syntax);
+
                for (i = 0, bufcnt = 0; i < len; i++, bufcnt++)
                  {
                    buffer[bufcnt] = current_ind->syntax[i];
-                   if (buffer[bufcnt - 1] == 'a' && buffer[bufcnt] == 'r')
+
+                   if (bufcnt > 0
+                       && bufcnt < OPERAND_BUFFER_LEN - 1
+                       && buffer[bufcnt - 1] == 'a'
+                       && buffer[bufcnt] == 'r')
                      buffer[++bufcnt] = arnum + '0';
-                   if (buffer[bufcnt] == '('
+                   
+                   if (bufcnt < OPERAND_BUFFER_LEN - 1
+                       && buffer[bufcnt] == '('
                        && current_ind->displacement == DISP_REQUIRED)
                      {
-                       sprintf (&buffer[bufcnt + 1], "%u", disp);
-                       bufcnt += strlen (&buffer[bufcnt + 1]);
+                       snprintf (buffer + (bufcnt + 1),
+                                OPERAND_BUFFER_LEN - (bufcnt + 1),
+                                "%u", disp);
+                       bufcnt += strlen (buffer + (bufcnt + 1));
                      }
                  }
                buffer[bufcnt + 1] = '\0';
@@ -272,7 +286,7 @@ get_indirect_operand (unsigned short fragment,
 static int
 cnvt_tmsfloat_ieee (unsigned long tmsfloat, int size, float *ieeefloat)
 {
-  unsigned long exp, sign, mant;
+  unsigned long exponent, sign, mant;
   union
   {
     unsigned long l;
@@ -289,16 +303,16 @@ cnvt_tmsfloat_ieee (unsigned long tmsfloat, int size, float *ieeefloat)
          tmsfloat = (long) tmsfloat >> 4;
        }
     }
-  exp = tmsfloat & 0xFF000000;
-  if (exp == 0x80000000)
+  exponent = tmsfloat & 0xFF000000;
+  if (exponent == 0x80000000)
     {
       *ieeefloat = 0.0;
       return 1;
     }
-  exp += 0x7F000000;
+  exponent += 0x7F000000;
   sign = (tmsfloat & 0x00800000) << 8;
   mant = tmsfloat & 0x007FFFFF;
-  if (exp == 0xFF000000)
+  if (exponent == 0xFF000000)
     {
       if (mant == 0)
        *ieeefloat = ERANGE;
@@ -315,18 +329,18 @@ cnvt_tmsfloat_ieee (unsigned long tmsfloat, int size, float *ieeefloat)
 #endif
       return 1;
     }
-  exp >>= 1;
+  exponent >>= 1;
   if (sign)
     {
       mant = (~mant) & 0x007FFFFF;
       mant += 1;
-      exp += mant & 0x00800000;
-      exp &= 0x7F800000;
+      exponent += mant & 0x00800000;
+      exponent &= 0x7F800000;
       mant &= 0x007FFFFF;
     }
   if (tmsfloat == 0x80000000)
-    sign = mant = exp = 0;
-  tmsfloat = sign | exp | mant;
+    sign = mant = exponent = 0;
+  tmsfloat = sign | exponent | mant;
   val.l = tmsfloat;
   *ieeefloat = val.f;
   return 1;
@@ -338,7 +352,7 @@ print_two_operand (disassemble_info *info,
                   struct instruction *insn)
 {
   char name[12];
-  char operand[2][13] =
+  char operand[2][OPERAND_BUFFER_LEN] =
   {
     {0},
     {0}
@@ -425,7 +439,7 @@ print_three_operand (disassemble_info *info,
                     unsigned long insn_word,
                     struct instruction *insn)
 {
-  char operand[3][13] =
+  char operand[3][OPERAND_BUFFER_LEN] =
   {
     {0},
     {0},
@@ -471,7 +485,7 @@ print_par_insn (disassemble_info *info,
 {
   size_t i, len;
   char *name1, *name2;
-  char operand[2][3][13] =
+  char operand[2][3][OPERAND_BUFFER_LEN] =
   {
     {
       {0},
@@ -593,7 +607,7 @@ print_branch (disassemble_info *info,
              unsigned long insn_word,
              struct instruction *insn)
 {
-  char operand[2][13] =
+  char operand[2][OPERAND_BUFFER_LEN] =
   {
     {0},
     {0}
@@ -667,9 +681,9 @@ print_branch (disassemble_info *info,
       if (address == 0)
        info->fprintf_func (info->stream, " <%s>", sym->name);
       else
-       info->fprintf_func (info->stream, " <%s %c %d>", sym->name,
+       info->fprintf_func (info->stream, " <%s %c %lu>", sym->name,
                            ((short) address < 0) ? '-' : '+',
-                           abs (address));
+                           address);
     }
   return 1;
 }
@@ -681,11 +695,16 @@ print_insn_tic30 (bfd_vma pc, disassemble_info *info)
   struct instruction insn = { 0, NULL, NULL };
   bfd_vma bufaddr = pc - info->buffer_vma;
 
+  if (bufaddr + 3 >= info->buffer_length)
+    return -1;
+
   /* Obtain the current instruction word from the buffer.  */
-  insn_word = (*(info->buffer + bufaddr) << 24) | (*(info->buffer + bufaddr + 1) << 16) |
-    (*(info->buffer + bufaddr + 2) << 8) | *(info->buffer + bufaddr + 3);
+  insn_word = (((unsigned) *(info->buffer + bufaddr) << 24)
+              | (*(info->buffer + bufaddr + 1) << 16)
+              | (*(info->buffer + bufaddr + 2) << 8)
+              | *(info->buffer + bufaddr + 3));
   _pc = pc / 4;
-  /* Get the instruction refered to by the current instruction word
+  /* Get the instruction referred to by the current instruction word
      and print it out based on its type.  */
   if (!get_tic30_instruction (insn_word, &insn))
     return -1;
This page took 0.029828 seconds and 4 git commands to generate.