2007-11-15 Markus Deuling <deuling@de.ibm.com>
[deliverable/binutils-gdb.git] / gdb / stabsread.c
index d4d5c3599fd5ba43fb9e7c30e1303b4c74112933..fb031c71116ffe25838a9da9052c5eb089c96e13 100644 (file)
@@ -8,7 +8,7 @@
 
    This program 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
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -17,9 +17,7 @@
    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 program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Support routines for reading and decoding debugging information in
    the "stabs" format.  This format is used with many systems that use
@@ -47,6 +45,7 @@
 #include "doublest.h"
 #include "cp-abi.h"
 #include "cp-support.h"
+#include "gdb_assert.h"
 
 #include <ctype.h>
 
@@ -162,15 +161,6 @@ void stabsread_clear_cache (void);
 static const char vptr_name[] = "_vptr$";
 static const char vb_name[] = "_vb$";
 
-/* Define this as 1 if a pcc declaration of a char or short argument
-   gives the correct address.  Otherwise assume pcc gives the
-   address of the corresponding int, which is not the same on a
-   big-endian machine.  */
-
-#if !defined (BELIEVE_PCC_PROMOTION)
-#define BELIEVE_PCC_PROMOTION 0
-#endif
-
 static void
 invalid_cpp_abbrev_complaint (const char *arg1)
 {
@@ -292,15 +282,12 @@ dbx_lookup_type (int typenums[2])
 
       if (real_filenum >= N_HEADER_FILES (current_objfile))
        {
-         struct type *temp_type;
-         struct type **temp_type_p;
+         static struct type **temp_type_p;
 
          warning (_("GDB internal error: bad real_filenum"));
 
        error_return:
-         temp_type = init_type (TYPE_CODE_ERROR, 0, 0, NULL, NULL);
-         temp_type_p = (struct type **) xmalloc (sizeof (struct type *));
-         *temp_type_p = temp_type;
+         temp_type_p = &builtin_type_error;
          return temp_type_p;
        }
 
@@ -373,6 +360,7 @@ patch_block_stabs (struct pending *symbols, struct pending_stabs *stabs,
        {
          name = stabs->stab[ii];
          pp = (char *) strchr (name, ':');
+         gdb_assert (pp);      /* Must find a ':' or game's over.  */
          while (pp[1] == ':')
            {
              pp += 2;
@@ -676,11 +664,11 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
          /* This was an anonymous type that was never fixed up.  */
          goto normal;
 
-#ifdef STATIC_TRANSFORM_NAME
        case 'X':
          /* SunPRO (3.0 at least) static variable encoding.  */
-         goto normal;
-#endif
+         if (gdbarch_static_transform_name_p (current_gdbarch))
+           goto normal;
+         /* ... fall through ... */
 
        default:
          complaint (&symfile_complaints, _("Unknown C++ symbol name `%s'"),
@@ -971,10 +959,11 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
        }
 
       /* If it's gcc-compiled, if it says `short', believe it.  */
-      if (processing_gcc_compilation || BELIEVE_PCC_PROMOTION)
+      if (processing_gcc_compilation
+         || gdbarch_believe_pcc_promotion (current_gdbarch))
        break;
 
-      if (!BELIEVE_PCC_PROMOTION)
+      if (!gdbarch_believe_pcc_promotion (current_gdbarch))
        {
          /* This is the signed type which arguments get promoted to.  */
          static struct type *pcc_promotion_type;
@@ -1107,18 +1096,21 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
       SYMBOL_CLASS (sym) = LOC_STATIC;
       SYMBOL_VALUE_ADDRESS (sym) = valu;
-#ifdef STATIC_TRANSFORM_NAME
-      if (IS_STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym)))
+      if (gdbarch_static_transform_name_p (current_gdbarch)
+         && gdbarch_static_transform_name (current_gdbarch,
+                                           DEPRECATED_SYMBOL_NAME (sym))
+            != DEPRECATED_SYMBOL_NAME (sym))
        {
          struct minimal_symbol *msym;
          msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym), NULL, objfile);
          if (msym != NULL)
            {
-             DEPRECATED_SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym));
+             DEPRECATED_SYMBOL_NAME (sym) = gdbarch_static_transform_name
+                                              (current_gdbarch,        
+                                               DEPRECATED_SYMBOL_NAME (sym));
              SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym);
            }
        }
-#endif
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       add_symbol_to_list (sym, &file_symbols);
       break;
@@ -1287,18 +1279,21 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
       SYMBOL_TYPE (sym) = read_type (&p, objfile);
       SYMBOL_CLASS (sym) = LOC_STATIC;
       SYMBOL_VALUE_ADDRESS (sym) = valu;
-#ifdef STATIC_TRANSFORM_NAME
-      if (IS_STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym)))
+      if (gdbarch_static_transform_name_p (current_gdbarch)
+         && gdbarch_static_transform_name (current_gdbarch,
+                                           DEPRECATED_SYMBOL_NAME (sym))
+            != DEPRECATED_SYMBOL_NAME (sym))
        {
          struct minimal_symbol *msym;
          msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym), NULL, objfile);
          if (msym != NULL)
            {
-             DEPRECATED_SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (DEPRECATED_SYMBOL_NAME (sym));
+             DEPRECATED_SYMBOL_NAME (sym) = gdbarch_static_transform_name
+                                              (current_gdbarch,        
+                                               DEPRECATED_SYMBOL_NAME (sym));
              SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym);
            }
        }
-#endif
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
        add_symbol_to_list (sym, &local_symbols);
       break;
