This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: 2.19 -enable-targets=all one error in m68k-dis.c due to longjmp, easily fixed with volatile


Hi Alan, Hi Jay,

In this particular case I'm quite sure the warning is
false, so it isn't a good idea to slow down this function by making
"info" volatile.

Agreed.


Perhaps we should turn off -Werror in the opcodes/
directory instead as there isn't a way to turn off just the longjmp
without turning off a bunch of other errors.

I disagree. I think that we should keep -Werror as it does help to find real bugs.


The real problem it seems to me is that m68k-dis.c is using setjmp / longjmp when there really is no need for it. It was just to save the author from writing a whole lot of error value handling code. So I have gone ahead and written that code.

Jay - would you care to try out the attached patch and let me know if it works for you ? Assuming that it does I will check the patch into the branch and the mainline.

Cheers
  Nick



Index: opcodes/m68k-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/m68k-dis.c,v
retrieving revision 1.29
diff -c -3 -p -r1.29 m68k-dis.c
*** opcodes/m68k-dis.c	27 Sep 2007 11:14:10 -0000	1.29
--- opcodes/m68k-dis.c	24 Nov 2008 16:18:24 -0000
*************** static char *const reg_half_names[] =
*** 60,105 ****
  #endif
  
  /* Get a 1 byte signed integer.  */
! #define NEXTBYTE(p)  (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1]))
  
  /* Get a 2 byte signed integer.  */
  #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
! #define NEXTWORD(p)  \
!   (p += 2, FETCH_DATA (info, p), \
!    COERCE16 ((p[-2] << 8) + p[-1]))
  
  /* Get a 4 byte signed integer.  */
  #define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000)
! #define NEXTLONG(p)  \
!   (p += 4, FETCH_DATA (info, p), \
!    (COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])))
  
  /* Get a 4 byte unsigned integer.  */
! #define NEXTULONG(p)  \
!   (p += 4, FETCH_DATA (info, p), \
!    (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]))
  
  /* Get a single precision float.  */
! #define NEXTSINGLE(val, p) \
!   (p += 4, FETCH_DATA (info, p), \
!    floatformat_to_double (&floatformat_ieee_single_big, (char *) p - 4, &val))
  
  /* Get a double precision float.  */
! #define NEXTDOUBLE(val, p) \
!   (p += 8, FETCH_DATA (info, p), \
!    floatformat_to_double (&floatformat_ieee_double_big, (char *) p - 8, &val))
  
  /* Get an extended precision float.  */
! #define NEXTEXTEND(val, p) \
!   (p += 12, FETCH_DATA (info, p), \
!    floatformat_to_double (&floatformat_m68881_ext, (char *) p - 12, &val))
  
  /* Need a function to convert from packed to double
     precision.   Actually, it's easier to print a
     packed number than a double anyway, so maybe
     there should be a special case to handle this... */
! #define NEXTPACKED(p) \
!   (p += 12, FETCH_DATA (info, p), 0.0)
  
  /* Maximum length of an instruction.  */
  #define MAXLEN 22
--- 60,162 ----
  #endif
  
  /* Get a 1 byte signed integer.  */
! #define NEXTBYTE(p, val)			\
!   do						\
!     {						\
!       p += 2;					\
!       if (FETCH_DATA (info, p) < 0)		\
! 	return -3;				\
!       val = COERCE_SIGNED_CHAR (p[-1]);		\
!     }						\
!   while (0)
  
  /* Get a 2 byte signed integer.  */
  #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
! 
! #define NEXTWORD(p, val, ret_val)		\
!   do						\
!     {						\
!       p += 2;					\
!       if (FETCH_DATA (info, p) < 0)		\
! 	return ret_val;				\
!       val = COERCE16 ((p[-2] << 8) + p[-1]);	\
!     }						\
!   while (0)						
  
  /* Get a 4 byte signed integer.  */
  #define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000)
! 
! #define NEXTLONG(p, val, ret_val)					\
!   do									\
!     {									\
!       p += 4;								\
!       if (FETCH_DATA (info, p) < 0)					\
! 	return ret_val;							\
!       val = COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]); \
!     }									\
!   while (0)
  
  /* Get a 4 byte unsigned integer.  */
! #define NEXTULONG(p, val)						\
!   do									\
!     {									\
!       p += 4;								\
!       if (FETCH_DATA (info, p) < 0)					\
! 	return -3;							\
!       val = (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]); \
!     }									\
!   while (0)
  
  /* Get a single precision float.  */
! #define NEXTSINGLE(val, p)					\
!   do								\
!     {								\
!       p += 4;							\
!       if (FETCH_DATA (info, p) < 0)				\
! 	return -3;						\
!       floatformat_to_double (& floatformat_ieee_single_big,	\
! 			     (char *) p - 4, & val);		\
!     }								\
!   while (0)
  
  /* Get a double precision float.  */
! #define NEXTDOUBLE(val, p)					\
!   do								\
!     {								\
!       p += 8;							\
!       if (FETCH_DATA (info, p) , 0)				\
! 	return -3;						\
!       floatformat_to_double (& floatformat_ieee_double_big,	\
! 			     (char *) p - 8, & val);		\
!     }								\
!   while (0)
  
  /* Get an extended precision float.  */