@@ -1927,7 +1922,7 @@ again:
       if (is_string)
        TYPE_CODE (type) = TYPE_CODE_STRING;
       if (is_vector)
-       TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
+       make_vector_type (type);
       break;
 
     case 'S':                  /* Set or bitstring  type */
@@ -3714,15 +3709,14 @@ read_huge_number (char **pp, int end, int *bits, int twos_complement_bits)
 {
   char *p = *pp;
   int sign = 1;
-  int sign_bit;
+  int sign_bit = 0;
   long n = 0;
-  long sn = 0;
   int radix = 10;
   char overflow = 0;
   int nbits = 0;
   int c;
   long upper_limit;
-  int twos_complement_representation = radix == 8 && twos_complement_bits > 0;
+  int twos_complement_representation = 0;
 
   if (*p == '-')
     {
@@ -3738,6 +3732,37 @@ read_huge_number (char **pp, int end, int *bits, int twos_complement_bits)
       p++;
     }
 
+  /* Skip extra zeros.  */
+  while (*p == '0')
+    p++;
+
+  if (sign > 0 && radix == 8 && twos_complement_bits > 0)
+    {
+      /* Octal, possibly signed.  Check if we have enough chars for a
+        negative number.  */
+
+      size_t len;
+      char *p1 = p;
+      while ((c = *p1) >= '0' && c < '8')
+       p1++;
+
+      len = p1 - p;
+      if (len > twos_complement_bits / 3
+         || (twos_complement_bits % 3 == 0 && len == twos_complement_bits / 3))
+       {
+         /* Ok, we have enough characters for a signed value, check
+            for signness by testing if the sign bit is set.  */
+         sign_bit = (twos_complement_bits % 3 + 2) % 3;
+         c = *p - '0';
+         if (c & (1 << sign_bit))
+           {
+             /* Definitely signed.  */
+             twos_complement_representation = 1;
+             sign = -1;
+           }
+       }
+    }
+
   upper_limit = LONG_MAX / radix;
 
   while ((c = *p++) >= '0' && c < ('0' + radix))
@@ -3746,23 +3771,18 @@ read_huge_number (char **pp, int end, int *bits, int twos_complement_bits)
         {
           if (twos_complement_representation)
             {
-              /* Octal, signed, twos complement representation. In this case,
-                 sn is the signed value, n is the corresponding absolute
-                 value. signed_bit is the position of the sign bit in the
-                 first three bits.  */
-              if (sn == 0)
-                {
-                  sign_bit = (twos_complement_bits % 3 + 2) % 3;
-                  sn = c - '0' - ((2 * (c - '0')) | (2 << sign_bit));
-                }
+             /* Octal, signed, twos complement representation.  In
+                this case, n is the corresponding absolute value.  */
+             if (n == 0)
+               {
+                 long sn = c - '0' - ((2 * (c - '0')) | (2 << sign_bit));
+                 n = -sn;
+               }
               else
                 {
-                  sn *= radix;
-                  sn += c - '0';
+                  n *= radix;
+                  n -= c - '0';
                 }
-
-              if (sn < 0)
-                n = -sn;
             }
           else
             {
@@ -3806,6 +3826,15 @@ read_huge_number (char **pp, int end, int *bits, int twos_complement_bits)
   else
     --p;
 
+  if (radix == 8 && twos_complement_bits > 0 && nbits > twos_complement_bits)
+    {
+      /* We were supposed to parse a number with maximum
+        TWOS_COMPLEMENT_BITS bits, but something went wrong.  */
+      if (bits != NULL)
+       *bits = -1;
+      return 0;
+    }
+
   *pp = p;
   if (overflow)
     {
@@ -3819,8 +3848,9 @@ read_huge_number (char **pp, int end, int *bits, int twos_complement_bits)
        }
 
       /* -0x7f is the same as 0x80.  So deal with it by adding one to
-         the number of bits.  */
-      if (sign == -1)
+         the number of bits.  Two's complement represention octals
+         can't have a '-' in front.  */
+      if (sign == -1 && !twos_complement_representation)
        ++nbits;
       if (bits)
        *bits = nbits;
@@ -3829,10 +3859,7 @@ read_huge_number (char **pp, int end, int *bits, int twos_complement_bits)
     {
       if (bits)
        *bits = 0;
-      if (twos_complement_representation)
-        return sn;
-      else
-        return n * sign;
+      return n * sign;
     }
   /* It's *BITS which has the interesting information.  */
   return 0;
@@ -3957,15 +3984,20 @@ read_range_type (char **pp, int typenums[2], int type_size,
        return float_type;
     }
 
-  /* If the upper bound is -1, it must really be an unsigned int.  */
+  /* If the upper bound is -1, it must really be an unsigned integral.  */
 
   else if (n2 == 0 && n3 == -1)
     {
-      /* It is unsigned int or unsigned long.  */
-      /* GCC 2.3.3 uses this for long long too, but that is just a GDB 3.5
-         compatibility hack.  */
-      return init_type (TYPE_CODE_INT, 
-                       gdbarch_int_bit (current_gdbarch) / TARGET_CHAR_BIT,
+      int bits = type_size;
+      if (bits <= 0)
+       {
+         /* We don't know its size.  It is unsigned int or unsigned
+            long.  GCC 2.3.3 uses this for long long too, but that is
+            just a GDB 3.5 compatibility hack.  */
+         bits = gdbarch_int_bit (current_gdbarch);
+       }
+
+      return init_type (TYPE_CODE_INT, bits / TARGET_CHAR_BIT,
                        TYPE_FLAG_UNSIGNED, NULL, objfile);
     }
 
This page took 0.026782 seconds and 4 git commands to generate.