! #define NEXTEXTEND(val, p)				\
!   do							\
!     {							\
!       p += 12;						\
!       if (FETCH_DATA (info, p) < 0)			\
! 	return -3;					\
!       floatformat_to_double (& floatformat_m68881_ext,	\
! 			     (char *) p - 12, & val);	\
!     }							\
!   while (0)
  
  /* Need a function to convert from packed to double
     precision.   Actually, it's easier to print a
     packed number than a double anyway, so maybe
     there should be a special case to handle this... */
! #define NEXTPACKED(p, val)			\
!   do						\
!     {						\
!       p += 12;					\
!       if (FETCH_DATA (info, p) < 0)		\
! 	return -3;				\
!       val = 0.0;				\
!     }						\
!   while (0)
! 
  
  /* Maximum length of an instruction.  */
  #define MAXLEN 22
*************** struct private
*** 112,123 ****
    bfd_byte *max_fetched;
    bfd_byte the_buffer[MAXLEN];
    bfd_vma insn_start;
-   jmp_buf bailout;
  };
  
  /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
!    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
!    on error.  */
  #define FETCH_DATA(info, addr) \
    ((addr) <= ((struct private *) (info->private_data))->max_fetched \
     ? 1 : fetch_data ((info), (addr)))
--- 169,181 ----
    bfd_byte *max_fetched;
    bfd_byte the_buffer[MAXLEN];
    bfd_vma insn_start;
  };
  
+ static fprintf_ftype save_printer;
+ static void (* save_print_address) (bfd_vma, struct disassemble_info *);
+ 
  /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
!    to ADDR (exclusive) are valid.  Returns 1 for success, 0 on error.  */
  #define FETCH_DATA(info, addr) \
    ((addr) <= ((struct private *) (info->private_data))->max_fetched \
     ? 1 : fetch_data ((info), (addr)))
*************** fetch_data (struct disassemble_info *inf
*** 136,142 ****
    if (status != 0)
      {
        (*info->memory_error_func) (status, start, info);
!       longjmp (priv->bailout, 1);
      }
    else
      priv->max_fetched = addr;
--- 194,202 ----
    if (status != 0)
      {
        (*info->memory_error_func) (status, start, info);
!       info->fprintf_func = save_printer;
!       info->print_address_func = save_print_address;
!       return 0;
      }
    else
      priv->max_fetched = addr;
*************** dummy_print_address (bfd_vma vma ATTRIBU
*** 161,167 ****
  /* Fetch BITS bits from a position in the instruction specified by CODE.
     CODE is a "place to put an argument", or 'x' for a destination
     that is a general address (mode and register).
!    BUFFER contains the instruction.  */
  
  static int
  fetch_arg (unsigned char *buffer,
--- 221,228 ----
  /* Fetch BITS bits from a position in the instruction specified by CODE.
     CODE is a "place to put an argument", or 'x' for a destination
     that is a general address (mode and register).
!    BUFFER contains the instruction.
!    Returns -1 on failure.  */
  
  static int
  fetch_arg (unsigned char *buffer,
*************** fetch_arg (unsigned char *buffer,
*** 216,279 ****
        break;
  
      case 'k':
!       FETCH_DATA (info, buffer + 3);
        val = (buffer[3] >> 4);
        break;
  
      case 'C':
!       FETCH_DATA (info, buffer + 3);
        val = buffer[3];
        break;
  
      case '1':
!       FETCH_DATA (info, buffer + 3);
        val = (buffer[2] << 8) + buffer[3];
        val >>= 12;
        break;
  
      case '2':
!       FETCH_DATA (info, buffer + 3);
        val = (buffer[2] << 8) + buffer[3];
        val >>= 6;
        break;
  
      case '3':
      case 'j':
!       FETCH_DATA (info, buffer + 3);
        val = (buffer[2] << 8) + buffer[3];
        break;
  
      case '4':
!       FETCH_DATA (info, buffer + 5);
        val = (buffer[4] << 8) + buffer[5];
        val >>= 12;
        break;
  
      case '5':
!       FETCH_DATA (info, buffer + 5);
        val = (buffer[4] << 8) + buffer[5];
        val >>= 6;
        break;
  
      case '6':
!       FETCH_DATA (info, buffer + 5);
        val = (buffer[4] << 8) + buffer[5];
        break;
  
      case '7':
!       FETCH_DATA (info, buffer + 3);
        val = (buffer[2] << 8) + buffer[3];
        val >>= 7;
        break;
  
      case '8':
!       FETCH_DATA (info, buffer + 3);
        val = (buffer[2] << 8) + buffer[3];
        val >>= 10;
        break;
  
      case '9':
!       FETCH_DATA (info, buffer + 3);
        val = (buffer[2] << 8) + buffer[3];
        val >>= 5;
        break;
--- 277,351 ----
        break;
  
      case 'k':
!       if (! FETCH_DATA (info, buffer + 3))
! 	return -1;
        val = (buffer[3] >> 4);
        break;
  
      case 'C':
!       if (! FETCH_DATA (info, buffer + 3))
! 	return -1;
        val = buffer[3];
        break;
  
      case '1':
!       if (! FETCH_DATA (info, buffer + 3))
! 	return -1;
        val = (buffer[2] << 8) + buffer[3];
        val >>= 12;
        break;
  
      case '2':
!       if (! FETCH_DATA (info, buffer + 3))
! 	return -1;
        val = (buffer[2] << 8) + buffer[3];
        val >>= 6;
        break;
  
      case '3':
      case 'j':
!       if (! FETCH_DATA (info, buffer + 3))
! 	return -1;
        val = (buffer[2] << 8) + buffer[3];
        break;
  
      case '4':
!       if (! FETCH_DATA (info, buffer + 5))
! 	return -1;
        val = (buffer[4] << 8) + buffer[5];
        val >>= 12;
        break;
  
      case '5':
!       if (! FETCH_DATA (info, buffer + 5))
! 	return -1;
        val = (buffer[4] << 8) + buffer[5];
        val >>= 6;
        break;
  
      case '6':
!       if (! FETCH_DATA (info, buffer + 5))
! 	return -1;
        val = (buffer[4] << 8) + buffer[5];
        break;
  
      case '7':
!       if (! FETCH_DATA (info, buffer + 3))
! 	return -1;
        val = (buffer[2] << 8) + buffer[3];
        val >>= 7;
        break;
  
      case '8':
!       if (! FETCH_DATA (info, buffer + 3))
! 	return -1;
        val = (buffer[2] << 8) + buffer[3];
        val >>= 10;
        break;
  
      case '9':
!       if (! FETCH_DATA (info, buffer + 3))
! 	return -1;
        val = (buffer[2] << 8) + buffer[3];
        val >>= 5;
        break;
*************** fetch_arg (unsigned char *buffer,
*** 283,289 ****
        break;
  
      case 'E':
!       FETCH_DATA (info, buffer + 3);
        val = (buffer[2] >> 1);
        break;
  
--- 355,362 ----
        break;
  
      case 'E':
!       if (! FETCH_DATA (info, buffer + 3))
! 	return -1;
        val = (buffer[2] >> 1);
        break;
  
*************** print_base (int regno, bfd_vma disp, dis
*** 450,456 ****
  
  /* Print an indexed argument.  The base register is BASEREG (-1 for pc).
     P points to extension word, in buffer.
!    ADDR is the nominal core address of that extension word.  */
  
  static unsigned char *
  print_indexed (int basereg,
--- 523,530 ----
  
  /* Print an indexed argument.  The base register is BASEREG (-1 for pc).
     P points to extension word, in buffer.
!    ADDR is the nominal core address of that extension word.
!    Returns NULL upon error.  */
  
  static unsigned char *
  print_indexed (int basereg,
*************** print_indexed (int basereg,
*** 465,471 ****
    char buf[40];
    char vmabuf[50];
  
!   word = NEXTWORD (p);
  
    /* Generate the text for the index register.
       Where this will be output is not yet determined.  */
--- 539,545 ----
    char buf[40];
    char vmabuf[50];
  
!   NEXTWORD (p, word, NULL);
  
    /* Generate the text for the index register.
       Where this will be output is not yet determined.  */
*************** print_indexed (int basereg,
*** 503,512 ****
    switch ((word >> 4) & 3)
      {
      case 2:
!       base_disp = NEXTWORD (p);
        break;
      case 3:
!       base_disp = NEXTLONG (p);
      }
    if (basereg == -1)
      base_disp += addr;
--- 577,586 ----
    switch ((word >> 4) & 3)
      {
      case 2:
!       NEXTWORD (p, base_disp, NULL);
        break;
      case 3:
!       NEXTLONG (p, base_disp, NULL);
      }
    if (basereg == -1)
      base_disp += addr;
*************** print_indexed (int basereg,
*** 526,535 ****
    switch (word & 3)
      {
      case 2:
!       outer_disp = NEXTWORD (p);
        break;
      case 3:
!       outer_disp = NEXTLONG (p);
      }
  
    print_base (basereg, base_disp, info);
--- 600,609 ----
    switch (word & 3)
      {
      case 2:
!       NEXTWORD (p, outer_disp, NULL);
        break;
      case 3:
!       NEXTLONG (p, outer_disp, NULL);
      }
  
    print_base (basereg, base_disp, info);
*************** print_indexed (int basereg,
*** 547,555 ****
    return p;
  }
  
  /* Returns number of bytes "eaten" by the operand, or
     return -1 if an invalid operand was found, or -2 if
!    an opcode tabe error was found.
     ADDR is the pc for this arg to be relative to.  */
  
  static int
--- 621,638 ----
    return p;
  }
  
+ #define FETCH_ARG(size, val)				\
+   do							\
+     {							\
+       val = fetch_arg (buffer, place, size, info);	\
+       if (val < 0)					\
+ 	return -3;					\
+     }							\
+   while (0)
+ 
  /* Returns number of bytes "eaten" by the operand, or
     return -1 if an invalid operand was found, or -2 if
!    an opcode tabe error was found or -3 to simply abort.
     ADDR is the pc for this arg to be relative to.  */
  
  static int
*************** print_insn_arg (const char *d,
*** 575,597 ****
      case 'c':		/* Cache identifier.  */
        {
          static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
!         val = fetch_arg (buffer, place, 2, info);
!         (*info->fprintf_func) (info->stream, cacheFieldName[val]);
          break;
        }
  
      case 'a':		/* Address register indirect only. Cf. case '+'.  */
        {
!         (*info->fprintf_func)
! 	  (info->stream,
! 	   "%s@",
! 	   reg_names[fetch_arg (buffer, place, 3, info) + 8]);
          break;
        }
  
      case '_':		/* 32-bit absolute address for move16.  */
        {
!         uval = NEXTULONG (p);
  	(*info->print_address_func) (uval, info);
          break;
        }
--- 658,678 ----
      case 'c':		/* Cache identifier.  */
        {
          static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
!         FETCH_ARG (2, val);
! 	(*info->fprintf_func) (info->stream, cacheFieldName[val]);
          break;
        }
  
      case 'a':		/* Address register indirect only. Cf. case '+'.  */
        {
! 	FETCH_ARG (3, val);
! 	(*info->fprintf_func) (info->stream, "%s@", reg_names[val + 8]);
          break;
        }
  
      case '_':		/* 32-bit absolute address for move16.  */
        {
!         NEXTULONG (p, uval);
  	(*info->print_address_func) (uval, info);
          break;
        }
*************** print_insn_arg (const char *d,
*** 643,649 ****
  	     /* Fido added these.  */
               {"%cac", 0xffe}, {"%mbo", 0xfff}};
  
! 	val = fetch_arg (buffer, place, 12, info);
  	for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
  	  if (names[regno].value == val)
  	    {
--- 724,730 ----
  	     /* Fido added these.  */
               {"%cac", 0xffe}, {"%mbo", 0xfff}};
  
! 	FETCH_ARG (12, val);
  	for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
  	  if (names[regno].value == val)
  	    {
*************** print_insn_arg (const char *d,
*** 656,662 ****
        break;
  
      case 'Q':
!       val = fetch_arg (buffer, place, 3, info);
        /* 0 means 8, except for the bkpt instruction... */
        if (val == 0 && d[1] != 's')
  	val = 8;
--- 737,743 ----
        break;
  
      case 'Q':
!       FETCH_ARG (3, val);
        /* 0 means 8, except for the bkpt instruction... */
        if (val == 0 && d[1] != 's')
  	val = 8;
*************** print_insn_arg (const char *d,
*** 664,670 ****
        break;
  
      case 'x':
!       val = fetch_arg (buffer, place, 3, info);
        /* 0 means -1.  */
        if (val == 0)
  	val = -1;
--- 745,751 ----
        break;
  
      case 'x':
!       FETCH_ARG (3, val);
        /* 0 means -1.  */
        if (val == 0)
  	val = -1;
*************** print_insn_arg (const char *d,
*** 672,683 ****
        break;
  
      case 'j':
!       val = fetch_arg (buffer, place, 3, info);
        (*info->fprintf_func) (info->stream, "#%d", val+1);
        break;
  
      case 'K':
!       val = fetch_arg (buffer, place, 9, info);
        (*info->fprintf_func) (info->stream, "#%d", val);
        break;
  
--- 753,764 ----
        break;
  
      case 'j':
!       FETCH_ARG (3, val);
        (*info->fprintf_func) (info->stream, "#%d", val+1);
        break;
  
      case 'K':
!       FETCH_ARG (9, val);
        (*info->fprintf_func) (info->stream, "#%d", val);
        break;
  
*************** print_insn_arg (const char *d,
*** 685,696 ****
        if (place == 'h')
  	{
  	  static char *const scalefactor_name[] = { "<<", ">>" };
! 	  val = fetch_arg (buffer, place, 1, info);
  	  (*info->fprintf_func) (info->stream, scalefactor_name[val]);
  	}
        else
  	{
! 	  val = fetch_arg (buffer, place, 8, info);
  	  if (val & 0x80)
  	    val = val - 0x100;
  	  (*info->fprintf_func) (info->stream, "#%d", val);
--- 766,778 ----
        if (place == 'h')
  	{
  	  static char *const scalefactor_name[] = { "<<", ">>" };
! 
! 	  FETCH_ARG (1, val);
  	  (*info->fprintf_func) (info->stream, scalefactor_name[val]);
  	}
        else
  	{
! 	  FETCH_ARG (8, val);
  	  if (val & 0x80)
  	    val = val - 0x100;
  	  (*info->fprintf_func) (info->stream, "#%d", val);
*************** print_insn_arg (const char *d,
*** 698,726 ****
        break;
  
      case 'T':
!       val = fetch_arg (buffer, place, 4, info);
        (*info->fprintf_func) (info->stream, "#%d", val);
        break;
  
      case 'D':
!       (*info->fprintf_func) (info->stream, "%s",
! 			     reg_names[fetch_arg (buffer, place, 3, info)]);
        break;
  
      case 'A':
!       (*info->fprintf_func)
! 	(info->stream, "%s",
! 	 reg_names[fetch_arg (buffer, place, 3, info) + 010]);
        break;
  
      case 'R':
!       (*info->fprintf_func)
! 	(info->stream, "%s",
! 	 reg_names[fetch_arg (buffer, place, 4, info)]);
        break;
  
      case 'r':
!       regno = fetch_arg (buffer, place, 4, info);
        if (regno > 7)
  	(*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
        else
--- 780,806 ----
        break;
  
      case 'T':
!       FETCH_ARG (4, val);
        (*info->fprintf_func) (info->stream, "#%d", val);
        break;
  
      case 'D':
!       FETCH_ARG (3, val);
!       (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
        break;
  
      case 'A':
!       FETCH_ARG (3, val);
!       (*info->fprintf_func) (info->stream, "%s", reg_names[val + 010]);
        break;
  
      case 'R':
!       FETCH_ARG (4, val);
!       (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
        break;
  
      case 'r':
!       FETCH_ARG (4, regno);
        if (regno > 7)
  	(*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
        else
*************** print_insn_arg (const char *d,
*** 728,740 ****
        break;
  
      case 'F':
!       (*info->fprintf_func)
! 	(info->stream, "%%fp%d",
! 	 fetch_arg (buffer, place, 3, info));
        break;
  
      case 'O':
!       val = fetch_arg (buffer, place, 6, info);
        if (val & 0x20)
  	(*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]);
        else
--- 808,819 ----
        break;
  
      case 'F':
!       FETCH_ARG (3, val);
!       (*info->fprintf_func) (info->stream, "%%fp%d", val);
        break;
  
      case 'O':
!       FETCH_ARG (6, val);
        if (val & 0x20)
  	(*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]);
        else
*************** print_insn_arg (const char *d,
*** 742,819 ****
        break;
  
      case '+':
!       (*info->fprintf_func)
! 	(info->stream, "%s@+",
! 	 reg_names[fetch_arg (buffer, place, 3, info) + 8]);
        break;
  
      case '-':
!       (*info->fprintf_func)
! 	(info->stream, "%s@-",
! 	 reg_names[fetch_arg (buffer, place, 3, info) + 8]);
        break;
  
      case 'k':
        if (place == 'k')
! 	(*info->fprintf_func)
! 	  (info->stream, "{%s}",
! 	   reg_names[fetch_arg (buffer, place, 3, info)]);
        else if (place == 'C')
  	{
! 	  val = fetch_arg (buffer, place, 7, info);
  	  if (val > 63)		/* This is a signed constant.  */
  	    val -= 128;
  	  (*info->fprintf_func) (info->stream, "{#%d}", val);
  	}
        else
! 	return -2;
        break;
  
      case '#':
      case '^':
        p1 = buffer + (*d == '#' ? 2 : 4);
        if (place == 's')
! 	val = fetch_arg (buffer, place, 4, info);
        else if (place == 'C')
! 	val = fetch_arg (buffer, place, 7, info);
        else if (place == '8')
! 	val = fetch_arg (buffer, place, 3, info);
        else if (place == '3')
! 	val = fetch_arg (buffer, place, 8, info);
        else if (place == 'b')
! 	val = NEXTBYTE (p1);
        else if (place == 'w' || place == 'W')
! 	val = NEXTWORD (p1);
        else if (place == 'l')
! 	val = NEXTLONG (p1);
        else
  	return -2;
        (*info->fprintf_func) (info->stream, "#%d", val);
        break;
  
      case 'B':
        if (place == 'b')
! 	disp = NEXTBYTE (p);
        else if (place == 'B')
  	disp = COERCE_SIGNED_CHAR (buffer[1]);
        else if (place == 'w' || place == 'W')
! 	disp = NEXTWORD (p);
        else if (place == 'l' || place == 'L' || place == 'C')
! 	disp = NEXTLONG (p);
        else if (place == 'g')
  	{
! 	  disp = NEXTBYTE (buffer);
  	  if (disp == 0)
! 	    disp = NEXTWORD (p);
  	  else if (disp == -1)
! 	    disp = NEXTLONG (p);
  	}
        else if (place == 'c')
  	{
  	  if (buffer[1] & 0x40)		/* If bit six is one, long offset.  */
! 	    disp = NEXTLONG (p);
  	  else
! 	    disp = NEXTWORD (p);
  	}
        else
  	return -2;
--- 821,898 ----
        break;
  
      case '+':
!       FETCH_ARG (3, val);
!       (*info->fprintf_func) (info->stream, "%s@+", reg_names[val + 8]);
        break;
  
      case '-':
!       FETCH_ARG (3, val);
!       (*info->fprintf_func) (info->stream, "%s@-", reg_names[val + 8]);
        break;
  
      case 'k':
        if (place == 'k')
! 	{
! 	  FETCH_ARG (3, val);
! 	  (*info->fprintf_func) (info->stream, "{%s}", reg_names[val]);
! 	}
        else if (place == 'C')
  	{
! 	  FETCH_ARG (7, val);
  	  if (val > 63)		/* This is a signed constant.  */
  	    val -= 128;
  	  (*info->fprintf_func) (info->stream, "{#%d}", val);
  	}
        else
! 	return -1;
        break;
  
      case '#':
      case '^':
        p1 = buffer + (*d == '#' ? 2 : 4);
        if (place == 's')
! 	FETCH_ARG (4, val);
        else if (place == 'C')
! 	FETCH_ARG (7, val);
        else if (place == '8')
! 	FETCH_ARG (3, val);
        else if (place == '3')
! 	FETCH_ARG (8, val);
        else if (place == 'b')
! 	NEXTBYTE (p1, val);
        else if (place == 'w' || place == 'W')
! 	NEXTWORD (p1, val, -3);
        else if (place == 'l')
! 	NEXTLONG (p1, val, -3);
        else
  	return -2;
+ 
        (*info->fprintf_func) (info->stream, "#%d", val);
        break;
  
      case 'B':
        if (place == 'b')
! 	NEXTBYTE (p, disp);
        else if (place == 'B')
  	disp = COERCE_SIGNED_CHAR (buffer[1]);
        else if (place == 'w' || place == 'W')
! 	NEXTWORD (p, disp, -3);
        else if (place == 'l' || place == 'L' || place == 'C')
! 	NEXTLONG (p, disp, -3);
        else if (place == 'g')
  	{
! 	  NEXTBYTE (buffer, disp);
  	  if (disp == 0)
! 	    NEXTWORD (p, disp, -3);
  	  else if (disp == -1)
! 	    NEXTLONG (p, disp, -3);
  	}
        else if (place == 'c')
  	{
  	  if (buffer[1] & 0x40)		/* If bit six is one, long offset.  */
! 	    NEXTLONG (p, disp, -3);
  	  else
! 	    NEXTWORD (p, disp, -3);
  	}
        else
  	return -2;
*************** print_insn_arg (const char *d,
*** 822,850 ****
        break;
  
      case 'd':
!       val = NEXTWORD (p);
!       (*info->fprintf_func)
! 	(info->stream, "%s@(%d)",
! 	 reg_names[fetch_arg (buffer, place, 3, info) + 8], val);
!       break;
  
      case 's':
!       (*info->fprintf_func) (info->stream, "%s",
! 			     fpcr_names[fetch_arg (buffer, place, 3, info)]);
        break;
  
      case 'e':
!       val = fetch_arg(buffer, place, 2, info);
        (*info->fprintf_func) (info->stream, "%%acc%d", val);
        break;
  
      case 'g':
!       val = fetch_arg(buffer, place, 1, info);
!       (*info->fprintf_func) (info->stream, "%%accext%s", val==0 ? "01" : "23");
        break;
  
      case 'i':
!       val = fetch_arg(buffer, place, 2, info);
        if (val == 1)
  	(*info->fprintf_func) (info->stream, "<<");
        else if (val == 3)
--- 901,932 ----
        break;
  
      case 'd':
!       {
! 	int val1;
! 
! 	NEXTWORD (p, val, -3);
! 	FETCH_ARG (3, val1);
! 	(*info->fprintf_func) (info->stream, "%s@(%d)", reg_names[val1 + 8], val);
! 	break;
!       }
  
      case 's':
!       FETCH_ARG (3, val);
!       (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]);
        break;
  
      case 'e':
!       FETCH_ARG (2, val);
        (*info->fprintf_func) (info->stream, "%%acc%d", val);
        break;
  
      case 'g':
!       FETCH_ARG (1, val);
!       (*info->fprintf_func) (info->stream, "%%accext%s", val == 0 ? "01" : "23");
        break;
  
      case 'i':
!       FETCH_ARG (2, val);
        if (val == 1)
  	(*info->fprintf_func) (info->stream, "<<");
        else if (val == 3)
*************** print_insn_arg (const char *d,
*** 856,862 ****
      case 'I':
        /* Get coprocessor ID... */
        val = fetch_arg (buffer, 'd', 3, info);
! 
        if (val != 1)				/* Unusual coprocessor ID?  */
  	(*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
        break;
--- 938,945 ----
      case 'I':
        /* Get coprocessor ID... */
        val = fetch_arg (buffer, 'd', 3, info);
!       if (val < 0)
! 	return -3;
        if (val != 1)				/* Unusual coprocessor ID?  */
  	(*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
        break;
*************** print_insn_arg (const char *d,
*** 888,897 ****
        if (place == 'd')
  	{
  	  val = fetch_arg (buffer, 'x', 6, info);
  	  val = ((val & 7) << 3) + ((val >> 3) & 7);
  	}
        else
! 	val = fetch_arg (buffer, 's', 6, info);
  
        /* If the <ea> is invalid for *d, then reject this match.  */
        if (!m68k_valid_ea (*d, val))
--- 971,986 ----
        if (place == 'd')
  	{
  	  val = fetch_arg (buffer, 'x', 6, info);
+ 	  if (val < 0)
+ 	    return -3;
  	  val = ((val & 7) << 3) + ((val >> 3) & 7);
  	}
        else
! 	{
! 	  val = fetch_arg (buffer, 's', 6, info);
! 	  if (val < 0)
! 	    return -3;
! 	}
  
        /* If the <ea> is invalid for *d, then reject this match.  */
        if (!m68k_valid_ea (*d, val))
*************** print_insn_arg (const char *d,
*** 923,951 ****
  	  break;
  
  	case 5:
! 	  val = NEXTWORD (p);
  	  (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
  	  break;
  
  	case 6:
  	  p = print_indexed (regno, p, addr, info);
  	  break;
  
  	case 7:
  	  switch (val & 7)
  	    {
  	    case 0:
! 	      val = NEXTWORD (p);
  	      (*info->print_address_func) (val, info);
  	      break;
  
  	    case 1:
! 	      uval = NEXTULONG (p);
  	      (*info->print_address_func) (uval, info);
  	      break;
  
  	    case 2:
! 	      val = NEXTWORD (p);
  	      (*info->fprintf_func) (info->stream, "%%pc@(");
  	      (*info->print_address_func) (addr + val, info);
  	      (*info->fprintf_func) (info->stream, ")");
--- 1012,1042 ----
  	  break;
  
  	case 5:
! 	  NEXTWORD (p, val, -3);
  	  (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
  	  break;
  
  	case 6:
  	  p = print_indexed (regno, p, addr, info);
+ 	  if (p == NULL)
+ 	    return -3;
  	  break;
  
  	case 7:
  	  switch (val & 7)
  	    {
  	    case 0:
! 	      NEXTWORD (p, val, -3);
  	      (*info->print_address_func) (val, info);
  	      break;
  
  	    case 1:
! 	      NEXTULONG (p, uval);
  	      (*info->print_address_func) (uval, info);
  	      break;
  
  	    case 2:
! 	      NEXTWORD (p, val, -3);
  	      (*info->fprintf_func) (info->stream, "%%pc@(");
  	      (*info->print_address_func) (addr + val, info);
  	      (*info->fprintf_func) (info->stream, ")");
*************** print_insn_arg (const char *d,
*** 953,958 ****
--- 1044,1051 ----
  
  	    case 3:
  	      p = print_indexed (-1, p, addr, info);
+ 	      if (p == NULL)
+ 		return -3;
  	      break;
  
  	    case 4:
*************** print_insn_arg (const char *d,
*** 960,976 ****
  	      switch (place)
  	      {
  		case 'b':
! 		  val = NEXTBYTE (p);
  		  flt_p = 0;
  		  break;
  
  		case 'w':
! 		  val = NEXTWORD (p);
  		  flt_p = 0;
  		  break;
  
  		case 'l':
! 		  val = NEXTLONG (p);
  		  flt_p = 0;
  		  break;
  
--- 1053,1069 ----
  	      switch (place)
  	      {
  		case 'b':
! 		  NEXTBYTE (p, val);
  		  flt_p = 0;
  		  break;
  
  		case 'w':
! 		  NEXTWORD (p, val, -3);
  		  flt_p = 0;
  		  break;
  
  		case 'l':
! 		  NEXTLONG (p, val, -3);
  		  flt_p = 0;
  		  break;
  
*************** print_insn_arg (const char *d,
*** 987,993 ****
  		  break;
  
  		case 'p':
! 		  flval = NEXTPACKED (p);
  		  break;
  
  		default:
--- 1080,1086 ----
  		  break;
  
  		case 'p':
! 		  NEXTPACKED (p, flval);
  		  break;
  
  		default:
*************** print_insn_arg (const char *d,
*** 1009,1015 ****
  	 mask bit and if set, add a '&' to the arg.  */
        if (place == '/')
  	{
! 	  val = fetch_arg (buffer, place, 1, info);
  	  if (val)
  	    info->fprintf_func (info->stream, "&");
  	}
--- 1102,1108 ----
  	 mask bit and if set, add a '&' to the arg.  */
        if (place == '/')
  	{
! 	  FETCH_ARG (1, val);
  	  if (val)
  	    info->fprintf_func (info->stream, "&");
  	}
*************** print_insn_arg (const char *d,
*** 1021,1027 ****
  	  {
  	    char doneany;
  	    p1 = buffer + 2;
! 	    val = NEXTWORD (p1);
  	    /* Move the pointer ahead if this point is farther ahead
  	       than the last.  */
  	    p = p1 > p ? p1 : p;
--- 1114,1120 ----
  	  {
  	    char doneany;
  	    p1 = buffer + 2;
! 	    NEXTWORD (p1, val, -3);
  	    /* Move the pointer ahead if this point is farther ahead
  	       than the last.  */
  	    p = p1 > p ? p1 : p;
*************** print_insn_arg (const char *d,
*** 1062,1068 ****
  	  {
  	    /* `fmovem' insn.  */
  	    char doneany;
! 	    val = fetch_arg (buffer, place, 8, info);
  	    if (val == 0)
  	      {
  		(*info->fprintf_func) (info->stream, "#0");
--- 1155,1162 ----
  	  {
  	    /* `fmovem' insn.  */
  	    char doneany;
! 
! 	    FETCH_ARG (8, val);
  	    if (val == 0)
  	      {
  		(*info->fprintf_func) (info->stream, "#0");
*************** print_insn_arg (const char *d,
*** 1096,1105 ****
  	  }
  	else if (place == '8')
  	  {
  	    /* fmoveml for FP status registers.  */
! 	    (*info->fprintf_func) (info->stream, "%s",
! 				   fpcr_names[fetch_arg (buffer, place, 3,
! 							 info)]);
  	  }
  	else
  	  return -2;
--- 1190,1198 ----
  	  }
  	else if (place == '8')
  	  {
+ 	    FETCH_ARG (3, val);
  	    /* fmoveml for FP status registers.  */
! 	    (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]);
  	  }
  	else
  	  return -2;
*************** print_insn_arg (const char *d,
*** 1115,1123 ****
      case '2':
      case '3':
        {
! 	int val = fetch_arg (buffer, place, 5, info);
  	char *name = 0;
  
  	switch (val)
  	  {
  	  case 2: name = "%tt0"; break;
--- 1208,1217 ----
      case '2':
      case '3':
        {
! 	int val;
  	char *name = 0;
  
+ 	FETCH_ARG (5, val);
  	switch (val)
  	  {
  	  case 2: name = "%tt0"; break;
*************** print_insn_arg (const char *d,
*** 1152,1159 ****
  
      case 'f':
        {
! 	int fc = fetch_arg (buffer, place, 5, info);
  
  	if (fc == 1)
  	  (*info->fprintf_func) (info->stream, "%%dfc");
  	else if (fc == 0)
--- 1246,1254 ----
  
      case 'f':
        {
! 	int fc;
  
+ 	FETCH_ARG (5, fc);
  	if (fc == 1)
  	  (*info->fprintf_func) (info->stream, "%%dfc");
  	else if (fc == 0)
*************** print_insn_arg (const char *d,
*** 1170,1177 ****
  
      case 't':
        {
! 	int level = fetch_arg (buffer, place, 3, info);
  
  	(*info->fprintf_func) (info->stream, "%d", level);
        }
        break;
--- 1265,1273 ----
  
      case 't':
        {
! 	int level;
  
+ 	FETCH_ARG (3, level);
  	(*info->fprintf_func) (info->stream, "%d", level);
        }
        break;
*************** print_insn_arg (const char *d,
*** 1179,1186 ****
      case 'u':
        {
  	short is_upper = 0;
! 	int reg = fetch_arg (buffer, place, 5, info);
  
  	if (reg & 0x10)
  	  {
  	    is_upper = 1;
--- 1275,1283 ----
      case 'u':
        {
  	short is_upper = 0;
! 	int reg;
  
+ 	FETCH_ARG (5, reg);
  	if (reg & 0x10)
  	  {
  	    is_upper = 1;
*************** match_insn_m68k (bfd_vma memaddr,
*** 1309,1314 ****
--- 1406,1413 ----
  	  info->print_address_func = save_print_address;
  	  return 0;
  	}
+       else if (eaten == -3)
+ 	return 0;
        else
  	{
  	  /* We must restore the print functions before trying to print the
*************** match_insn_m68k (bfd_vma memaddr,
*** 1318,1324 ****
  	  info->fprintf_func (info->stream,
  			      /* xgettext:c-format */
  			      _("<internal error in opcode table: %s %s>\n"),
! 			      best->name,  best->args);
  	  return 2;
  	}
      }
--- 1417,1423 ----
  	  info->fprintf_func (info->stream,
  			      /* xgettext:c-format */
  			      _("<internal error in opcode table: %s %s>\n"),
! 			      best->name, best->args);
  	  return 2;
  	}
      }
*************** m68k_scan_mask (bfd_vma memaddr, disasse
*** 1439,1444 ****
--- 1538,1545 ----
  		  if (d[0] == 's' && d[1] == '8')
  		    {
  		      val = fetch_arg (buffer, d[1], 3, info);
+ 		      if (val < 0)
+ 			return 0;
  		      if ((val & (val - 1)) != 0)
  			break;
  		    }
*************** m68k_scan_mask (bfd_vma memaddr, disasse
*** 1473,1478 ****
--- 1574,1581 ----
  int
  print_insn_m68k (bfd_vma memaddr, disassemble_info *info)
  {
+   static fprintf_ftype save_printer;
+   static void (* save_print_address) (bfd_vma, struct disassemble_info *);
    unsigned int arch_mask;
    struct private priv;
    int val;
*************** print_insn_m68k (bfd_vma memaddr, disass
*** 1481,1491 ****
  
    /* Save these printing functions in case we need to restore them
       later.  */
!   fprintf_ftype save_printer = info->fprintf_func;
!   void (* save_print_address) (bfd_vma, struct disassemble_info *)
!     = info->print_address_func;
  
!   info->private_data = (PTR) &priv;
    /* Tell objdump to use two bytes per chunk
       and six bytes per line for displaying raw data.  */
    info->bytes_per_chunk = 2;
--- 1584,1593 ----
  
    /* Save these printing functions in case we need to restore them
       later.  */
!   save_printer = info->fprintf_func;
!   save_print_address = info->print_address_func;
  
!   info->private_data = & priv;
    /* Tell objdump to use two bytes per chunk
       and six bytes per line for displaying raw data.  */
    info->bytes_per_chunk = 2;
*************** print_insn_m68k (bfd_vma memaddr, disass
*** 1494,1542 ****
    priv.max_fetched = priv.the_buffer;
    priv.insn_start = memaddr;
  
-   if (setjmp (priv.bailout) != 0)
-     {
-       /* longjmp may be called while these printing functions are
- 	 temporarily replaced with dummy functions.  Restore them
- 	 before we leave.
- 
- 	 Admittedly, this save-and-restore operation is somewhat ugly
- 	 in that we are exposing the fact that match_insn_m68k
- 	 temporarily replaces insn->fprintf_func and
- 	 insn->print_address_func.  Perhaps, a real fix is to report a
- 	 FETCH_DATA failure with a return value of some sort, without
- 	 using setjmp/longjmp.  A better fix may be to teach the m68k
- 	 disassembler do its job without temporarily replacing
- 	 insn->fprintf_func and insn->print_address_func, but that's a
- 	 task for another day.  */
-       info->fprintf_func = save_printer;
-       info->print_address_func = save_print_address;
- 
-       /* Error return.  */
-       return -1;
-     }
- 
    arch_mask = bfd_m68k_mach_to_features (info->mach);
    if (!arch_mask)
      {
        /* First try printing an m680x0 instruction.  Try printing a Coldfire
  	 one if that fails.  */
        val = m68k_scan_mask (memaddr, info, m68k_mask);
!       if (val)
! 	return val;
! 
!       val = m68k_scan_mask (memaddr, info, mcf_mask);
!       if (val)
! 	return val;
      }
    else
      {
        val = m68k_scan_mask (memaddr, info, arch_mask);
-       if (val)
- 	return val;
      }
  
!   /* Handle undefined instructions.  */
!   info->fprintf_func (info->stream, "0%o", (buffer[0] << 8) + buffer[1]);
!   return 2;
  }
--- 1596,1622 ----
    priv.max_fetched = priv.the_buffer;
    priv.insn_start = memaddr;
  
    arch_mask = bfd_m68k_mach_to_features (info->mach);
    if (!arch_mask)
      {
        /* First try printing an m680x0 instruction.  Try printing a Coldfire
  	 one if that fails.  */
        val = m68k_scan_mask (memaddr, info, m68k_mask);
!       if (val == 0)
! 	val = m68k_scan_mask (memaddr, info, mcf_mask);
      }
    else
      {
        val = m68k_scan_mask (memaddr, info, arch_mask);
      }
  
!   if (val == 0)
!     /* Handle undefined instructions.  */
!     info->fprintf_func (info->stream, "0%o", (buffer[0] << 8) + buffer[1]);
! 
!   /* Restore print functions.  */
!   info->fprintf_func = save_printer;
!   info->print_address_func = save_print_address;
! 
!   return val ? val : 2;
  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]