Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Functions
stabs.c File Reference
#include <stdio.h>
#include "bfd.h"
#include "bucomm.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "demangle.h"
#include "debug.h"
#include "budbg.h"
#include "filenames.h"
#include "aout/aout64.h"
#include "aout/stab_gnu.h"

Go to the source code of this file.

Classes

struct  stab_handle
struct  stab_pending_var
struct  stab_types
struct  stab_tag
struct  bincl_file
struct  stab_demangle_typestring
struct  stab_demangle_info

Defines

#define XCOFF_TYPE_COUNT   34
#define STAB_TYPES_SLOTS   (16)
#define LLLOW   "01000000000000000000000;"
#define LLHIGH   "0777777777777777777777;"
#define ULLHIGH   "01777777777777777777777;"

Functions

static char * savestring (const char *, int)
static bfd_vma parse_number (const char **, bfd_boolean *)
static void bad_stab (const char *)
static void warn_stab (const char *, const char *)
static bfd_boolean parse_stab_string (void *, struct stab_handle *, int, int, bfd_vma, const char *)
static debug_type parse_stab_type (void *, struct stab_handle *, const char *, const char **, debug_type **)
static bfd_boolean parse_stab_type_number (const char **, int *)
static debug_type parse_stab_range_type (void *, struct stab_handle *, const char *, const char **, const int *)
static debug_type parse_stab_sun_builtin_type (void *, const char **)
static debug_type parse_stab_sun_floating_type (void *, const char **)
static debug_type parse_stab_enum_type (void *, const char **)
static debug_type parse_stab_struct_type (void *, struct stab_handle *, const char *, const char **, bfd_boolean, const int *)
static bfd_boolean parse_stab_baseclasses (void *, struct stab_handle *, const char **, debug_baseclass **)
static bfd_boolean parse_stab_struct_fields (void *, struct stab_handle *, const char **, debug_field **, bfd_boolean *)
static bfd_boolean parse_stab_cpp_abbrev (void *, struct stab_handle *, const char **, debug_field *)
static bfd_boolean parse_stab_one_struct_field (void *, struct stab_handle *, const char **, const char *, debug_field *, bfd_boolean *)
static bfd_boolean parse_stab_members (void *, struct stab_handle *, const char *, const char **, const int *, debug_method **)
static debug_type parse_stab_argtypes (void *, struct stab_handle *, debug_type, const char *, const char *, debug_type, const char *, bfd_boolean, bfd_boolean, const char **)
static bfd_boolean parse_stab_tilde_field (void *, struct stab_handle *, const char **, const int *, debug_type *, bfd_boolean *)
static debug_type parse_stab_array_type (void *, struct stab_handle *, const char **, bfd_boolean)
static void push_bincl (struct stab_handle *, const char *, bfd_vma)
static const char * pop_bincl (struct stab_handle *)
static bfd_boolean find_excl (struct stab_handle *, const char *, bfd_vma)
static bfd_boolean stab_record_variable (void *, struct stab_handle *, const char *, debug_type, enum debug_var_kind, bfd_vma)
static bfd_boolean stab_emit_pending_vars (void *, struct stab_handle *)
static debug_typestab_find_slot (struct stab_handle *, const int *)
static debug_type stab_find_type (void *, struct stab_handle *, const int *)
static bfd_boolean stab_record_type (void *, struct stab_handle *, const int *, debug_type)
static debug_type stab_xcoff_builtin_type (void *, struct stab_handle *, int)
static debug_type stab_find_tagged_type (void *, struct stab_handle *, const char *, int, enum debug_type_kind)
static debug_typestab_demangle_argtypes (void *, struct stab_handle *, const char *, bfd_boolean *, unsigned int)
static debug_typestab_demangle_v3_argtypes (void *, struct stab_handle *, const char *, bfd_boolean *)
static debug_typestab_demangle_v3_arglist (void *, struct stab_handle *, struct demangle_component *, bfd_boolean *)
static debug_type stab_demangle_v3_arg (void *, struct stab_handle *, struct demangle_component *, debug_type, bfd_boolean *)
void * start_stab (void *dhandle ATTRIBUTE_UNUSED, bfd *abfd, bfd_boolean sections, asymbol **syms, long symcount)
bfd_boolean finish_stab (void *dhandle, void *handle)
bfd_boolean parse_stab (void *dhandle, void *handle, int type, int desc, bfd_vma value, const char *string)
static bfd_boolean stab_record_type (void *dhandle ATTRIBUTE_UNUSED, struct stab_handle *info, const int *typenums, debug_type type)
static void stab_bad_demangle (const char *)
static unsigned int stab_demangle_count (const char **)
static bfd_boolean stab_demangle_get_count (const char **, unsigned int *)
static bfd_boolean stab_demangle_prefix (struct stab_demangle_info *, const char **, unsigned int)
static bfd_boolean stab_demangle_function_name (struct stab_demangle_info *, const char **, const char *)
static bfd_boolean stab_demangle_signature (struct stab_demangle_info *, const char **)
static bfd_boolean stab_demangle_qualified (struct stab_demangle_info *, const char **, debug_type *)
static bfd_boolean stab_demangle_template (struct stab_demangle_info *, const char **, char **)
static bfd_boolean stab_demangle_class (struct stab_demangle_info *, const char **, const char **)
static bfd_boolean stab_demangle_args (struct stab_demangle_info *, const char **, debug_type **, bfd_boolean *)
static bfd_boolean stab_demangle_arg (struct stab_demangle_info *, const char **, debug_type **, unsigned int *, unsigned int *)
static bfd_boolean stab_demangle_type (struct stab_demangle_info *, const char **, debug_type *)
static bfd_boolean stab_demangle_fund_type (struct stab_demangle_info *, const char **, debug_type *)
static bfd_boolean stab_demangle_remember_type (struct stab_demangle_info *, const char *, int)
static bfd_boolean stab_demangle_class (struct stab_demangle_info *minfo ATTRIBUTE_UNUSED, const char **pp, const char **pstart)

Class Documentation

struct stab_handle

Definition at line 48 of file stabs.c.

Collaboration diagram for stab_handle:
Class Members
bfd * abfd
struct bincl_file * bincl_list
struct bincl_file * bincl_stack
int block_depth
bfd_vma file_start_offset
struct stab_types ** file_types
unsigned int files
bfd_vma function_end
bfd_vma function_start_offset
int gcc_compiled
char * main_filename
bfd_boolean n_opt_found
struct stab_pending_var * pending
bfd_boolean sections
bfd_boolean self_crossref
char * so_string
bfd_vma so_value
long symcount
asymbol ** syms
struct stab_tag * tags
bfd_boolean within_function
debug_type xcoff_types
struct stab_pending_var

Definition at line 106 of file stabs.c.

Collaboration diagram for stab_pending_var:
Class Members
const char * name
struct stab_pending_var * next
debug_type type
struct stab_types

Definition at line 123 of file stabs.c.

Collaboration diagram for stab_types:
Class Members
struct stab_types * next
debug_type types
struct stab_tag

Definition at line 135 of file stabs.c.

Collaboration diagram for stab_tag:
Class Members
long index
const char * name
struct stab_tag * next
const char * tag
struct bincl_file

Definition at line 3109 of file stabs.c.

Collaboration diagram for bincl_file:
Class Members
unsigned int file
struct stab_types * file_types
bfd_vma hash
const char * name
struct bincl_file * next
struct bincl_file * next_stack
struct stab_demangle_typestring

Definition at line 3583 of file stabs.c.

Class Members
unsigned int len
const char * typestring
struct stab_demangle_info

Definition at line 3594 of file stabs.c.

Collaboration diagram for stab_demangle_info:
Class Members
debug_type * args
void * dhandle
struct stab_handle * info
unsigned int typestring_alloc
unsigned int typestring_count
struct stab_demangle_typestring * typestrings
bfd_boolean varargs

Define Documentation

#define LLHIGH   "0777777777777777777777;"
#define LLLOW   "01000000000000000000000;"
#define STAB_TYPES_SLOTS   (16)

Definition at line 128 of file stabs.c.

#define ULLHIGH   "01777777777777777777777;"
#define XCOFF_TYPE_COUNT   34

Definition at line 43 of file stabs.c.


Function Documentation

static void bad_stab ( const char *  p) [static]

Definition at line 338 of file stabs.c.

{
  fprintf (stderr, _("Bad stab: %s\n"), p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean find_excl ( struct stab_handle info,
const char *  name,
bfd_vma  hash 
) [static]

Definition at line 3173 of file stabs.c.

{
  struct bincl_file *l;

  ++info->files;
  info->file_types = ((struct stab_types **)
                    xrealloc (info->file_types,
                            (info->files
                             * sizeof *info->file_types)));

  for (l = info->bincl_list; l != NULL; l = l->next)
    if (l->hash == hash && strcmp (l->name, name) == 0)
      break;
  if (l == NULL)
    {
      warn_stab (name, _("Undefined N_EXCL"));
      info->file_types[info->files - 1] = NULL;
      return TRUE;
    }

  info->file_types[info->files - 1] = l->file_types;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean finish_stab ( void *  dhandle,
void *  handle 
)

Definition at line 376 of file stabs.c.

{
  struct stab_handle *info = (struct stab_handle *) handle;
  struct stab_tag *st;

  if (info->within_function)
    {
      if (! stab_emit_pending_vars (dhandle, info)
         || ! debug_end_function (dhandle, info->function_end))
       return FALSE;
      info->within_function = FALSE;
      info->function_end = (bfd_vma) -1;
    }

  for (st = info->tags; st != NULL; st = st->next)
    {
      enum debug_type_kind kind;

      kind = st->kind;
      if (kind == DEBUG_KIND_ILLEGAL)
       kind = DEBUG_KIND_STRUCT;
      st->slot = debug_make_undefined_tagged_type (dhandle, st->name, kind);
      if (st->slot == DEBUG_TYPE_NULL)
       return FALSE;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_vma parse_number ( const char **  pp,
bfd_boolean poverflow 
) [static]

Definition at line 228 of file stabs.c.

{
  unsigned long ul;
  const char *orig;

  if (poverflow != NULL)
    *poverflow = FALSE;

  orig = *pp;

  errno = 0;
  ul = strtoul (*pp, (char **) pp, 0);
  if (ul + 1 != 0 || errno == 0)
    {
      /* If bfd_vma is larger than unsigned long, and the number is
         meant to be negative, we have to make sure that we sign
         extend properly.  */
      if (*orig == '-')
       return (bfd_vma) (bfd_signed_vma) (long) ul;
      return (bfd_vma) ul;
    }

  /* Note that even though strtoul overflowed, it should have set *pp
     to the end of the number, which is where we want it.  */
  if (sizeof (bfd_vma) > sizeof (unsigned long))
    {
      const char *p;
      bfd_boolean neg;
      int base;
      bfd_vma over, lastdig;
      bfd_boolean overflow;
      bfd_vma v;

      /* Our own version of strtoul, for a bfd_vma.  */
      p = orig;

      neg = FALSE;
      if (*p == '+')
       ++p;
      else if (*p == '-')
       {
         neg = TRUE;
         ++p;
       }

      base = 10;
      if (*p == '0')
       {
         if (p[1] == 'x' || p[1] == 'X')
           {
             base = 16;
             p += 2;
           }
         else
           {
             base = 8;
             ++p;
           }
       }

      over = ((bfd_vma) (bfd_signed_vma) -1) / (bfd_vma) base;
      lastdig = ((bfd_vma) (bfd_signed_vma) -1) % (bfd_vma) base;

      overflow = FALSE;
      v = 0;
      while (1)
       {
         int d;

         d = *p++;
         if (ISDIGIT (d))
           d -= '0';
         else if (ISUPPER (d))
           d -= 'A';
         else if (ISLOWER (d))
           d -= 'a';
         else
           break;

         if (d >= base)
           break;

         if (v > over || (v == over && (bfd_vma) d > lastdig))
           {
             overflow = TRUE;
             break;
           }
       }

      if (! overflow)
       {
         if (neg)
           v = - v;
         return v;
       }
    }

  /* If we get here, the number is too large to represent in a
     bfd_vma.  */
  if (poverflow != NULL)
    *poverflow = TRUE;
  else
    warn_stab (orig, _("numeric overflow"));

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean parse_stab ( void *  dhandle,
void *  handle,
int  type,
int  desc,
bfd_vma  value,
const char *  string 
)

Definition at line 408 of file stabs.c.

{
  struct stab_handle *info = (struct stab_handle *) handle;

  /* gcc will emit two N_SO strings per compilation unit, one for the
     directory name and one for the file name.  We just collect N_SO
     strings as we see them, and start the new compilation unit when
     we see a non N_SO symbol.  */
  if (info->so_string != NULL
      && (type != N_SO || *string == '\0' || value != info->so_value))
    {
      if (! debug_set_filename (dhandle, info->so_string))
       return FALSE;
      info->main_filename = info->so_string;

      info->gcc_compiled = 0;
      info->n_opt_found = FALSE;

      /* Generally, for stabs in the symbol table, the N_LBRAC and
        N_RBRAC symbols are relative to the N_SO symbol value.  */
      if (! info->sections)
       info->file_start_offset = info->so_value;

      /* We need to reset the mapping from type numbers to types.  We
        can't free the old mapping, because of the use of
        debug_make_indirect_type.  */
      info->files = 1;
      info->file_types = ((struct stab_types **)
                       xmalloc (sizeof *info->file_types));
      info->file_types[0] = NULL;

      info->so_string = NULL;

      /* Now process whatever type we just got.  */
    }

  switch (type)
    {
    case N_FN:
    case N_FN_SEQ:
      break;

    case N_LBRAC:
      /* Ignore extra outermost context from SunPRO cc and acc.  */
      if (info->n_opt_found && desc == 1)
       break;

      if (! info->within_function)
       {
         fprintf (stderr, _("N_LBRAC not within function\n"));
         return FALSE;
       }

      /* Start an inner lexical block.  */
      if (! debug_start_block (dhandle,
                            (value
                            + info->file_start_offset
                            + info->function_start_offset)))
       return FALSE;

      /* Emit any pending variable definitions.  */
      if (! stab_emit_pending_vars (dhandle, info))
       return FALSE;

      ++info->block_depth;
      break;

    case N_RBRAC:
      /* Ignore extra outermost context from SunPRO cc and acc.  */
      if (info->n_opt_found && desc == 1)
       break;

      /* We shouldn't have any pending variable definitions here, but,
         if we do, we probably need to emit them before closing the
         block.  */
      if (! stab_emit_pending_vars (dhandle, info))
       return FALSE;

      /* End an inner lexical block.  */
      if (! debug_end_block (dhandle,
                          (value
                           + info->file_start_offset
                           + info->function_start_offset)))
       return FALSE;

      --info->block_depth;
      if (info->block_depth < 0)
       {
         fprintf (stderr, _("Too many N_RBRACs\n"));
         return FALSE;
       }
      break;

    case N_SO:
      /* This always ends a function.  */
      if (info->within_function)
       {
         bfd_vma endval;

         endval = value;
         if (*string != '\0'
             && info->function_end != (bfd_vma) -1
             && info->function_end < endval)
           endval = info->function_end;
         if (! stab_emit_pending_vars (dhandle, info)
             || ! debug_end_function (dhandle, endval))
           return FALSE;
         info->within_function = FALSE;
         info->function_end = (bfd_vma) -1;
       }

      /* An empty string is emitted by gcc at the end of a compilation
         unit.  */
      if (*string == '\0')
       return TRUE;

      /* Just accumulate strings until we see a non N_SO symbol.  If
         the string starts with a directory separator or some other
        form of absolute path specification, we discard the previously
         accumulated strings.  */
      if (info->so_string == NULL)
       info->so_string = xstrdup (string);
      else
       {
         char *f;

         f = info->so_string;

         if (IS_ABSOLUTE_PATH (string))
           info->so_string = xstrdup (string);
         else
           info->so_string = concat (info->so_string, string,
                                  (const char *) NULL);
         free (f);
       }

      info->so_value = value;

      break;

    case N_SOL:
      /* Start an include file.  */
      if (! debug_start_source (dhandle, string))
       return FALSE;
      break;

    case N_BINCL:
      /* Start an include file which may be replaced.  */
      push_bincl (info, string, value);
      if (! debug_start_source (dhandle, string))
       return FALSE;
      break;

    case N_EINCL:
      /* End an N_BINCL include.  */
      if (! debug_start_source (dhandle, pop_bincl (info)))
       return FALSE;
      break;

    case N_EXCL:
      /* This is a duplicate of a header file named by N_BINCL which
         was eliminated by the linker.  */
      if (! find_excl (info, string, value))
       return FALSE;
      break;

    case N_SLINE:
      if (! debug_record_line (dhandle, desc,
                            value + (info->within_function
                                   ? info->function_start_offset : 0)))
       return FALSE;
      break;

    case N_BCOMM:
      if (! debug_start_common_block (dhandle, string))
       return FALSE;
      break;

    case N_ECOMM:
      if (! debug_end_common_block (dhandle, string))
       return FALSE;
      break;

    case N_FUN:
      if (*string == '\0')
       {
         if (info->within_function)
           {
             /* This always marks the end of a function; we don't
                 need to worry about info->function_end.  */
             if (info->sections)
              value += info->function_start_offset;
             if (! stab_emit_pending_vars (dhandle, info)
                || ! debug_end_function (dhandle, value))
              return FALSE;
             info->within_function = FALSE;
             info->function_end = (bfd_vma) -1;
           }
         break;
       }

      /* A const static symbol in the .text section will have an N_FUN
         entry.  We need to use these to mark the end of the function,
         in case we are looking at gcc output before it was changed to
         always emit an empty N_FUN.  We can't call debug_end_function
         here, because it might be a local static symbol.  */
      if (info->within_function
         && (info->function_end == (bfd_vma) -1
             || value < info->function_end))
       info->function_end = value;

      /* Fall through.  */
      /* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM
         symbols, and if it does not start with :S, gdb relocates the
         value to the start of the section.  gcc always seems to use
         :S, so we don't worry about this.  */
      /* Fall through.  */
    default:
      {
       const char *colon;

       colon = strchr (string, ':');
       if (colon != NULL
           && (colon[1] == 'f' || colon[1] == 'F'))
         {
           if (info->within_function)
             {
              bfd_vma endval;

              endval = value;
              if (info->function_end != (bfd_vma) -1
                  && info->function_end < endval)
                endval = info->function_end;
              if (! stab_emit_pending_vars (dhandle, info)
                  || ! debug_end_function (dhandle, endval))
                return FALSE;
              info->function_end = (bfd_vma) -1;
             }
           /* For stabs in sections, line numbers and block addresses
               are offsets from the start of the function.  */
           if (info->sections)
             info->function_start_offset = value;
           info->within_function = TRUE;
         }

       if (! parse_stab_string (dhandle, info, type, desc, value, string))
         return FALSE;
      }
      break;

    case N_OPT:
      if (string != NULL && strcmp (string, "gcc2_compiled.") == 0)
       info->gcc_compiled = 2;
      else if (string != NULL && strcmp (string, "gcc_compiled.") == 0)
       info->gcc_compiled = 1;
      else
       info->n_opt_found = TRUE;
      break;

    case N_OBJ:
    case N_ENDM:
    case N_MAIN:
    case N_WARNING:
      break;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type parse_stab_argtypes ( void *  dhandle,
struct stab_handle info,
debug_type  class_type,
const char *  fieldname,
const char *  tagname,
debug_type  return_type,
const char *  argtypes,
bfd_boolean  constp,
bfd_boolean  volatilep,
const char **  pphysname 
) [static]

Definition at line 2815 of file stabs.c.

{
  bfd_boolean is_full_physname_constructor;
  bfd_boolean is_constructor;
  bfd_boolean is_destructor;
  bfd_boolean is_v3;
  debug_type *args;
  bfd_boolean varargs;
  unsigned int physname_len = 0;

  /* Constructors are sometimes handled specially.  */
  is_full_physname_constructor = ((argtypes[0] == '_'
                               && argtypes[1] == '_'
                               && (ISDIGIT (argtypes[2])
                                   || argtypes[2] == 'Q'
                                   || argtypes[2] == 't'))
                              || CONST_STRNEQ (argtypes, "__ct"));

  is_constructor = (is_full_physname_constructor
                  || (tagname != NULL
                     && strcmp (fieldname, tagname) == 0));
  is_destructor = ((argtypes[0] == '_'
                  && (argtypes[1] == '$' || argtypes[1] == '.')
                  && argtypes[2] == '_')
                 || CONST_STRNEQ (argtypes, "__dt"));
  is_v3 = argtypes[0] == '_' && argtypes[1] == 'Z';

  if (is_destructor || is_full_physname_constructor || is_v3)
    *pphysname = argtypes;
  else
    {
      unsigned int len;
      const char *const_prefix;
      const char *volatile_prefix;
      char buf[20];
      unsigned int mangled_name_len;
      char *physname;

      len = tagname == NULL ? 0 : strlen (tagname);
      const_prefix = constp ? "C" : "";
      volatile_prefix = volatilep ? "V" : "";

      if (len == 0)
       sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
      else if (tagname != NULL && strchr (tagname, '<') != NULL)
       {
         /* Template methods are fully mangled.  */
         sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
         tagname = NULL;
         len = 0;
       }
      else
       sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);

      mangled_name_len = ((is_constructor ? 0 : strlen (fieldname))
                       + strlen (buf)
                       + len
                       + strlen (argtypes)
                       + 1);

      if (fieldname[0] == 'o'
         && fieldname[1] == 'p'
         && (fieldname[2] == '$' || fieldname[2] == '.'))
       {
         const char *opname;

         opname = cplus_mangle_opname (fieldname + 3, 0);
         if (opname == NULL)
           {
             fprintf (stderr, _("No mangling for \"%s\"\n"), fieldname);
             return DEBUG_TYPE_NULL;
           }
         mangled_name_len += strlen (opname);
         physname = (char *) xmalloc (mangled_name_len);
         strncpy (physname, fieldname, 3);
         strcpy (physname + 3, opname);
       }
      else
       {
         physname = (char *) xmalloc (mangled_name_len);
         if (is_constructor)
           physname[0] = '\0';
         else
           strcpy (physname, fieldname);
       }

      physname_len = strlen (physname);
      strcat (physname, buf);
      if (tagname != NULL)
       strcat (physname, tagname);
      strcat (physname, argtypes);

      *pphysname = physname;
    }

  if (*argtypes == '\0' || is_destructor)
    {
      args = (debug_type *) xmalloc (sizeof *args);
      *args = NULL;
      return debug_make_method_type (dhandle, return_type, class_type, args,
                                 FALSE);
    }

  args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs, physname_len);
  if (args == NULL)
    return DEBUG_TYPE_NULL;

  return debug_make_method_type (dhandle, return_type, class_type, args,
                             varargs);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type parse_stab_array_type ( void *  dhandle,
struct stab_handle info,
const char **  pp,
bfd_boolean  stringp 
) [static]

Definition at line 3011 of file stabs.c.

{
  const char *orig;
  const char *p;
  int typenums[2];
  debug_type index_type;
  bfd_boolean adjustable;
  bfd_signed_vma lower, upper;
  debug_type element_type;

  /* Format of an array type:
     "ar<index type>;lower;upper;<array_contents_type>".
     OS9000: "arlower,upper;<array_contents_type>".

     Fortran adjustable arrays use Adigits or Tdigits for lower or upper;
     for these, produce a type like float[][].  */

  orig = *pp;

  /* FIXME: gdb checks os9k_stabs here.  */

  /* If the index type is type 0, we take it as int.  */
  p = *pp;
  if (! parse_stab_type_number (&p, typenums))
    return DEBUG_TYPE_NULL;
  if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=')
    {
      index_type = debug_find_named_type (dhandle, "int");
      if (index_type == DEBUG_TYPE_NULL)
       {
         index_type = debug_make_int_type (dhandle, 4, FALSE);
         if (index_type == DEBUG_TYPE_NULL)
           return DEBUG_TYPE_NULL;
       }
      *pp = p;
    }
  else
    {
      index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                                (debug_type **) NULL);
    }

  if (**pp != ';')
    {
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }
  ++*pp;

  adjustable = FALSE;

  if (! ISDIGIT (**pp) && **pp != '-')
    {
      ++*pp;
      adjustable = TRUE;
    }

  lower = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL);
  if (**pp != ';')
    {
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }
  ++*pp;

  if (! ISDIGIT (**pp) && **pp != '-')
    {
      ++*pp;
      adjustable = TRUE;
    }

  upper = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL);
  if (**pp != ';')
    {
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }
  ++*pp;

  element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                              (debug_type **) NULL);
  if (element_type == DEBUG_TYPE_NULL)
    return DEBUG_TYPE_NULL;

  if (adjustable)
    {
      lower = 0;
      upper = -1;
    }

  return debug_make_array_type (dhandle, element_type, index_type, lower,
                            upper, stringp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean parse_stab_baseclasses ( void *  dhandle,
struct stab_handle info,
const char **  pp,
debug_baseclass **  retp 
) [static]

Definition at line 2069 of file stabs.c.

{
  const char *orig;
  unsigned int c, i;
  debug_baseclass *classes;

  *retp = NULL;

  orig = *pp;

  if (**pp != '!')
    {
      /* No base classes.  */
      return TRUE;
    }
  ++*pp;

  c = (unsigned int) parse_number (pp, (bfd_boolean *) NULL);

  if (**pp != ',')
    {
      bad_stab (orig);
      return FALSE;
    }
  ++*pp;

  classes = (debug_baseclass *) xmalloc ((c + 1) * sizeof (**retp));

  for (i = 0; i < c; i++)
    {
      bfd_boolean virtual;
      enum debug_visibility visibility;
      bfd_vma bitpos;
      debug_type type;

      switch (**pp)
       {
       case '0':
         virtual = FALSE;
         break;
       case '1':
         virtual = TRUE;
         break;
       default:
         warn_stab (orig, _("unknown virtual character for baseclass"));
         virtual = FALSE;
         break;
       }
      ++*pp;

      switch (**pp)
       {
       case '0':
         visibility = DEBUG_VISIBILITY_PRIVATE;
         break;
       case '1':
         visibility = DEBUG_VISIBILITY_PROTECTED;
         break;
       case '2':
         visibility = DEBUG_VISIBILITY_PUBLIC;
         break;
       default:
         warn_stab (orig, _("unknown visibility character for baseclass"));
         visibility = DEBUG_VISIBILITY_PUBLIC;
         break;
       }
      ++*pp;

      /* The remaining value is the bit offset of the portion of the
        object corresponding to this baseclass.  Always zero in the
        absence of multiple inheritance.  */
      bitpos = parse_number (pp, (bfd_boolean *) NULL);
      if (**pp != ',')
       {
         bad_stab (orig);
         return FALSE;
       }
      ++*pp;

      type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                           (debug_type **) NULL);
      if (type == DEBUG_TYPE_NULL)
       return FALSE;

      classes[i] = debug_make_baseclass (dhandle, type, bitpos, virtual,
                                    visibility);
      if (classes[i] == DEBUG_BASECLASS_NULL)
       return FALSE;

      if (**pp != ';')
       return FALSE;
      ++*pp;
    }

  classes[i] = DEBUG_BASECLASS_NULL;

  *retp = classes;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean parse_stab_cpp_abbrev ( void *  dhandle,
struct stab_handle info,
const char **  pp,
debug_field retp 
) [static]

Definition at line 2272 of file stabs.c.

{
  const char *orig;
  int cpp_abbrev;
  debug_type context;
  const char *name;
  const char *typename;
  debug_type type;
  bfd_vma bitpos;

  *retp = DEBUG_FIELD_NULL;

  orig = *pp;

  if (**pp != 'v')
    {
      bad_stab (*pp);
      return FALSE;
    }
  ++*pp;

  cpp_abbrev = **pp;
  ++*pp;

  /* At this point, *pp points to something like "22:23=*22...", where
     the type number before the ':' is the "context" and everything
     after is a regular type definition.  Lookup the type, find it's
     name, and construct the field name.  */

  context = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                          (debug_type **) NULL);
  if (context == DEBUG_TYPE_NULL)
    return FALSE;

  switch (cpp_abbrev)
    {
    case 'f':
      /* $vf -- a virtual function table pointer.  */
      name = "_vptr$";
      break;
    case 'b':
      /* $vb -- a virtual bsomethingorother */
      typename = debug_get_type_name (dhandle, context);
      if (typename == NULL)
       {
         warn_stab (orig, _("unnamed $vb type"));
         typename = "FOO";
       }
      name = concat ("_vb$", typename, (const char *) NULL);
      break;
    default:
      warn_stab (orig, _("unrecognized C++ abbreviation"));
      name = "INVALID_CPLUSPLUS_ABBREV";
      break;
    }

  if (**pp != ':')
    {
      bad_stab (orig);
      return FALSE;
    }
  ++*pp;

  type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                       (debug_type **) NULL);
  if (**pp != ',')
    {
      bad_stab (orig);
      return FALSE;
    }
  ++*pp;

  bitpos = parse_number (pp, (bfd_boolean *) NULL);
  if (**pp != ';')
    {
      bad_stab (orig);
      return FALSE;
    }
  ++*pp;

  *retp = debug_make_field (dhandle, name, type, bitpos, 0,
                         DEBUG_VISIBILITY_PRIVATE);
  if (*retp == DEBUG_FIELD_NULL)
    return FALSE;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type parse_stab_enum_type ( void *  dhandle,
const char **  pp 
) [static]

Definition at line 1927 of file stabs.c.

{
  const char *orig;
  const char **names;
  bfd_signed_vma *values;
  unsigned int n;
  unsigned int alloc;

  orig = *pp;

  /* FIXME: gdb checks os9k_stabs here.  */

  /* The aix4 compiler emits an extra field before the enum members;
     my guess is it's a type of some sort.  Just ignore it.  */
  if (**pp == '-')
    {
      while (**pp != ':')
       ++*pp;
      ++*pp;
    }

  /* Read the value-names and their values.
     The input syntax is NAME:VALUE,NAME:VALUE, and so on.
     A semicolon or comma instead of a NAME means the end.  */
  alloc = 10;
  names = (const char **) xmalloc (alloc * sizeof *names);
  values = (bfd_signed_vma *) xmalloc (alloc * sizeof *values);
  n = 0;
  while (**pp != '\0' && **pp != ';' && **pp != ',')
    {
      const char *p;
      char *name;
      bfd_signed_vma val;

      p = *pp;
      while (*p != ':')
       ++p;

      name = savestring (*pp, p - *pp);

      *pp = p + 1;
      val = (bfd_signed_vma) parse_number (pp, (bfd_boolean *) NULL);
      if (**pp != ',')
       {
         bad_stab (orig);
         return DEBUG_TYPE_NULL;
       }
      ++*pp;

      if (n + 1 >= alloc)
       {
         alloc += 10;
         names = ((const char **)
                 xrealloc (names, alloc * sizeof *names));
         values = ((bfd_signed_vma *)
                  xrealloc (values, alloc * sizeof *values));
       }

      names[n] = name;
      values[n] = val;
      ++n;
    }

  names[n] = NULL;
  values[n] = 0;

  if (**pp == ';')
    ++*pp;

  return debug_make_enum_type (dhandle, names, values);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean parse_stab_members ( void *  dhandle,
struct stab_handle info,
const char *  tagname,
const char **  pp,
const int typenums,
debug_method **  retp 
) [static]

Definition at line 2498 of file stabs.c.

{
  const char *orig;
  debug_method *methods;
  unsigned int c;
  unsigned int alloc;

  *retp = NULL;

  orig = *pp;

  alloc = 0;
  methods = NULL;
  c = 0;

  while (**pp != ';')
    {
      const char *p;
      char *name;
      debug_method_variant *variants;
      unsigned int cvars;
      unsigned int allocvars;
      debug_type look_ahead_type;

      p = strchr (*pp, ':');
      if (p == NULL || p[1] != ':')
       break;

      /* FIXME: Some systems use something other than '$' here.  */
      if ((*pp)[0] != 'o' || (*pp)[1] != 'p' || (*pp)[2] != '$')
       {
         name = savestring (*pp, p - *pp);
         *pp = p + 2;
       }
      else
       {
         /* This is a completely weird case.  In order to stuff in the
            names that might contain colons (the usual name delimiter),
            Mike Tiemann defined a different name format which is
            signalled if the identifier is "op$".  In that case, the
            format is "op$::XXXX." where XXXX is the name.  This is
            used for names like "+" or "=".  YUUUUUUUK!  FIXME!  */
         *pp = p + 2;
         for (p = *pp; *p != '.' && *p != '\0'; p++)
           ;
         if (*p != '.')
           {
             bad_stab (orig);
             return FALSE;
           }
         name = savestring (*pp, p - *pp);
         *pp = p + 1;
       }

      allocvars = 10;
      variants = ((debug_method_variant *)
                xmalloc (allocvars * sizeof *variants));
      cvars = 0;

      look_ahead_type = DEBUG_TYPE_NULL;

      do
       {
         debug_type type;
         bfd_boolean stub;
         char *argtypes;
         enum debug_visibility visibility;
         bfd_boolean constp, volatilep, staticp;
         bfd_vma voffset;
         debug_type context;
         const char *physname;
         bfd_boolean varargs;

         if (look_ahead_type != DEBUG_TYPE_NULL)
           {
             /* g++ version 1 kludge */
             type = look_ahead_type;
             look_ahead_type = DEBUG_TYPE_NULL;
           }
         else
           {
             type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                                  (debug_type **) NULL);
             if (type == DEBUG_TYPE_NULL)
              return FALSE;
             if (**pp != ':')
              {
                bad_stab (orig);
                return FALSE;
              }
           }

         ++*pp;
         p = strchr (*pp, ';');
         if (p == NULL)
           {
             bad_stab (orig);
             return FALSE;
           }

         stub = FALSE;
         if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
             && debug_get_parameter_types (dhandle, type, &varargs) == NULL)
           stub = TRUE;

         argtypes = savestring (*pp, p - *pp);
         *pp = p + 1;

         switch (**pp)
           {
           case '0':
             visibility = DEBUG_VISIBILITY_PRIVATE;
             break;
           case '1':
             visibility = DEBUG_VISIBILITY_PROTECTED;
             break;
           default:
             visibility = DEBUG_VISIBILITY_PUBLIC;
             break;
           }
         ++*pp;

         constp = FALSE;
         volatilep = FALSE;
         switch (**pp)
           {
           case 'A':
             /* Normal function.  */
             ++*pp;
             break;
           case 'B':
             /* const member function.  */
             constp = TRUE;
             ++*pp;
             break;
           case 'C':
             /* volatile member function.  */
             volatilep = TRUE;
             ++*pp;
             break;
           case 'D':
             /* const volatile member function.  */
             constp = TRUE;
             volatilep = TRUE;
             ++*pp;
             break;
           case '*':
           case '?':
           case '.':
             /* File compiled with g++ version 1; no information.  */
             break;
           default:
             warn_stab (orig, _("const/volatile indicator missing"));
             break;
           }

         staticp = FALSE;
         switch (**pp)
           {
           case '*':
             /* virtual member function, followed by index.  The sign
               bit is supposedly set to distinguish
               pointers-to-methods from virtual function indicies.  */
             ++*pp;
             voffset = parse_number (pp, (bfd_boolean *) NULL);
             if (**pp != ';')
              {
                bad_stab (orig);
                return FALSE;
              }
             ++*pp;
             voffset &= 0x7fffffff;

             if (**pp == ';' || *pp == '\0')
              {
                /* Must be g++ version 1.  */
                context = DEBUG_TYPE_NULL;
              }
             else
              {
                /* Figure out from whence this virtual function
                   came.  It may belong to virtual function table of
                   one of its baseclasses.  */
                look_ahead_type = parse_stab_type (dhandle, info,
                                               (const char *) NULL,
                                               pp,
                                               (debug_type **) NULL);
                if (**pp == ':')
                  {
                    /* g++ version 1 overloaded methods.  */
                    context = DEBUG_TYPE_NULL;
                  }
                else
                  {
                    context = look_ahead_type;
                    look_ahead_type = DEBUG_TYPE_NULL;
                    if (**pp != ';')
                     {
                       bad_stab (orig);
                       return FALSE;
                     }
                    ++*pp;
                  }
              }
             break;

           case '?':
             /* static member function.  */
             ++*pp;
             staticp = TRUE;
             voffset = 0;
             context = DEBUG_TYPE_NULL;
             if (strncmp (argtypes, name, strlen (name)) != 0)
              stub = TRUE;
             break;

           default:
             warn_stab (orig, "member function type missing");
             voffset = 0;
             context = DEBUG_TYPE_NULL;
             break;

           case '.':
             ++*pp;
             voffset = 0;
             context = DEBUG_TYPE_NULL;
             break;
           }

         /* If the type is not a stub, then the argtypes string is
             the physical name of the function.  Otherwise the
             argtypes string is the mangled form of the argument
             types, and the full type and the physical name must be
             extracted from them.  */
         if (! stub)
           physname = argtypes;
         else
           {
             debug_type class_type, return_type;

             class_type = stab_find_type (dhandle, info, typenums);
             if (class_type == DEBUG_TYPE_NULL)
              return FALSE;
             return_type = debug_get_return_type (dhandle, type);
             if (return_type == DEBUG_TYPE_NULL)
              {
                bad_stab (orig);
                return FALSE;
              }
             type = parse_stab_argtypes (dhandle, info, class_type, name,
                                     tagname, return_type, argtypes,
                                     constp, volatilep, &physname);
             if (type == DEBUG_TYPE_NULL)
              return FALSE;
           }

         if (cvars + 1 >= allocvars)
           {
             allocvars += 10;
             variants = ((debug_method_variant *)
                       xrealloc (variants,
                                allocvars * sizeof *variants));
           }

         if (! staticp)
           variants[cvars] = debug_make_method_variant (dhandle, physname,
                                                  type, visibility,
                                                  constp, volatilep,
                                                  voffset, context);
         else
           variants[cvars] = debug_make_static_method_variant (dhandle,
                                                        physname,
                                                        type,
                                                        visibility,
                                                        constp,
                                                        volatilep);
         if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL)
           return FALSE;

         ++cvars;
       }
      while (**pp != ';' && **pp != '\0');

      variants[cvars] = DEBUG_METHOD_VARIANT_NULL;

      if (**pp != '\0')
       ++*pp;

      if (c + 1 >= alloc)
       {
         alloc += 10;
         methods = ((debug_method *)
                   xrealloc (methods, alloc * sizeof *methods));
       }

      methods[c] = debug_make_method (dhandle, name, variants);

      ++c;
    }

  if (methods != NULL)
    methods[c] = DEBUG_METHOD_NULL;

  *retp = methods;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean parse_stab_one_struct_field ( void *  dhandle,
struct stab_handle info,
const char **  pp,
const char *  p,
debug_field retp,
bfd_boolean staticsp 
) [static]

Definition at line 2364 of file stabs.c.

{
  const char *orig;
  char *name;
  enum debug_visibility visibility;
  debug_type type;
  bfd_vma bitpos;
  bfd_vma bitsize;

  orig = *pp;

  /* FIXME: gdb checks ARM_DEMANGLING here.  */

  name = savestring (*pp, p - *pp);

  *pp = p + 1;

  if (**pp != '/')
    visibility = DEBUG_VISIBILITY_PUBLIC;
  else
    {
      ++*pp;
      switch (**pp)
       {
       case '0':
         visibility = DEBUG_VISIBILITY_PRIVATE;
         break;
       case '1':
         visibility = DEBUG_VISIBILITY_PROTECTED;
         break;
       case '2':
         visibility = DEBUG_VISIBILITY_PUBLIC;
         break;
       default:
         warn_stab (orig, _("unknown visibility character for field"));
         visibility = DEBUG_VISIBILITY_PUBLIC;
         break;
       }
      ++*pp;
    }

  type = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                       (debug_type **) NULL);
  if (type == DEBUG_TYPE_NULL)
    return FALSE;

  if (**pp == ':')
    {
      char *varname;

      /* This is a static class member.  */
      ++*pp;
      p = strchr (*pp, ';');
      if (p == NULL)
       {
         bad_stab (orig);
         return FALSE;
       }

      varname = savestring (*pp, p - *pp);

      *pp = p + 1;

      *retp = debug_make_static_member (dhandle, name, type, varname,
                                   visibility);
      *staticsp = TRUE;

      return TRUE;
    }

  if (**pp != ',')
    {
      bad_stab (orig);
      return FALSE;
    }
  ++*pp;

  bitpos = parse_number (pp, (bfd_boolean *) NULL);
  if (**pp != ',')
    {
      bad_stab (orig);
      return FALSE;
    }
  ++*pp;

  bitsize = parse_number (pp, (bfd_boolean *) NULL);
  if (**pp != ';')
    {
      bad_stab (orig);
      return FALSE;
    }
  ++*pp;

  if (bitpos == 0 && bitsize == 0)
    {
      /* This can happen in two cases: (1) at least for gcc 2.4.5 or
        so, it is a field which has been optimized out.  The correct
        stab for this case is to use VISIBILITY_IGNORE, but that is a
        recent invention.  (2) It is a 0-size array.  For example
        union { int num; char str[0]; } foo.  Printing "<no value>"
        for str in "p foo" is OK, since foo.str (and thus foo.str[3])
        will continue to work, and a 0-size array as a whole doesn't
        have any contents to print.

        I suspect this probably could also happen with gcc -gstabs
        (not -gstabs+) for static fields, and perhaps other C++
        extensions.  Hopefully few people use -gstabs with gdb, since
        it is intended for dbx compatibility.  */
      visibility = DEBUG_VISIBILITY_IGNORE;
    }

  /* FIXME: gdb does some stuff here to mark fields as unpacked.  */

  *retp = debug_make_field (dhandle, name, type, bitpos, bitsize, visibility);

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type parse_stab_range_type ( void *  dhandle,
struct stab_handle info,
const char *  typename,
const char **  pp,
const int typenums 
) [static]

Definition at line 1636 of file stabs.c.

{
  const char *orig;
  int rangenums[2];
  bfd_boolean self_subrange;
  debug_type index_type;
  const char *s2, *s3;
  bfd_signed_vma n2, n3;
  bfd_boolean ov2, ov3;

  orig = *pp;

  index_type = DEBUG_TYPE_NULL;

  /* First comes a type we are a subrange of.
     In C it is usually 0, 1 or the type being defined.  */
  if (! parse_stab_type_number (pp, rangenums))
    return DEBUG_TYPE_NULL;

  self_subrange = (rangenums[0] == typenums[0]
                 && rangenums[1] == typenums[1]);

  if (**pp == '=')
    {
      *pp = orig;
      index_type = parse_stab_type (dhandle, info, (const char *) NULL,
                                pp, (debug_type **) NULL);
      if (index_type == DEBUG_TYPE_NULL)
       return DEBUG_TYPE_NULL;
    }

  if (**pp == ';')
    ++*pp;

  /* The remaining two operands are usually lower and upper bounds of
     the range.  But in some special cases they mean something else.  */
  s2 = *pp;
  n2 = parse_number (pp, &ov2);
  if (**pp != ';')
    {
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }
  ++*pp;

  s3 = *pp;
  n3 = parse_number (pp, &ov3);
  if (**pp != ';')
    {
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }
  ++*pp;

  if (ov2 || ov3)
    {
      /* gcc will emit range stabs for long long types.  Handle this
         as a special case.  FIXME: This needs to be more general.  */
#define LLLOW   "01000000000000000000000;"
#define LLHIGH   "0777777777777777777777;"
#define ULLHIGH "01777777777777777777777;"
      if (index_type == DEBUG_TYPE_NULL)
       {
         if (CONST_STRNEQ (s2, LLLOW)
             && CONST_STRNEQ (s3, LLHIGH))
           return debug_make_int_type (dhandle, 8, FALSE);
         if (! ov2
             && n2 == 0
             && CONST_STRNEQ (s3, ULLHIGH))
           return debug_make_int_type (dhandle, 8, TRUE);
       }

      warn_stab (orig, _("numeric overflow"));
    }

  if (index_type == DEBUG_TYPE_NULL)
    {
      /* A type defined as a subrange of itself, with both bounds 0,
         is void.  */
      if (self_subrange && n2 == 0 && n3 == 0)
       return debug_make_void_type (dhandle);

      /* A type defined as a subrange of itself, with n2 positive and
        n3 zero, is a complex type, and n2 is the number of bytes.  */
      if (self_subrange && n3 == 0 && n2 > 0)
       return debug_make_complex_type (dhandle, n2);

      /* If n3 is zero and n2 is positive, this is a floating point
         type, and n2 is the number of bytes.  */
      if (n3 == 0 && n2 > 0)
       return debug_make_float_type (dhandle, n2);

      /* If the upper bound is -1, this is an unsigned int.  */
      if (n2 == 0 && n3 == -1)
       {
         /* When gcc is used with -gstabs, but not -gstabs+, it will emit
                long long int:t6=r1;0;-1;
               long long unsigned int:t7=r1;0;-1;
            We hack here to handle this reasonably.  */
         if (typename != NULL)
           {
             if (strcmp (typename, "long long int") == 0)
              return debug_make_int_type (dhandle, 8, FALSE);
             else if (strcmp (typename, "long long unsigned int") == 0)
              return debug_make_int_type (dhandle, 8, TRUE);
           }
         /* FIXME: The size here really depends upon the target.  */
         return debug_make_int_type (dhandle, 4, TRUE);
       }

      /* A range of 0 to 127 is char.  */
      if (self_subrange && n2 == 0 && n3 == 127)
       return debug_make_int_type (dhandle, 1, FALSE);

      /* FIXME: gdb checks for the language CHILL here.  */

      if (n2 == 0)
       {
         if (n3 < 0)
           return debug_make_int_type (dhandle, - n3, TRUE);
         else if (n3 == 0xff)
           return debug_make_int_type (dhandle, 1, TRUE);
         else if (n3 == 0xffff)
           return debug_make_int_type (dhandle, 2, TRUE);
         else if (n3 == (bfd_signed_vma) 0xffffffff)
           return debug_make_int_type (dhandle, 4, TRUE);
#ifdef BFD64
         else if (n3 == ((((bfd_signed_vma) 0xffffffff) << 32) | 0xffffffff))
           return debug_make_int_type (dhandle, 8, TRUE);
#endif
       }
      else if (n3 == 0
              && n2 < 0
              && (self_subrange || n2 == -8))
       return debug_make_int_type (dhandle, - n2, TRUE);
      else if (n2 == - n3 - 1 || n2 == n3 + 1)
       {
         if (n3 == 0x7f)
           return debug_make_int_type (dhandle, 1, FALSE);
         else if (n3 == 0x7fff)
           return debug_make_int_type (dhandle, 2, FALSE);
         else if (n3 == 0x7fffffff)
           return debug_make_int_type (dhandle, 4, FALSE);
#ifdef BFD64
         else if (n3 == ((((bfd_vma) 0x7fffffff) << 32) | 0xffffffff))
           return debug_make_int_type (dhandle, 8, FALSE);
#endif
       }
    }

  /* At this point I don't have the faintest idea how to deal with a
     self_subrange type; I'm going to assume that this is used as an
     idiom, and that all of them are special cases.  So . . .  */
  if (self_subrange)
    {
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }

  index_type = stab_find_type (dhandle, info, rangenums);
  if (index_type == DEBUG_TYPE_NULL)
    {
      /* Does this actually ever happen?  Is that why we are worrying
         about dealing with it rather than just calling error_type?  */
      warn_stab (orig, _("missing index type"));
      index_type = debug_make_int_type (dhandle, 4, FALSE);
    }

  return debug_make_range_type (dhandle, index_type, n2, n3);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean parse_stab_string ( void *  dhandle,
struct stab_handle info,
int  stabtype,
int  desc,
bfd_vma  value,
const char *  string 
) [static]

Definition at line 681 of file stabs.c.

{
  const char *p;
  char *name;
  int type;
  debug_type dtype;
  bfd_boolean synonym;
  bfd_boolean self_crossref;
  unsigned int lineno;
  debug_type *slot;

  p = strchr (string, ':');
  if (p == NULL)
    return TRUE;

  while (p[1] == ':')
    {
      p += 2;
      p = strchr (p, ':');
      if (p == NULL)
       {
         bad_stab (string);
         return FALSE;
       }
    }

  /* GCC 2.x puts the line number in desc.  SunOS apparently puts in
     the number of bytes occupied by a type or object, which we
     ignore.  */
  if (info->gcc_compiled >= 2)
    lineno = desc;
  else
    lineno = 0;

  /* FIXME: Sometimes the special C++ names start with '.'.  */
  name = NULL;
  if (string[0] == '$')
    {
      switch (string[1])
       {
       case 't':
         name = "this";
         break;
       case 'v':
         /* Was: name = "vptr"; */
         break;
       case 'e':
         name = "eh_throw";
         break;
       case '_':
         /* This was an anonymous type that was never fixed up.  */
         break;
       case 'X':
         /* SunPRO (3.0 at least) static variable encoding.  */
         break;
       default:
         warn_stab (string, _("unknown C++ encoded name"));
         break;
       }
    }

  if (name == NULL)
    {
      if (p == string || (string[0] == ' ' && p == string + 1))
       name = NULL;
      else
       name = savestring (string, p - string);
    }

  ++p;
  if (ISDIGIT (*p) || *p == '(' || *p == '-')
    type = 'l';
  else
    type = *p++;

  switch (type)
    {
    case 'c':
      /* c is a special case, not followed by a type-number.
        SYMBOL:c=iVALUE for an integer constant symbol.
        SYMBOL:c=rVALUE for a floating constant symbol.
        SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.
        e.g. "b:c=e6,0" for "const b = blob1"
        (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;").  */
      if (*p != '=')
       {
         bad_stab (string);
         return FALSE;
       }
      ++p;
      switch (*p++)
       {
       case 'r':
         /* Floating point constant.  */
         if (! debug_record_float_const (dhandle, name, atof (p)))
           return FALSE;
         break;
       case 'i':
         /* Integer constant.  */
         /* Defining integer constants this way is kind of silly,
            since 'e' constants allows the compiler to give not only
            the value, but the type as well.  C has at least int,
            long, unsigned int, and long long as constant types;
            other languages probably should have at least unsigned as
            well as signed constants.  */
         if (! debug_record_int_const (dhandle, name, atoi (p)))
           return FALSE;
         break;
       case 'e':
         /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value
            can be represented as integral.
            e.g. "b:c=e6,0" for "const b = blob1"
            (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;").  */
         dtype = parse_stab_type (dhandle, info, (const char *) NULL,
                               &p, (debug_type **) NULL);
         if (dtype == DEBUG_TYPE_NULL)
           return FALSE;
         if (*p != ',')
           {
             bad_stab (string);
             return FALSE;
           }
         if (! debug_record_typed_const (dhandle, name, dtype, atoi (p)))
           return FALSE;
         break;
       default:
         bad_stab (string);
         return FALSE;
       }

      break;

    case 'C':
      /* The name of a caught exception.  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL,
                            &p, (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (! debug_record_label (dhandle, name, dtype, value))
       return FALSE;
      break;

    case 'f':
    case 'F':
      /* A function definition.  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                            (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (! debug_record_function (dhandle, name, dtype, type == 'F', value))
       return FALSE;

      /* Sun acc puts declared types of arguments here.  We don't care
        about their actual types (FIXME -- we should remember the whole
        function prototype), but the list may define some new types
        that we have to remember, so we must scan it now.  */
      while (*p == ';')
       {
         ++p;
         if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
                            (debug_type **) NULL)
             == DEBUG_TYPE_NULL)
           return FALSE;
       }

      break;

    case 'G':
      {
       char leading;
       long c;
       asymbol **ps;

       /* A global symbol.  The value must be extracted from the
          symbol table.  */
       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                             (debug_type **) NULL);
       if (dtype == DEBUG_TYPE_NULL)
         return FALSE;
       leading = bfd_get_symbol_leading_char (info->abfd);
       for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
         {
           const char *n;

           n = bfd_asymbol_name (*ps);
           if (leading != '\0' && *n == leading)
             ++n;
           if (*n == *name && strcmp (n, name) == 0)
             break;
         }
       if (c > 0)
         value = bfd_asymbol_value (*ps);
       if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL,
                                value))
         return FALSE;
      }
      break;

      /* This case is faked by a conditional above, when there is no
        code letter in the dbx data.  Dbx data never actually
        contains 'l'.  */
    case 'l':
    case 's':
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                            (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
                              value))
       return FALSE;
      break;

    case 'p':
      /* A function parameter.  */
      if (*p != 'F')
       dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                             (debug_type **) NULL);
      else
       {
       /* pF is a two-letter code that means a function parameter in
          Fortran.  The type-number specifies the type of the return
          value.  Translate it into a pointer-to-function type.  */
         ++p;
         dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                               (debug_type **) NULL);
         if (dtype != DEBUG_TYPE_NULL)
           {
             debug_type ftype;

             ftype = debug_make_function_type (dhandle, dtype,
                                          (debug_type *) NULL, FALSE);
             dtype = debug_make_pointer_type (dhandle, ftype);
           }
       }
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_STACK,
                                value))
       return FALSE;

      /* FIXME: At this point gdb considers rearranging the parameter
        address on a big endian machine if it is smaller than an int.
        We have no way to do that, since we don't really know much
        about the target.  */
      break;

    case 'P':
      if (stabtype == N_FUN)
       {
         /* Prototype of a function referenced by this file.  */
         while (*p == ';')
           {
             ++p;
             if (parse_stab_type (dhandle, info, (const char *) NULL, &p,
                               (debug_type **) NULL)
                == DEBUG_TYPE_NULL)
              return FALSE;
           }
         break;
       }
      /* Fall through.  */
    case 'R':
      /* Parameter which is in a register.  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                            (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG,
                                value))
       return FALSE;
      break;

    case 'r':
      /* Register variable (either global or local).  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                            (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER,
                              value))
       return FALSE;

      /* FIXME: At this point gdb checks to combine pairs of 'p' and
        'r' stabs into a single 'P' stab.  */
      break;

    case 'S':
      /* Static symbol at top level of file.  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                            (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC,
                              value))
       return FALSE;
      break;

    case 't':
      /* A typedef.  */
      dtype = parse_stab_type (dhandle, info, name, &p, &slot);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (name == NULL)
       {
         /* A nameless type.  Nothing to do.  */
         return TRUE;
       }

      dtype = debug_name_type (dhandle, name, dtype);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;

      if (slot != NULL)
       *slot = dtype;

      break;

    case 'T':
      /* Struct, union, or enum tag.  For GNU C++, this can be be followed
        by 't' which means we are typedef'ing it as well.  */
      if (*p != 't')
       {
         synonym = FALSE;
         /* FIXME: gdb sets synonym to TRUE if the current language
             is C++.  */
       }
      else
       {
         synonym = TRUE;
         ++p;
       }

      dtype = parse_stab_type (dhandle, info, name, &p, &slot);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (name == NULL)
       return TRUE;

      /* INFO->SELF_CROSSREF is set by parse_stab_type if this type is
         a cross reference to itself.  These are generated by some
         versions of g++.  */
      self_crossref = info->self_crossref;

      dtype = debug_tag_type (dhandle, name, dtype);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (slot != NULL)
       *slot = dtype;

      /* See if we have a cross reference to this tag which we can now
         fill in.  Avoid filling in a cross reference to ourselves,
         because that would lead to circular debugging information.  */
      if (! self_crossref)
       {
         register struct stab_tag **pst;

         for (pst = &info->tags; *pst != NULL; pst = &(*pst)->next)
           {
             if ((*pst)->name[0] == name[0]
                && strcmp ((*pst)->name, name) == 0)
              {
                (*pst)->slot = dtype;
                *pst = (*pst)->next;
                break;
              }
           }
       }

      if (synonym)
       {
         dtype = debug_name_type (dhandle, name, dtype);
         if (dtype == DEBUG_TYPE_NULL)
           return FALSE;

         if (slot != NULL)
           *slot = dtype;
       }

      break;

    case 'V':
      /* Static symbol of local scope */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                            (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      /* FIXME: gdb checks os9k_stabs here.  */
      if (! stab_record_variable (dhandle, info, name, dtype,
                              DEBUG_LOCAL_STATIC, value))
       return FALSE;
      break;

    case 'v':
      /* Reference parameter.  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                            (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE,
                                value))
       return FALSE;
      break;

    case 'a':
      /* Reference parameter which is in a register.  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                            (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG,
                                value))
       return FALSE;
      break;

    case 'X':
      /* This is used by Sun FORTRAN for "function result value".
        Sun claims ("dbx and dbxtool interfaces", 2nd ed)
        that Pascal uses it too, but when I tried it Pascal used
        "x:3" (local symbol) instead.  */
      dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p,
                            (debug_type **) NULL);
      if (dtype == DEBUG_TYPE_NULL)
       return FALSE;
      if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL,
                              value))
       return FALSE;
      break;

    default:
      bad_stab (string);
      return FALSE;
    }

  /* FIXME: gdb converts structure values to structure pointers in a
     couple of cases, depending upon the target.  */

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean parse_stab_struct_fields ( void *  dhandle,
struct stab_handle info,
const char **  pp,
debug_field **  retp,
bfd_boolean staticsp 
) [static]

Definition at line 2192 of file stabs.c.

{
  const char *orig;
  const char *p;
  debug_field *fields;
  unsigned int c;
  unsigned int alloc;

  *retp = NULL;
  *staticsp = FALSE;

  orig = *pp;

  c = 0;
  alloc = 10;
  fields = (debug_field *) xmalloc (alloc * sizeof *fields);
  while (**pp != ';')
    {
      /* FIXME: gdb checks os9k_stabs here.  */

      p = *pp;

      /* Add 1 to c to leave room for NULL pointer at end.  */
      if (c + 1 >= alloc)
       {
         alloc += 10;
         fields = ((debug_field *)
                  xrealloc (fields, alloc * sizeof *fields));
       }

      /* If it starts with CPLUS_MARKER it is a special abbreviation,
        unless the CPLUS_MARKER is followed by an underscore, in
        which case it is just the name of an anonymous type, which we
        should handle like any other type name.  We accept either '$'
        or '.', because a field name can never contain one of these
        characters except as a CPLUS_MARKER.  */

      if ((*p == '$' || *p == '.') && p[1] != '_')
       {
         ++*pp;
         if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c))
           return FALSE;
         ++c;
         continue;
       }

      /* Look for the ':' that separates the field name from the field
        values.  Data members are delimited by a single ':', while member
        functions are delimited by a pair of ':'s.  When we hit the member
        functions (if any), terminate scan loop and return.  */

      p = strchr (p, ':');
      if (p == NULL)
       {
         bad_stab (orig);
         return FALSE;
       }

      if (p[1] == ':')
       break;

      if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c,
                                    staticsp))
       return FALSE;

      ++c;
    }

  fields[c] = DEBUG_FIELD_NULL;

  *retp = fields;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type parse_stab_struct_type ( void *  dhandle,
struct stab_handle info,
const char *  tagname,
const char **  pp,
bfd_boolean  structp,
const int typenums 
) [static]

Definition at line 2007 of file stabs.c.

{
  const char *orig;
  bfd_vma size;
  debug_baseclass *baseclasses;
  debug_field *fields;
  bfd_boolean statics;
  debug_method *methods;
  debug_type vptrbase;
  bfd_boolean ownvptr;

  orig = *pp;

  /* Get the size.  */
  size = parse_number (pp, (bfd_boolean *) NULL);

  /* Get the other information.  */
  if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses)
      || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics)
      || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods)
      || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase,
                               &ownvptr))
    return DEBUG_TYPE_NULL;

  if (! statics
      && baseclasses == NULL
      && methods == NULL
      && vptrbase == DEBUG_TYPE_NULL
      && ! ownvptr)
    return debug_make_struct_type (dhandle, structp, size, fields);

  return debug_make_object_type (dhandle, structp, size, fields, baseclasses,
                             methods, vptrbase, ownvptr);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type parse_stab_sun_builtin_type ( void *  dhandle,
const char **  pp 
) [static]

Definition at line 1820 of file stabs.c.

{
  const char *orig;
  bfd_boolean unsignedp;
  bfd_vma bits;

  orig = *pp;

  switch (**pp)
    {
    case 's':
      unsignedp = FALSE;
      break;
    case 'u':
      unsignedp = TRUE;
      break;
    default:
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }
  ++*pp;

  /* For some odd reason, all forms of char put a c here.  This is strange
     because no other type has this honor.  We can safely ignore this because
     we actually determine 'char'acterness by the number of bits specified in
     the descriptor.  */
  if (**pp == 'c')
    ++*pp;

  /* The first number appears to be the number of bytes occupied
     by this type, except that unsigned short is 4 instead of 2.
     Since this information is redundant with the third number,
     we will ignore it.  */
  (void) parse_number (pp, (bfd_boolean *) NULL);
  if (**pp != ';')
    {
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }
  ++*pp;

  /* The second number is always 0, so ignore it too.  */
  (void) parse_number (pp, (bfd_boolean *) NULL);
  if (**pp != ';')
    {
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }
  ++*pp;

  /* The third number is the number of bits for this type.  */
  bits = parse_number (pp, (bfd_boolean *) NULL);

  /* The type *should* end with a semicolon.  If it are embedded
     in a larger type the semicolon may be the only way to know where
     the type ends.  If this type is at the end of the stabstring we
     can deal with the omitted semicolon (but we don't have to like
     it).  Don't bother to complain(), Sun's compiler omits the semicolon
     for "void".  */
  if (**pp == ';')
    ++*pp;

  if (bits == 0)
    return debug_make_void_type (dhandle);

  return debug_make_int_type (dhandle, bits / 8, unsignedp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type parse_stab_sun_floating_type ( void *  dhandle,
const char **  pp 
) [static]

Definition at line 1891 of file stabs.c.

{
  const char *orig;
  bfd_vma details;
  bfd_vma bytes;

  orig = *pp;

  /* The first number has more details about the type, for example
     FN_COMPLEX.  */
  details = parse_number (pp, (bfd_boolean *) NULL);
  if (**pp != ';')
    {
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }

  /* The second number is the number of bytes occupied by this type */
  bytes = parse_number (pp, (bfd_boolean *) NULL);
  if (**pp != ';')
    {
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }

  if (details == NF_COMPLEX
      || details == NF_COMPLEX16
      || details == NF_COMPLEX32)
    return debug_make_complex_type (dhandle, bytes);

  return debug_make_float_type (dhandle, bytes);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean parse_stab_tilde_field ( void *  dhandle,
struct stab_handle info,
const char **  pp,
const int typenums,
debug_type retvptrbase,
bfd_boolean retownvptr 
) [static]

Definition at line 2939 of file stabs.c.

{
  const char *orig;
  const char *hold;
  int vtypenums[2];

  *retvptrbase = DEBUG_TYPE_NULL;
  *retownvptr = FALSE;

  orig = *pp;

  /* If we are positioned at a ';', then skip it.  */
  if (**pp == ';')
    ++*pp;

  if (**pp != '~')
    return TRUE;

  ++*pp;

  if (**pp == '=' || **pp == '+' || **pp == '-')
    {
      /* Obsolete flags that used to indicate the presence of
        constructors and/or destructors.  */
      ++*pp;
    }

  if (**pp != '%')
    return TRUE;

  ++*pp;

  hold = *pp;

  /* The next number is the type number of the base class (possibly
     our own class) which supplies the vtable for this class.  */
  if (! parse_stab_type_number (pp, vtypenums))
    return FALSE;

  if (vtypenums[0] == typenums[0]
      && vtypenums[1] == typenums[1])
    *retownvptr = TRUE;
  else
    {
      debug_type vtype;
      const char *p;

      *pp = hold;

      vtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                            (debug_type **) NULL);
      for (p = *pp; *p != ';' && *p != '\0'; p++)
       ;
      if (*p != ';')
       {
         bad_stab (orig);
         return FALSE;
       }

      *retvptrbase = vtype;

      *pp = p + 1;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type parse_stab_type ( void *  dhandle,
struct stab_handle info,
const char *  typename,
const char **  pp,
debug_type **  slotp 
) [static]

Definition at line 1127 of file stabs.c.

{
  const char *orig;
  int typenums[2];
  int size;
  bfd_boolean stringp;
  int descriptor;
  debug_type dtype;

  if (slotp != NULL)
    *slotp = NULL;

  orig = *pp;

  size = -1;
  stringp = FALSE;

  info->self_crossref = FALSE;

  /* Read type number if present.  The type number may be omitted.
     for instance in a two-dimensional array declared with type
     "ar1;1;10;ar1;1;10;4".  */
  if (! ISDIGIT (**pp) && **pp != '(' && **pp != '-')
    {
      /* 'typenums=' not present, type is anonymous.  Read and return
        the definition, but don't put it in the type vector.  */
      typenums[0] = typenums[1] = -1;
    }
  else
    {
      if (! parse_stab_type_number (pp, typenums))
       return DEBUG_TYPE_NULL;

      if (**pp != '=')
       /* Type is not being defined here.  Either it already
          exists, or this is a forward reference to it.  */
       return stab_find_type (dhandle, info, typenums);

      /* Only set the slot if the type is being defined.  This means
         that the mapping from type numbers to types will only record
         the name of the typedef which defines a type.  If we don't do
         this, then something like
            typedef int foo;
            int i;
        will record that i is of type foo.  Unfortunately, stabs
        information is ambiguous about variable types.  For this code,
            typedef int foo;
            int i;
            foo j;
        the stabs information records both i and j as having the same
        type.  This could be fixed by patching the compiler.  */
      if (slotp != NULL && typenums[0] >= 0 && typenums[1] >= 0)
       *slotp = stab_find_slot (info, typenums);

      /* Type is being defined here.  */
      /* Skip the '='.  */
      ++*pp;

      while (**pp == '@')
       {
         const char *p = *pp + 1;
         const char *attr;

         if (ISDIGIT (*p) || *p == '(' || *p == '-')
           /* Member type.  */
           break;

         /* Type attributes.  */
         attr = p;

         for (; *p != ';'; ++p)
           {
             if (*p == '\0')
              {
                bad_stab (orig);
                return DEBUG_TYPE_NULL;
              }
           }
         *pp = p + 1;

         switch (*attr)
           {
           case 's':
             size = atoi (attr + 1);
             size /= 8;  /* Size is in bits.  We store it in bytes.  */
             if (size <= 0)
              size = -1;
             break;

           case 'S':
             stringp = TRUE;
             break;

           default:
             /* Ignore unrecognized type attributes, so future
               compilers can invent new ones.  */
             break;
           }
       }
    }

  descriptor = **pp;
  ++*pp;

  switch (descriptor)
    {
    case 'x':
      {
       enum debug_type_kind code;
       const char *q1, *q2, *p;

       /* A cross reference to another type.  */
       switch (**pp)
         {
         case 's':
           code = DEBUG_KIND_STRUCT;
           break;
         case 'u':
           code = DEBUG_KIND_UNION;
           break;
         case 'e':
           code = DEBUG_KIND_ENUM;
           break;
         default:
           /* Complain and keep going, so compilers can invent new
              cross-reference types.  */
           warn_stab (orig, _("unrecognized cross reference type"));
           code = DEBUG_KIND_STRUCT;
           break;
         }
       ++*pp;

       q1 = strchr (*pp, '<');
       p = strchr (*pp, ':');
       if (p == NULL)
         {
           bad_stab (orig);
           return DEBUG_TYPE_NULL;
         }
       if (q1 != NULL && p > q1 && p[1] == ':')
         {
           int nest = 0;

           for (q2 = q1; *q2 != '\0'; ++q2)
             {
              if (*q2 == '<')
                ++nest;
              else if (*q2 == '>')
                --nest;
              else if (*q2 == ':' && nest == 0)
                break;
             }
           p = q2;
           if (*p != ':')
             {
              bad_stab (orig);
              return DEBUG_TYPE_NULL;
             }
         }

       /* Some versions of g++ can emit stabs like
              fleep:T20=xsfleep:
          which define structures in terms of themselves.  We need to
          tell the caller to avoid building a circular structure.  */
       if (typename != NULL
           && strncmp (typename, *pp, p - *pp) == 0
           && typename[p - *pp] == '\0')
         info->self_crossref = TRUE;

       dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code);

       *pp = p + 1;
      }
      break;

    case '-':
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '(':
      {
       const char *hold;
       int xtypenums[2];

       /* This type is defined as another type.  */
       (*pp)--;
       hold = *pp;

       /* Peek ahead at the number to detect void.  */
       if (! parse_stab_type_number (pp, xtypenums))
         return DEBUG_TYPE_NULL;

       if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
         {
           /* This type is being defined as itself, which means that
               it is void.  */
           dtype = debug_make_void_type (dhandle);
         }
       else
         {
           *pp = hold;

           /* Go back to the number and have parse_stab_type get it.
              This means that we can deal with something like
              t(1,2)=(3,4)=... which the Lucid compiler uses.  */
           dtype = parse_stab_type (dhandle, info, (const char *) NULL,
                                 pp, (debug_type **) NULL);
           if (dtype == DEBUG_TYPE_NULL)
             return DEBUG_TYPE_NULL;
         }

       if (typenums[0] != -1)
         {
           if (! stab_record_type (dhandle, info, typenums, dtype))
             return DEBUG_TYPE_NULL;
         }

       break;
      }

    case '*':
      dtype = debug_make_pointer_type (dhandle,
                                   parse_stab_type (dhandle, info,
                                                 (const char *) NULL,
                                                 pp,
                                                 (debug_type **) NULL));
      break;

    case '&':
      /* Reference to another type.  */
      dtype = (debug_make_reference_type
              (dhandle,
              parse_stab_type (dhandle, info, (const char *) NULL, pp,
                             (debug_type **) NULL)));
      break;

    case 'f':
      /* Function returning another type.  */
      /* FIXME: gdb checks os9k_stabs here.  */
      dtype = (debug_make_function_type
              (dhandle,
              parse_stab_type (dhandle, info, (const char *) NULL, pp,
                             (debug_type **) NULL),
              (debug_type *) NULL, FALSE));
      break;

    case 'k':
      /* Const qualifier on some type (Sun).  */
      /* FIXME: gdb accepts 'c' here if os9k_stabs.  */
      dtype = debug_make_const_type (dhandle,
                                 parse_stab_type (dhandle, info,
                                                (const char *) NULL,
                                                pp,
                                                (debug_type **) NULL));
      break;

    case 'B':
      /* Volatile qual on some type (Sun).  */
      /* FIXME: gdb accepts 'i' here if os9k_stabs.  */
      dtype = (debug_make_volatile_type
              (dhandle,
              parse_stab_type (dhandle, info, (const char *) NULL, pp,
                             (debug_type **) NULL)));
      break;

    case '@':
      /* Offset (class & variable) type.  This is used for a pointer
         relative to an object.  */
      {
       debug_type domain;
       debug_type memtype;

       /* Member type.  */

       domain = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                              (debug_type **) NULL);
       if (domain == DEBUG_TYPE_NULL)
         return DEBUG_TYPE_NULL;

       if (**pp != ',')
         {
           bad_stab (orig);
           return DEBUG_TYPE_NULL;
         }
       ++*pp;

       memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp,
                               (debug_type **) NULL);
       if (memtype == DEBUG_TYPE_NULL)
         return DEBUG_TYPE_NULL;

       dtype = debug_make_offset_type (dhandle, domain, memtype);
      }
      break;

    case '#':
      /* Method (class & fn) type.  */
      if (**pp == '#')
       {
         debug_type return_type;

         ++*pp;
         return_type = parse_stab_type (dhandle, info, (const char *) NULL,
                                    pp, (debug_type **) NULL);
         if (return_type == DEBUG_TYPE_NULL)
           return DEBUG_TYPE_NULL;
         if (**pp != ';')
           {
             bad_stab (orig);
             return DEBUG_TYPE_NULL;
           }
         ++*pp;
         dtype = debug_make_method_type (dhandle, return_type,
                                     DEBUG_TYPE_NULL,
                                     (debug_type *) NULL, FALSE);
       }
      else
       {
         debug_type domain;
         debug_type return_type;
         debug_type *args;
         unsigned int n;
         unsigned int alloc;
         bfd_boolean varargs;

         domain = parse_stab_type (dhandle, info, (const char *) NULL,
                                pp, (debug_type **) NULL);
         if (domain == DEBUG_TYPE_NULL)
           return DEBUG_TYPE_NULL;

         if (**pp != ',')
           {
             bad_stab (orig);
             return DEBUG_TYPE_NULL;
           }
         ++*pp;

         return_type = parse_stab_type (dhandle, info, (const char *) NULL,
                                    pp, (debug_type **) NULL);
         if (return_type == DEBUG_TYPE_NULL)
           return DEBUG_TYPE_NULL;

         alloc = 10;
         args = (debug_type *) xmalloc (alloc * sizeof *args);
         n = 0;
         while (**pp != ';')
           {
             if (**pp != ',')
              {
                bad_stab (orig);
                return DEBUG_TYPE_NULL;
              }
             ++*pp;

             if (n + 1 >= alloc)
              {
                alloc += 10;
                args = ((debug_type *)
                       xrealloc (args, alloc * sizeof *args));
              }

             args[n] = parse_stab_type (dhandle, info, (const char *) NULL,
                                    pp, (debug_type **) NULL);
             if (args[n] == DEBUG_TYPE_NULL)
              return DEBUG_TYPE_NULL;
             ++n;
           }
         ++*pp;

         /* If the last type is not void, then this function takes a
            variable number of arguments.  Otherwise, we must strip
            the void type.  */
         if (n == 0
             || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID)
           varargs = TRUE;
         else
           {
             --n;
             varargs = FALSE;
           }

         args[n] = DEBUG_TYPE_NULL;

         dtype = debug_make_method_type (dhandle, return_type, domain, args,
                                     varargs);
       }
      break;

    case 'r':
      /* Range type.  */
      dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums);
      break;

    case 'b':
      /* FIXME: gdb checks os9k_stabs here.  */
      /* Sun ACC builtin int type.  */
      dtype = parse_stab_sun_builtin_type (dhandle, pp);
      break;

    case 'R':
      /* Sun ACC builtin float type.  */
      dtype = parse_stab_sun_floating_type (dhandle, pp);
      break;

    case 'e':
      /* Enumeration type.  */
      dtype = parse_stab_enum_type (dhandle, pp);
      break;

    case 's':
    case 'u':
      /* Struct or union type.  */
      dtype = parse_stab_struct_type (dhandle, info, typename, pp,
                                  descriptor == 's', typenums);
      break;

    case 'a':
      /* Array type.  */
      if (**pp != 'r')
       {
         bad_stab (orig);
         return DEBUG_TYPE_NULL;
       }
      ++*pp;

      dtype = parse_stab_array_type (dhandle, info, pp, stringp);
      break;

    case 'S':
      dtype = debug_make_set_type (dhandle,
                               parse_stab_type (dhandle, info,
                                              (const char *) NULL,
                                              pp,
                                              (debug_type **) NULL),
                               stringp);
      break;

    default:
      bad_stab (orig);
      return DEBUG_TYPE_NULL;
    }

  if (dtype == DEBUG_TYPE_NULL)
    return DEBUG_TYPE_NULL;

  if (typenums[0] != -1)
    {
      if (! stab_record_type (dhandle, info, typenums, dtype))
       return DEBUG_TYPE_NULL;
    }

  if (size != -1)
    {
      if (! debug_record_type_size (dhandle, dtype, (unsigned int) size))
       return DEBUG_TYPE_NULL;
    }

  return dtype;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean parse_stab_type_number ( const char **  pp,
int typenums 
) [static]

Definition at line 1600 of file stabs.c.

{
  const char *orig;

  orig = *pp;

  if (**pp != '(')
    {
      typenums[0] = 0;
      typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL);
    }
  else
    {
      ++*pp;
      typenums[0] = (int) parse_number (pp, (bfd_boolean *) NULL);
      if (**pp != ',')
       {
         bad_stab (orig);
         return FALSE;
       }
      ++*pp;
      typenums[1] = (int) parse_number (pp, (bfd_boolean *) NULL);
      if (**pp != ')')
       {
         bad_stab (orig);
         return FALSE;
       }
      ++*pp;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char * pop_bincl ( struct stab_handle info) [static]

Definition at line 3154 of file stabs.c.

{
  struct bincl_file *o;

  o = info->bincl_stack;
  if (o == NULL)
    return info->main_filename;
  info->bincl_stack = o->next_stack;

  o->file_types = info->file_types[o->file];

  if (info->bincl_stack == NULL)
    return info->main_filename;
  return info->bincl_stack->name;
}

Here is the caller graph for this function:

static void push_bincl ( struct stab_handle info,
const char *  name,
bfd_vma  hash 
) [static]

Definition at line 3128 of file stabs.c.

{
  struct bincl_file *n;

  n = (struct bincl_file *) xmalloc (sizeof *n);
  n->next = info->bincl_list;
  n->next_stack = info->bincl_stack;
  n->name = name;
  n->hash = hash;
  n->file = info->files;
  n->file_types = NULL;
  info->bincl_list = n;
  info->bincl_stack = n;

  ++info->files;
  info->file_types = ((struct stab_types **)
                    xrealloc (info->file_types,
                            (info->files
                             * sizeof *info->file_types)));
  info->file_types[n->file] = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char * savestring ( const char *  start,
int  len 
) [static]

Definition at line 215 of file stabs.c.

{
  char *ret;

  ret = (char *) xmalloc (len + 1);
  memcpy (ret, start, len);
  ret[len] = '\0';
  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void stab_bad_demangle ( const char *  s) [static]

Definition at line 3642 of file stabs.c.

{
  fprintf (stderr, _("bad mangled name `%s'\n"), s);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_arg ( struct stab_demangle_info minfo,
const char **  pp,
debug_type **  pargs,
unsigned int pcount,
unsigned int palloc 
) [static]

Definition at line 4488 of file stabs.c.

{
  const char *start;
  debug_type type;

  start = *pp;
  if (! stab_demangle_type (minfo, pp,
                         pargs == NULL ? (debug_type *) NULL : &type)
      || ! stab_demangle_remember_type (minfo, start, *pp - start))
    return FALSE;

  if (pargs != NULL)
    {
      if (type == DEBUG_TYPE_NULL)
       return FALSE;

      if (*pcount + 1 >= *palloc)
       {
         *palloc += 10;
         *pargs = ((debug_type *)
                  xrealloc (*pargs, *palloc * sizeof **pargs));
       }
      (*pargs)[*pcount] = type;
      ++*pcount;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_args ( struct stab_demangle_info minfo,
const char **  pp,
debug_type **  pargs,
bfd_boolean pvarargs 
) [static]

Definition at line 4408 of file stabs.c.

{
  const char *orig;
  unsigned int alloc, count;

  orig = *pp;

  alloc = 10;
  if (pargs != NULL)
    {
      *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs);
      *pvarargs = FALSE;
    }
  count = 0;

  while (**pp != '_' && **pp != '\0' && **pp != 'e')
    {
      if (**pp == 'N' || **pp == 'T')
       {
         char temptype;
         unsigned int r, t;

         temptype = **pp;
         ++*pp;

         if (temptype == 'T')
           r = 1;
         else
           {
             if (! stab_demangle_get_count (pp, &r))
              {
                stab_bad_demangle (orig);
                return FALSE;
              }
           }

         if (! stab_demangle_get_count (pp, &t))
           {
             stab_bad_demangle (orig);
             return FALSE;
           }

         if (t >= minfo->typestring_count)
           {
             stab_bad_demangle (orig);
             return FALSE;
           }
         while (r-- > 0)
           {
             const char *tem;

             tem = minfo->typestrings[t].typestring;
             if (! stab_demangle_arg (minfo, &tem, pargs, &count, &alloc))
              return FALSE;
           }
       }
      else
       {
         if (! stab_demangle_arg (minfo, pp, pargs, &count, &alloc))
           return FALSE;
       }
    }

  if (pargs != NULL)
    (*pargs)[count] = DEBUG_TYPE_NULL;

  if (**pp == 'e')
    {
      if (pargs != NULL)
       *pvarargs = TRUE;
      ++*pp;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type * stab_demangle_argtypes ( void *  dhandle,
struct stab_handle info,
const char *  physname,
bfd_boolean pvarargs,
unsigned int  physname_len 
) [static]

Definition at line 3703 of file stabs.c.

{
  struct stab_demangle_info minfo;

  /* Check for the g++ V3 ABI.  */
  if (physname[0] == '_' && physname[1] == 'Z')
    return stab_demangle_v3_argtypes (dhandle, info, physname, pvarargs);

  minfo.dhandle = dhandle;
  minfo.info = info;
  minfo.args = NULL;
  minfo.varargs = FALSE;
  minfo.typestring_alloc = 10;
  minfo.typestrings = ((struct stab_demangle_typestring *)
                     xmalloc (minfo.typestring_alloc
                            * sizeof *minfo.typestrings));
  minfo.typestring_count = 0;

  /* cplus_demangle checks for special GNU mangled forms, but we can't
     see any of them in mangled method argument types.  */

  if (! stab_demangle_prefix (&minfo, &physname, physname_len))
    goto error_return;

  if (*physname != '\0')
    {
      if (! stab_demangle_signature (&minfo, &physname))
       goto error_return;
    }

  free (minfo.typestrings);
  minfo.typestrings = NULL;

  if (minfo.args == NULL)
    fprintf (stderr, _("no argument types in mangled string\n"));

  *pvarargs = minfo.varargs;
  return minfo.args;

 error_return:
  if (minfo.typestrings != NULL)
    free (minfo.typestrings);
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_class ( struct stab_demangle_info ,
const char **  ,
const char **   
) [static]

Here is the caller graph for this function:

static bfd_boolean stab_demangle_class ( struct stab_demangle_info *minfo  ATTRIBUTE_UNUSED,
const char **  pp,
const char **  pstart 
) [static]

Definition at line 4381 of file stabs.c.

{
  const char *orig;
  unsigned int n;

  orig = *pp;

  n = stab_demangle_count (pp);
  if (strlen (*pp) < n)
    {
      stab_bad_demangle (orig);
      return FALSE;
    }

  if (pstart != NULL)
    *pstart = *pp;

  *pp += n;

  return TRUE;
}

Here is the call graph for this function:

static unsigned int stab_demangle_count ( const char **  pp) [static]

Definition at line 3650 of file stabs.c.

{
  unsigned int count;

  count = 0;
  while (ISDIGIT (**pp))
    {
      count *= 10;
      count += **pp - '0';
      ++*pp;
    }
  return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_function_name ( struct stab_demangle_info minfo,
const char **  pp,
const char *  scan 
) [static]

Definition at line 3830 of file stabs.c.

{
  const char *name;

  /* The string from *pp to scan is the name of the function.  We
     don't care about the name, since we just looking for argument
     types.  However, for conversion operators, the name may include a
     type which we must remember in order to handle backreferences.  */

  name = *pp;
  *pp = scan + 2;

  if (*pp - name >= 5
          && CONST_STRNEQ (name, "type")
          && (name[4] == '$' || name[4] == '.'))
    {
      const char *tem;

      /* This is a type conversion operator.  */
      tem = name + 5;
      if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
       return FALSE;
    }
  else if (name[0] == '_'
          && name[1] == '_'
          && name[2] == 'o'
          && name[3] == 'p')
    {
      const char *tem;

      /* This is a type conversion operator.  */
      tem = name + 4;
      if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL))
       return FALSE;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_fund_type ( struct stab_demangle_info minfo,
const char **  pp,
debug_type ptype 
) [static]

Definition at line 4790 of file stabs.c.

{
  const char *orig;
  bfd_boolean constp, volatilep, unsignedp, signedp;
  bfd_boolean done;

  orig = *pp;

  constp = FALSE;
  volatilep = FALSE;
  unsignedp = FALSE;
  signedp = FALSE;

  done = FALSE;
  while (! done)
    {
      switch (**pp)
       {
       case 'C':
         constp = TRUE;
         ++*pp;
         break;

       case 'U':
         unsignedp = TRUE;
         ++*pp;
         break;

       case 'S':
         signedp = TRUE;
         ++*pp;
         break;

       case 'V':
         volatilep = TRUE;
         ++*pp;
         break;

       default:
         done = TRUE;
         break;
       }
    }

  switch (**pp)
    {
    case '\0':
    case '_':
      /* cplus_demangle permits this, but I don't know what it means.  */
      stab_bad_demangle (orig);
      break;

    case 'v': /* void */
      if (ptype != NULL)
       {
         *ptype = debug_find_named_type (minfo->dhandle, "void");
         if (*ptype == DEBUG_TYPE_NULL)
           *ptype = debug_make_void_type (minfo->dhandle);
       }
      ++*pp;
      break;

    case 'x': /* long long */
      if (ptype != NULL)
       {
         *ptype = debug_find_named_type (minfo->dhandle,
                                     (unsignedp
                                      ? "long long unsigned int"
                                      : "long long int"));
         if (*ptype == DEBUG_TYPE_NULL)
           *ptype = debug_make_int_type (minfo->dhandle, 8, unsignedp);
       }
      ++*pp;
      break;

    case 'l': /* long */
      if (ptype != NULL)
       {
         *ptype = debug_find_named_type (minfo->dhandle,
                                     (unsignedp
                                      ? "long unsigned int"
                                      : "long int"));
         if (*ptype == DEBUG_TYPE_NULL)
           *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
       }
      ++*pp;
      break;

    case 'i': /* int */
      if (ptype != NULL)
       {
         *ptype = debug_find_named_type (minfo->dhandle,
                                     (unsignedp
                                      ? "unsigned int"
                                      : "int"));
         if (*ptype == DEBUG_TYPE_NULL)
           *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp);
       }
      ++*pp;
      break;

    case 's': /* short */
      if (ptype != NULL)
       {
         *ptype = debug_find_named_type (minfo->dhandle,
                                     (unsignedp
                                      ? "short unsigned int"
                                      : "short int"));
         if (*ptype == DEBUG_TYPE_NULL)
           *ptype = debug_make_int_type (minfo->dhandle, 2, unsignedp);
       }
      ++*pp;
      break;

    case 'b': /* bool */
      if (ptype != NULL)
       {
         *ptype = debug_find_named_type (minfo->dhandle, "bool");
         if (*ptype == DEBUG_TYPE_NULL)
           *ptype = debug_make_bool_type (minfo->dhandle, 4);
       }
      ++*pp;
      break;

    case 'c': /* char */
      if (ptype != NULL)
       {
         *ptype = debug_find_named_type (minfo->dhandle,
                                     (unsignedp
                                      ? "unsigned char"
                                      : (signedp
                                         ? "signed char"
                                         : "char")));
         if (*ptype == DEBUG_TYPE_NULL)
           *ptype = debug_make_int_type (minfo->dhandle, 1, unsignedp);
       }
      ++*pp;
      break;

    case 'w': /* wchar_t */
      if (ptype != NULL)
       {
         *ptype = debug_find_named_type (minfo->dhandle, "__wchar_t");
         if (*ptype == DEBUG_TYPE_NULL)
           *ptype = debug_make_int_type (minfo->dhandle, 2, TRUE);
       }
      ++*pp;
      break;

    case 'r': /* long double */
      if (ptype != NULL)
       {
         *ptype = debug_find_named_type (minfo->dhandle, "long double");
         if (*ptype == DEBUG_TYPE_NULL)
           *ptype = debug_make_float_type (minfo->dhandle, 8);
       }
      ++*pp;
      break;

    case 'd': /* double */
      if (ptype != NULL)
       {
         *ptype = debug_find_named_type (minfo->dhandle, "double");
         if (*ptype == DEBUG_TYPE_NULL)
           *ptype = debug_make_float_type (minfo->dhandle, 8);
       }
      ++*pp;
      break;

    case 'f': /* float */
      if (ptype != NULL)
       {
         *ptype = debug_find_named_type (minfo->dhandle, "float");
         if (*ptype == DEBUG_TYPE_NULL)
           *ptype = debug_make_float_type (minfo->dhandle, 4);
       }
      ++*pp;
      break;

    case 'G':
      ++*pp;
      if (! ISDIGIT (**pp))
       {
         stab_bad_demangle (orig);
         return FALSE;
       }
      /* Fall through.  */
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
      {
       const char *hold;

       if (! stab_demangle_class (minfo, pp, &hold))
         return FALSE;
       if (ptype != NULL)
         {
           char *name;

           name = savestring (hold, *pp - hold);
           *ptype = debug_find_named_type (minfo->dhandle, name);
           free (name);
           if (*ptype == DEBUG_TYPE_NULL)
             {
              /* FIXME: It is probably incorrect to assume that
                   undefined types are tagged types.  */
              *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info,
                                          hold, *pp - hold,
                                          DEBUG_KIND_ILLEGAL);
              if (*ptype == DEBUG_TYPE_NULL)
                return FALSE;
             }
         }
      }
      break;

    case 't':
      {
       char *name;

       if (! stab_demangle_template (minfo, pp,
                                  ptype != NULL ? &name : NULL))
         return FALSE;
       if (ptype != NULL)
         {
           *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info,
                                       name, strlen (name),
                                       DEBUG_KIND_CLASS);
           free (name);
           if (*ptype == DEBUG_TYPE_NULL)
             return FALSE;
         }
      }
      break;

    default:
      stab_bad_demangle (orig);
      return FALSE;
    }

  if (ptype != NULL)
    {
      if (constp)
       *ptype = debug_make_const_type (minfo->dhandle, *ptype);
      if (volatilep)
       *ptype = debug_make_volatile_type (minfo->dhandle, *ptype);
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_get_count ( const char **  pp,
unsigned int pi 
) [static]

Definition at line 3668 of file stabs.c.

{
  if (! ISDIGIT (**pp))
    return FALSE;

  *pi = **pp - '0';
  ++*pp;
  if (ISDIGIT (**pp))
    {
      unsigned int count;
      const char *p;

      count = *pi;
      p = *pp;
      do
       {
         count *= 10;
         count += *p - '0';
         ++p;
       }
      while (ISDIGIT (*p));
      if (*p == '_')
       {
         *pp = p + 1;
         *pi = count;
       }
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_prefix ( struct stab_demangle_info minfo,
const char **  pp,
unsigned int  physname_len 
) [static]

Definition at line 3753 of file stabs.c.

{
  const char *scan;
  unsigned int i;

  /* cplus_demangle checks for global constructors and destructors,
     but we can't see them in mangled argument types.  */

  if (physname_len)
    scan = *pp + physname_len;
  else
    {
      /* Look for `__'.  */
      scan = *pp;
      do
       scan = strchr (scan, '_');
      while (scan != NULL && *++scan != '_');

      if (scan == NULL)
       {
         stab_bad_demangle (*pp);
         return FALSE;
       }

      --scan;

      /* We found `__'; move ahead to the last contiguous `__' pair.  */
      i = strspn (scan, "_");
      if (i > 2)
       scan += i - 2;
    }

  if (scan == *pp
      && (ISDIGIT (scan[2])
         || scan[2] == 'Q'
         || scan[2] == 't'))
    {
      /* This is a GNU style constructor name.  */
      *pp = scan + 2;
      return TRUE;
    }
  else if (scan == *pp
          && ! ISDIGIT (scan[2])
          && scan[2] != 't')
    {
      /* Look for the `__' that separates the prefix from the
         signature.  */
      while (*scan == '_')
       ++scan;
      scan = strstr (scan, "__");
      if (scan == NULL || scan[2] == '\0')
       {
         stab_bad_demangle (*pp);
         return FALSE;
       }

      return stab_demangle_function_name (minfo, pp, scan);
    }
  else if (scan[2] != '\0')
    {
      /* The name doesn't start with `__', but it does contain `__'.  */
      return stab_demangle_function_name (minfo, pp, scan);
    }
  else
    {
      stab_bad_demangle (*pp);
      return FALSE;
    }
  /*NOTREACHED*/
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_qualified ( struct stab_demangle_info minfo,
const char **  pp,
debug_type ptype 
) [static]

Definition at line 3988 of file stabs.c.

{
  const char *orig;
  const char *p;
  unsigned int qualifiers;
  debug_type context;

  orig = *pp;

  switch ((*pp)[1])
    {
    case '_':
      /* GNU mangled name with more than 9 classes.  The count is
        preceded by an underscore (to distinguish it from the <= 9
        case) and followed by an underscore.  */
      p = *pp + 2;
      if (! ISDIGIT (*p) || *p == '0')
       {
         stab_bad_demangle (orig);
         return FALSE;
       }
      qualifiers = atoi (p);
      while (ISDIGIT (*p))
       ++p;
      if (*p != '_')
       {
         stab_bad_demangle (orig);
         return FALSE;
       }
      *pp = p + 1;
      break;

    case '1': case '2': case '3': case '4': case '5':
    case '6': case '7': case '8': case '9':
      qualifiers = (*pp)[1] - '0';
      /* Skip an optional underscore after the count.  */
      if ((*pp)[2] == '_')
       ++*pp;
      *pp += 2;
      break;

    case '0':
    default:
      stab_bad_demangle (orig);
      return FALSE;
    }

  context = DEBUG_TYPE_NULL;

  /* Pick off the names.  */
  while (qualifiers-- > 0)
    {
      if (**pp == '_')
       ++*pp;
      if (**pp == 't')
       {
         char *name;

         if (! stab_demangle_template (minfo, pp,
                                   ptype != NULL ? &name : NULL))
           return FALSE;

         if (ptype != NULL)
           {
             context = stab_find_tagged_type (minfo->dhandle, minfo->info,
                                          name, strlen (name),
                                          DEBUG_KIND_CLASS);
             free (name);
             if (context == DEBUG_TYPE_NULL)
              return FALSE;
           }
       }
      else
       {
         unsigned int len;

         len = stab_demangle_count (pp);
         if (strlen (*pp) < len)
           {
             stab_bad_demangle (orig);
             return FALSE;
           }

         if (ptype != NULL)
           {
             const debug_field *fields;

             fields = NULL;
             if (context != DEBUG_TYPE_NULL)
              fields = debug_get_fields (minfo->dhandle, context);

             context = DEBUG_TYPE_NULL;

             if (fields != NULL)
              {
                char *name;

                /* Try to find the type by looking through the
                     fields of context until we find a field with the
                     same type.  This ought to work for a class
                     defined within a class, but it won't work for,
                     e.g., an enum defined within a class.  stabs does
                     not give us enough information to figure out the
                     latter case.  */

                name = savestring (*pp, len);

                for (; *fields != DEBUG_FIELD_NULL; fields++)
                  {
                    debug_type ft;
                    const char *dn;

                    ft = debug_get_field_type (minfo->dhandle, *fields);
                    if (ft == NULL)
                     return FALSE;
                    dn = debug_get_type_name (minfo->dhandle, ft);
                    if (dn != NULL && strcmp (dn, name) == 0)
                     {
                       context = ft;
                       break;
                     }
                  }

                free (name);
              }

             if (context == DEBUG_TYPE_NULL)
              {
                /* We have to fall back on finding the type by name.
                     If there are more types to come, then this must
                     be a class.  Otherwise, it could be anything.  */

                if (qualifiers == 0)
                  {
                    char *name;

                    name = savestring (*pp, len);
                    context = debug_find_named_type (minfo->dhandle,
                                                 name);
                    free (name);
                  }

                if (context == DEBUG_TYPE_NULL)
                  {
                    context = stab_find_tagged_type (minfo->dhandle,
                                                 minfo->info,
                                                 *pp, len,
                                                 (qualifiers == 0
                                                 ? DEBUG_KIND_ILLEGAL
                                                 : DEBUG_KIND_CLASS));
                    if (context == DEBUG_TYPE_NULL)
                     return FALSE;
                  }
              }
           }

         *pp += len;
       }
    }

  if (ptype != NULL)
    *ptype = context;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_remember_type ( struct stab_demangle_info minfo,
const char *  p,
int  len 
) [static]

Definition at line 5044 of file stabs.c.

{
  if (minfo->typestring_count >= minfo->typestring_alloc)
    {
      minfo->typestring_alloc += 10;
      minfo->typestrings = ((struct stab_demangle_typestring *)
                         xrealloc (minfo->typestrings,
                                  (minfo->typestring_alloc
                                   * sizeof *minfo->typestrings)));
    }

  minfo->typestrings[minfo->typestring_count].typestring = p;
  minfo->typestrings[minfo->typestring_count].len = (unsigned int) len;
  ++minfo->typestring_count;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_signature ( struct stab_demangle_info minfo,
const char **  pp 
) [static]

Definition at line 3874 of file stabs.c.

{
  const char *orig;
  bfd_boolean expect_func, func_done;
  const char *hold;

  orig = *pp;

  expect_func = FALSE;
  func_done = FALSE;
  hold = NULL;

  while (**pp != '\0')
    {
      switch (**pp)
       {
       case 'Q':
         hold = *pp;
         if (! stab_demangle_qualified (minfo, pp, (debug_type *) NULL)
             || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
           return FALSE;
         expect_func = TRUE;
         hold = NULL;
         break;

       case 'S':
         /* Static member function.  FIXME: Can this happen?  */
         if (hold == NULL)
           hold = *pp;
         ++*pp;
         break;

       case 'C':
         /* Const member function.  */
         if (hold == NULL)
           hold = *pp;
         ++*pp;
         break;

       case '0': case '1': case '2': case '3': case '4':
       case '5': case '6': case '7': case '8': case '9':
         if (hold == NULL)
           hold = *pp;
         if (! stab_demangle_class (minfo, pp, (const char **) NULL)
             || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
           return FALSE;
         expect_func = TRUE;
         hold = NULL;
         break;

       case 'F':
         /* Function.  I don't know if this actually happens with g++
             output.  */
         hold = NULL;
         func_done = TRUE;
         ++*pp;
         if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
           return FALSE;
         break;

       case 't':
         /* Template.  */
         if (hold == NULL)
           hold = *pp;
         if (! stab_demangle_template (minfo, pp, (char **) NULL)
             || ! stab_demangle_remember_type (minfo, hold, *pp - hold))
           return FALSE;
         hold = NULL;
         expect_func = TRUE;
         break;

       case '_':
         /* At the outermost level, we cannot have a return type
            specified, so if we run into another '_' at this point we
            are dealing with a mangled name that is either bogus, or
            has been mangled by some algorithm we don't know how to
            deal with.  So just reject the entire demangling.  */
         stab_bad_demangle (orig);
         return FALSE;

       default:
         /* Assume we have stumbled onto the first outermost function
            argument token, and start processing args.  */
         func_done = TRUE;
         if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
           return FALSE;
         break;
       }

      if (expect_func)
       {
         func_done = TRUE;
         if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
           return FALSE;
       }
    }

  if (! func_done)
    {
      /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
        bar__3fooi is 'foo::bar(int)'.  We get here when we find the
        first case, and need to ensure that the '(void)' gets added
        to the current declp.  */
      if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs))
       return FALSE;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_template ( struct stab_demangle_info minfo,
const char **  pp,
char **  pname 
) [static]

Definition at line 4159 of file stabs.c.

{
  const char *orig;
  unsigned int r, i;

  orig = *pp;

  ++*pp;

  /* Skip the template name.  */
  r = stab_demangle_count (pp);
  if (r == 0 || strlen (*pp) < r)
    {
      stab_bad_demangle (orig);
      return FALSE;
    }
  *pp += r;

  /* Get the size of the parameter list.  */
  if (stab_demangle_get_count (pp, &r) == 0)
    {
      stab_bad_demangle (orig);
      return FALSE;
    }

  for (i = 0; i < r; i++)
    {
      if (**pp == 'Z')
       {
         /* This is a type parameter.  */
         ++*pp;
         if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
           return FALSE;
       }
      else
       {
         const char *old_p;
         bfd_boolean pointerp, realp, integralp, charp, boolp;
         bfd_boolean done;

         old_p = *pp;
         pointerp = FALSE;
         realp = FALSE;
         integralp = FALSE;
         charp = FALSE;
         boolp = FALSE;
         done = FALSE;

         /* This is a value parameter.  */

         if (! stab_demangle_type (minfo, pp, (debug_type *) NULL))
           return FALSE;

         while (*old_p != '\0' && ! done)
           {
             switch (*old_p)
              {
              case 'P':
              case 'p':
              case 'R':
                pointerp = TRUE;
                done = TRUE;
                break;
              case 'C':     /* Const.  */
              case 'S':     /* Signed.  */
              case 'U':     /* Unsigned.  */
              case 'V':     /* Volatile.  */
              case 'F':     /* Function.  */
              case 'M':     /* Member function.  */
              case 'O':     /* ??? */
                ++old_p;
                break;
              case 'Q':     /* Qualified name.  */
                integralp = TRUE;
                done = TRUE;
                break;
              case 'T':     /* Remembered type.  */
                abort ();
              case 'v':     /* Void.  */
                abort ();
              case 'x':     /* Long long.  */
              case 'l':     /* Long.  */
              case 'i':     /* Int.  */
              case 's':     /* Short.  */
              case 'w':     /* Wchar_t.  */
                integralp = TRUE;
                done = TRUE;
                break;
              case 'b':     /* Bool.  */
                boolp = TRUE;
                done = TRUE;
                break;
              case 'c':     /* Char.  */
                charp = TRUE;
                done = TRUE;
                break;
              case 'r':     /* Long double.  */
              case 'd':     /* Double.  */
              case 'f':     /* Float.  */
                realp = TRUE;
                done = TRUE;
                break;
              default:
                /* Assume it's a user defined integral type.  */
                integralp = TRUE;
                done = TRUE;
                break;
              }
           }

         if (integralp)
           {
             if (**pp == 'm')
              ++*pp;
             while (ISDIGIT (**pp))
              ++*pp;
           }
         else if (charp)
           {
             unsigned int val;

             if (**pp == 'm')
              ++*pp;
             val = stab_demangle_count (pp);
             if (val == 0)
              {
                stab_bad_demangle (orig);
                return FALSE;
              }
           }
         else if (boolp)
           {
             unsigned int val;

             val = stab_demangle_count (pp);
             if (val != 0 && val != 1)
              {
                stab_bad_demangle (orig);
                return FALSE;
              }
           }
         else if (realp)
           {
             if (**pp == 'm')
              ++*pp;
             while (ISDIGIT (**pp))
              ++*pp;
             if (**pp == '.')
              {
                ++*pp;
                while (ISDIGIT (**pp))
                  ++*pp;
              }
             if (**pp == 'e')
              {
                ++*pp;
                while (ISDIGIT (**pp))
                  ++*pp;
              }
           }
         else if (pointerp)
           {
             unsigned int len;

             len = stab_demangle_count (pp);
             if (len == 0)
              {
                stab_bad_demangle (orig);
                return FALSE;
              }
             *pp += len;
           }
       }
    }

  /* We can translate this to a string fairly easily by invoking the
     regular demangling routine.  */
  if (pname != NULL)
    {
      char *s1, *s2, *s3, *s4 = NULL;
      char *from, *to;

      s1 = savestring (orig, *pp - orig);

      s2 = concat ("NoSuchStrinG__", s1, (const char *) NULL);

      free (s1);

      s3 = cplus_demangle (s2, DMGL_ANSI);

      free (s2);

      if (s3 != NULL)
       s4 = strstr (s3, "::NoSuchStrinG");
      if (s3 == NULL || s4 == NULL)
       {
         stab_bad_demangle (orig);
         if (s3 != NULL)
           free (s3);
         return FALSE;
       }

      /* Eliminating all spaces, except those between > characters,
         makes it more likely that the demangled name will match the
         name which g++ used as the structure name.  */
      for (from = to = s3; from != s4; ++from)
       if (*from != ' '
           || (from[1] == '>' && from > s3 && from[-1] == '>'))
         *to++ = *from;

      *pname = savestring (s3, to - s3);

      free (s3);
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_demangle_type ( struct stab_demangle_info minfo,
const char **  pp,
debug_type ptype 
) [static]

Definition at line 4523 of file stabs.c.

{
  const char *orig;

  orig = *pp;

  switch (**pp)
    {
    case 'P':
    case 'p':
      /* A pointer type.  */
      ++*pp;
      if (! stab_demangle_type (minfo, pp, ptype))
       return FALSE;
      if (ptype != NULL)
       *ptype = debug_make_pointer_type (minfo->dhandle, *ptype);
      break;

    case 'R':
      /* A reference type.  */
      ++*pp;
      if (! stab_demangle_type (minfo, pp, ptype))
       return FALSE;
      if (ptype != NULL)
       *ptype = debug_make_reference_type (minfo->dhandle, *ptype);
      break;

    case 'A':
      /* An array.  */
      {
       unsigned long high;

       ++*pp;
       high = 0;
       while (**pp != '\0' && **pp != '_')
         {
           if (! ISDIGIT (**pp))
             {
              stab_bad_demangle (orig);
              return FALSE;
             }
           high *= 10;
           high += **pp - '0';
           ++*pp;
         }
       if (**pp != '_')
         {
           stab_bad_demangle (orig);
           return FALSE;
         }
       ++*pp;

       if (! stab_demangle_type (minfo, pp, ptype))
         return FALSE;
       if (ptype != NULL)
         {
           debug_type int_type;

           int_type = debug_find_named_type (minfo->dhandle, "int");
           if (int_type == NULL)
             int_type = debug_make_int_type (minfo->dhandle, 4, FALSE);
           *ptype = debug_make_array_type (minfo->dhandle, *ptype, int_type,
                                       0, high, FALSE);
         }
      }
      break;

    case 'T':
      /* A back reference to a remembered type.  */
      {
       unsigned int i;
       const char *p;

       ++*pp;
       if (! stab_demangle_get_count (pp, &i))
         {
           stab_bad_demangle (orig);
           return FALSE;
         }
       if (i >= minfo->typestring_count)
         {
           stab_bad_demangle (orig);
           return FALSE;
         }
       p = minfo->typestrings[i].typestring;
       if (! stab_demangle_type (minfo, &p, ptype))
         return FALSE;
      }
      break;

    case 'F':
      /* A function.  */
      {
       debug_type *args;
       bfd_boolean varargs;

       ++*pp;
       if (! stab_demangle_args (minfo, pp,
                              (ptype == NULL
                               ? (debug_type **) NULL
                               : &args),
                              (ptype == NULL
                               ? (bfd_boolean *) NULL
                               : &varargs)))
         return FALSE;
       if (**pp != '_')
         {
           /* cplus_demangle will accept a function without a return
              type, but I don't know when that will happen, or what
              to do if it does.  */
           stab_bad_demangle (orig);
           return FALSE;
         }
       ++*pp;
       if (! stab_demangle_type (minfo, pp, ptype))
         return FALSE;
       if (ptype != NULL)
         *ptype = debug_make_function_type (minfo->dhandle, *ptype, args,
                                        varargs);

      }
      break;

    case 'M':
    case 'O':
      {
       bfd_boolean memberp, constp, volatilep;
       debug_type class_type = DEBUG_TYPE_NULL;
       debug_type *args;
       bfd_boolean varargs;
       unsigned int n;
       const char *name;

       memberp = **pp == 'M';
       constp = FALSE;
       volatilep = FALSE;
       args = NULL;
       varargs = FALSE;

       ++*pp;
       if (ISDIGIT (**pp))
         {
           n = stab_demangle_count (pp);
           if (strlen (*pp) < n)
             {
              stab_bad_demangle (orig);
              return FALSE;
             }
           name = *pp;
           *pp += n;

           if (ptype != NULL)
             {
              class_type = stab_find_tagged_type (minfo->dhandle,
                                              minfo->info,
                                              name, (int) n,
                                              DEBUG_KIND_CLASS);
              if (class_type == DEBUG_TYPE_NULL)
                return FALSE;
             }
         }
       else if (**pp == 'Q')
         {
           if (! stab_demangle_qualified (minfo, pp,
                                      (ptype == NULL
                                       ? (debug_type *) NULL
                                       : &class_type)))
             return FALSE;
         }
       else
         {
           stab_bad_demangle (orig);
           return FALSE;
         }

       if (memberp)
         {
           if (**pp == 'C')
             {
              constp = TRUE;
              ++*pp;
             }
           else if (**pp == 'V')
             {
              volatilep = TRUE;
              ++*pp;
             }
           if (**pp != 'F')
             {
              stab_bad_demangle (orig);
              return FALSE;
             }
           ++*pp;
           if (! stab_demangle_args (minfo, pp,
                                  (ptype == NULL
                                   ? (debug_type **) NULL
                                   : &args),
                                  (ptype == NULL
                                   ? (bfd_boolean *) NULL
                                   : &varargs)))
             return FALSE;
         }

       if (**pp != '_')
         {
           stab_bad_demangle (orig);
           return FALSE;
         }
       ++*pp;

       if (! stab_demangle_type (minfo, pp, ptype))
         return FALSE;

       if (ptype != NULL)
         {
           if (! memberp)
             *ptype = debug_make_offset_type (minfo->dhandle, class_type,
                                          *ptype);
           else
             {
              /* FIXME: We have no way to record constp or
                   volatilep.  */
              *ptype = debug_make_method_type (minfo->dhandle, *ptype,
                                           class_type, args, varargs);
             }
         }
      }
      break;

    case 'G':
      ++*pp;
      if (! stab_demangle_type (minfo, pp, ptype))
       return FALSE;
      break;

    case 'C':
      ++*pp;
      if (! stab_demangle_type (minfo, pp, ptype))
       return FALSE;
      if (ptype != NULL)
       *ptype = debug_make_const_type (minfo->dhandle, *ptype);
      break;

    case 'Q':
      {
       const char *hold;

       hold = *pp;
       if (! stab_demangle_qualified (minfo, pp, ptype))
         return FALSE;
      }
      break;

    default:
      if (! stab_demangle_fund_type (minfo, pp, ptype))
       return FALSE;
      break;
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type stab_demangle_v3_arg ( void *  dhandle,
struct stab_handle info,
struct demangle_component dc,
debug_type  context,
bfd_boolean pvarargs 
) [static]

Definition at line 5172 of file stabs.c.

{
  debug_type dt;

  if (pvarargs != NULL)
    *pvarargs = FALSE;

  switch (dc->type)
    {
      /* FIXME: These are demangle component types which we probably
        need to handle one way or another.  */
    case DEMANGLE_COMPONENT_LOCAL_NAME:
    case DEMANGLE_COMPONENT_TYPED_NAME:
    case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
    case DEMANGLE_COMPONENT_CTOR:
    case DEMANGLE_COMPONENT_DTOR:
    case DEMANGLE_COMPONENT_JAVA_CLASS:
    case DEMANGLE_COMPONENT_RESTRICT_THIS:
    case DEMANGLE_COMPONENT_VOLATILE_THIS:
    case DEMANGLE_COMPONENT_CONST_THIS:
    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
    case DEMANGLE_COMPONENT_COMPLEX:
    case DEMANGLE_COMPONENT_IMAGINARY:
    case DEMANGLE_COMPONENT_VENDOR_TYPE:
    case DEMANGLE_COMPONENT_ARRAY_TYPE:
    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
    case DEMANGLE_COMPONENT_ARGLIST:
    default:
      fprintf (stderr, _("Unrecognized demangle component %d\n"),
              (int) dc->type);
      return NULL;

    case DEMANGLE_COMPONENT_NAME:
      if (context != NULL)
       {
         const debug_field *fields;

         fields = debug_get_fields (dhandle, context);
         if (fields != NULL)
           {
             /* Try to find this type by looking through the context
               class.  */
             for (; *fields != DEBUG_FIELD_NULL; fields++)
              {
                debug_type ft;
                const char *dn;

                ft = debug_get_field_type (dhandle, *fields);
                if (ft == NULL)
                  return NULL;
                dn = debug_get_type_name (dhandle, ft);
                if (dn != NULL
                    && (int) strlen (dn) == dc->u.s_name.len
                    && strncmp (dn, dc->u.s_name.s, dc->u.s_name.len) == 0)
                  return ft;
              }
           }
       }
      return stab_find_tagged_type (dhandle, info, dc->u.s_name.s,
                                dc->u.s_name.len, DEBUG_KIND_ILLEGAL);

    case DEMANGLE_COMPONENT_QUAL_NAME:
      context = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left,
                                  context, NULL);
      if (context == NULL)
       return NULL;
      return stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.right,
                               context, NULL);

    case DEMANGLE_COMPONENT_TEMPLATE:
      {
       char *p;
       size_t alc;

       /* We print this component to get a class name which we can
          use.  FIXME: This probably won't work if the template uses
          template parameters which refer to an outer template.  */
       p = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, dc, 20, &alc);
       if (p == NULL)
         {
           fprintf (stderr, _("Failed to print demangled template\n"));
           return NULL;
         }
       dt = stab_find_tagged_type (dhandle, info, p, strlen (p),
                                DEBUG_KIND_CLASS);
       free (p);
       return dt;
      }

    case DEMANGLE_COMPONENT_SUB_STD:
      return stab_find_tagged_type (dhandle, info, dc->u.s_string.string,
                                dc->u.s_string.len, DEBUG_KIND_ILLEGAL);

    case DEMANGLE_COMPONENT_RESTRICT:
    case DEMANGLE_COMPONENT_VOLATILE:
    case DEMANGLE_COMPONENT_CONST:
    case DEMANGLE_COMPONENT_POINTER:
    case DEMANGLE_COMPONENT_REFERENCE:
      dt = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left, NULL,
                             NULL);
      if (dt == NULL)
       return NULL;

      switch (dc->type)
       {
       default:
         abort ();
       case DEMANGLE_COMPONENT_RESTRICT:
         /* FIXME: We have no way to represent restrict.  */
         return dt;
       case DEMANGLE_COMPONENT_VOLATILE:
         return debug_make_volatile_type (dhandle, dt);
       case DEMANGLE_COMPONENT_CONST:
         return debug_make_const_type (dhandle, dt);
       case DEMANGLE_COMPONENT_POINTER:
         return debug_make_pointer_type (dhandle, dt);
       case DEMANGLE_COMPONENT_REFERENCE:
         return debug_make_reference_type (dhandle, dt);
       }

    case DEMANGLE_COMPONENT_FUNCTION_TYPE:
      {
       debug_type *pargs;
       bfd_boolean varargs;

       if (dc->u.s_binary.left == NULL)
         {
           /* In this case the return type is actually unknown.
              However, I'm not sure this will ever arise in practice;
              normally an unknown return type would only appear at
              the top level, which is handled above.  */
           dt = debug_make_void_type (dhandle);
         }
       else
         dt = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left, NULL,
                                 NULL);
       if (dt == NULL)
         return NULL;

       pargs = stab_demangle_v3_arglist (dhandle, info,
                                     dc->u.s_binary.right,
                                     &varargs);
       if (pargs == NULL)
         return NULL;

       return debug_make_function_type (dhandle, dt, pargs, varargs);
      }

    case DEMANGLE_COMPONENT_BUILTIN_TYPE:
      {
       char *p;
       size_t alc;
       debug_type ret;

       /* We print this component in order to find out the type name.
          FIXME: Should we instead expose the
          demangle_builtin_type_info structure?  */
       p = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, dc, 20, &alc);
       if (p == NULL)
         {
           fprintf (stderr, _("Couldn't get demangled builtin type\n"));
           return NULL;
         }

       /* The mangling is based on the type, but does not itself
          indicate what the sizes are.  So we have to guess.  */
       if (strcmp (p, "signed char") == 0)
         ret = debug_make_int_type (dhandle, 1, FALSE);
       else if (strcmp (p, "bool") == 0)
         ret = debug_make_bool_type (dhandle, 1);
       else if (strcmp (p, "char") == 0)
         ret = debug_make_int_type (dhandle, 1, FALSE);
       else if (strcmp (p, "double") == 0)
         ret = debug_make_float_type (dhandle, 8);
       else if (strcmp (p, "long double") == 0)
         ret = debug_make_float_type (dhandle, 8);
       else if (strcmp (p, "float") == 0)
         ret = debug_make_float_type (dhandle, 4);
       else if (strcmp (p, "__float128") == 0)
         ret = debug_make_float_type (dhandle, 16);
       else if (strcmp (p, "unsigned char") == 0)
         ret = debug_make_int_type (dhandle, 1, TRUE);
       else if (strcmp (p, "int") == 0)
         ret = debug_make_int_type (dhandle, 4, FALSE);
       else if (strcmp (p, "unsigned int") == 0)
         ret = debug_make_int_type (dhandle, 4, TRUE);
       else if (strcmp (p, "long") == 0)
         ret = debug_make_int_type (dhandle, 4, FALSE);
       else if (strcmp (p, "unsigned long") == 0)
         ret = debug_make_int_type (dhandle, 4, TRUE);
       else if (strcmp (p, "__int128") == 0)
         ret = debug_make_int_type (dhandle, 16, FALSE);
       else if (strcmp (p, "unsigned __int128") == 0)
         ret = debug_make_int_type (dhandle, 16, TRUE);
       else if (strcmp (p, "short") == 0)
         ret = debug_make_int_type (dhandle, 2, FALSE);
       else if (strcmp (p, "unsigned short") == 0)
         ret = debug_make_int_type (dhandle, 2, TRUE);
       else if (strcmp (p, "void") == 0)
         ret = debug_make_void_type (dhandle);
       else if (strcmp (p, "wchar_t") == 0)
         ret = debug_make_int_type (dhandle, 4, TRUE);
       else if (strcmp (p, "long long") == 0)
         ret = debug_make_int_type (dhandle, 8, FALSE);
       else if (strcmp (p, "unsigned long long") == 0)
         ret = debug_make_int_type (dhandle, 8, TRUE);
       else if (strcmp (p, "...") == 0)
         {
           if (pvarargs == NULL)
             fprintf (stderr, _("Unexpected demangled varargs\n"));
           else
             *pvarargs = TRUE;
           ret = NULL;
         }
       else
         {
           fprintf (stderr, _("Unrecognized demangled builtin type\n"));
           ret = NULL;
         }

       free (p);

       return ret;
      }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type * stab_demangle_v3_arglist ( void *  dhandle,
struct stab_handle info,
struct demangle_component arglist,
bfd_boolean pvarargs 
) [static]

Definition at line 5112 of file stabs.c.

{
  struct demangle_component *dc;
  unsigned int alloc, count;
  debug_type *pargs;

  alloc = 10;
  pargs = (debug_type *) xmalloc (alloc * sizeof *pargs);
  *pvarargs = FALSE;

  count = 0;

  for (dc = arglist;
       dc != NULL;
       dc = dc->u.s_binary.right)
    {
      debug_type arg;
      bfd_boolean varargs;

      if (dc->type != DEMANGLE_COMPONENT_ARGLIST)
       {
         fprintf (stderr, _("Unexpected type in v3 arglist demangling\n"));
         free (pargs);
         return NULL;
       }

      arg = stab_demangle_v3_arg (dhandle, info, dc->u.s_binary.left,
                              NULL, &varargs);
      if (arg == NULL)
       {
         if (varargs)
           {
             *pvarargs = TRUE;
             continue;
           }
         free (pargs);
         return NULL;
       }

      if (count + 1 >= alloc)
       {
         alloc += 10;
         pargs = (debug_type *) xrealloc (pargs, alloc * sizeof *pargs);
       }

      pargs[count] = arg;
      ++count;
    }

  pargs[count] = DEBUG_TYPE_NULL;

  return pargs;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type * stab_demangle_v3_argtypes ( void *  dhandle,
struct stab_handle info,
const char *  physname,
bfd_boolean pvarargs 
) [static]

Definition at line 5074 of file stabs.c.

{
  struct demangle_component *dc;
  void *mem;
  debug_type *pargs;

  dc = cplus_demangle_v3_components (physname, DMGL_PARAMS | DMGL_ANSI, &mem);
  if (dc == NULL)
    {
      stab_bad_demangle (physname);
      return NULL;
    }

  /* We expect to see TYPED_NAME, and the right subtree describes the
     function type.  */
  if (dc->type != DEMANGLE_COMPONENT_TYPED_NAME
      || dc->u.s_binary.right->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
    {
      fprintf (stderr, _("Demangled name is not a function\n"));
      free (mem);
      return NULL;
    }

  pargs = stab_demangle_v3_arglist (dhandle, info,
                                dc->u.s_binary.right->u.s_binary.right,
                                pvarargs);

  free (mem);

  return pargs;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_emit_pending_vars ( void *  dhandle,
struct stab_handle info 
) [static]

Definition at line 3232 of file stabs.c.

{
  struct stab_pending_var *v;

  v = info->pending;
  while (v != NULL)
    {
      struct stab_pending_var *next;

      if (! debug_record_variable (dhandle, v->name, v->type, v->kind, v->val))
       return FALSE;

      next = v->next;
      free (v);
      v = next;
    }

  info->pending = NULL;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type * stab_find_slot ( struct stab_handle info,
const int typenums 
) [static]

Definition at line 3257 of file stabs.c.

{
  int filenum;
  int index;
  struct stab_types **ps;

  filenum = typenums[0];
  index = typenums[1];

  if (filenum < 0 || (unsigned int) filenum >= info->files)
    {
      fprintf (stderr, _("Type file number %d out of range\n"), filenum);
      return NULL;
    }
  if (index < 0)
    {
      fprintf (stderr, _("Type index number %d out of range\n"), index);
      return NULL;
    }

  ps = info->file_types + filenum;

  while (index >= STAB_TYPES_SLOTS)
    {
      if (*ps == NULL)
       {
         *ps = (struct stab_types *) xmalloc (sizeof **ps);
         memset (*ps, 0, sizeof **ps);
       }
      ps = &(*ps)->next;
      index -= STAB_TYPES_SLOTS;
    }
  if (*ps == NULL)
    {
      *ps = (struct stab_types *) xmalloc (sizeof **ps);
      memset (*ps, 0, sizeof **ps);
    }

  return (*ps)->types + index;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type stab_find_tagged_type ( void *  dhandle,
struct stab_handle info,
const char *  p,
int  len,
enum debug_type_kind  kind 
) [static]

Definition at line 3521 of file stabs.c.

{
  char *name;
  debug_type dtype;
  struct stab_tag *st;

  name = savestring (p, len);

  /* We pass DEBUG_KIND_ILLEGAL because we want all tags in the same
     namespace.  This is right for C, and I don't know how to handle
     other languages.  FIXME.  */
  dtype = debug_find_tagged_type (dhandle, name, DEBUG_KIND_ILLEGAL);
  if (dtype != DEBUG_TYPE_NULL)
    {
      free (name);
      return dtype;
    }

  /* We need to allocate an entry on the undefined tag list.  */
  for (st = info->tags; st != NULL; st = st->next)
    {
      if (st->name[0] == name[0]
         && strcmp (st->name, name) == 0)
       {
         if (st->kind == DEBUG_KIND_ILLEGAL)
           st->kind = kind;
         free (name);
         break;
       }
    }
  if (st == NULL)
    {
      st = (struct stab_tag *) xmalloc (sizeof *st);
      memset (st, 0, sizeof *st);

      st->next = info->tags;
      st->name = name;
      st->kind = kind;
      st->slot = DEBUG_TYPE_NULL;
      st->type = debug_make_indirect_type (dhandle, &st->slot, name);
      info->tags = st;
    }

  return st->type;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type stab_find_type ( void *  dhandle,
struct stab_handle info,
const int typenums 
) [static]

Definition at line 3302 of file stabs.c.

{
  debug_type *slot;

  if (typenums[0] == 0 && typenums[1] < 0)
    {
      /* A negative type number indicates an XCOFF builtin type.  */
      return stab_xcoff_builtin_type (dhandle, info, typenums[1]);
    }

  slot = stab_find_slot (info, typenums);
  if (slot == NULL)
    return DEBUG_TYPE_NULL;

  if (*slot == DEBUG_TYPE_NULL)
    return debug_make_indirect_type (dhandle, slot, (const char *) NULL);

  return *slot;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean stab_record_type ( void *  ,
struct stab_handle ,
const int ,
debug_type   
) [static]

Here is the caller graph for this function:

static bfd_boolean stab_record_type ( void *dhandle  ATTRIBUTE_UNUSED,
struct stab_handle info,
const int typenums,
debug_type  type 
) [static]

Definition at line 3325 of file stabs.c.

{
  debug_type *slot;

  slot = stab_find_slot (info, typenums);
  if (slot == NULL)
    return FALSE;

  /* gdb appears to ignore type redefinitions, so we do as well.  */

  *slot = type;

  return TRUE;
}

Here is the call graph for this function:

static bfd_boolean stab_record_variable ( void *  dhandle,
struct stab_handle info,
const char *  name,
debug_type  type,
enum debug_var_kind  kind,
bfd_vma  val 
) [static]

Definition at line 3204 of file stabs.c.

{
  struct stab_pending_var *v;

  if ((kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
      || ! info->within_function
      || (info->gcc_compiled == 0 && info->n_opt_found))
    return debug_record_variable (dhandle, name, type, kind, val);

  v = (struct stab_pending_var *) xmalloc (sizeof *v);
  memset (v, 0, sizeof *v);

  v->next = info->pending;
  v->name = name;
  v->type = type;
  v->kind = kind;
  v->val = val;
  info->pending = v;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static debug_type stab_xcoff_builtin_type ( void *  dhandle,
struct stab_handle info,
int  typenum 
) [static]

Definition at line 3344 of file stabs.c.

{
  debug_type rettype;
  const char *name;

  if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT)
    {
      fprintf (stderr, _("Unrecognized XCOFF type %d\n"), typenum);
      return DEBUG_TYPE_NULL;
    }
  if (info->xcoff_types[-typenum] != NULL)
    return info->xcoff_types[-typenum];

  switch (-typenum)
    {
    case 1:
      /* The size of this and all the other types are fixed, defined
        by the debugging format.  */
      name = "int";
      rettype = debug_make_int_type (dhandle, 4, FALSE);
      break;
    case 2:
      name = "char";
      rettype = debug_make_int_type (dhandle, 1, FALSE);
      break;
    case 3:
      name = "short";
      rettype = debug_make_int_type (dhandle, 2, FALSE);
      break;
    case 4:
      name = "long";
      rettype = debug_make_int_type (dhandle, 4, FALSE);
      break;
    case 5:
      name = "unsigned char";
      rettype = debug_make_int_type (dhandle, 1, TRUE);
      break;
    case 6:
      name = "signed char";
      rettype = debug_make_int_type (dhandle, 1, FALSE);
      break;
    case 7:
      name = "unsigned short";
      rettype = debug_make_int_type (dhandle, 2, TRUE);
      break;
    case 8:
      name = "unsigned int";
      rettype = debug_make_int_type (dhandle, 4, TRUE);
      break;
    case 9:
      name = "unsigned";
      rettype = debug_make_int_type (dhandle, 4, TRUE);
    case 10:
      name = "unsigned long";
      rettype = debug_make_int_type (dhandle, 4, TRUE);
      break;
    case 11:
      name = "void";
      rettype = debug_make_void_type (dhandle);
      break;
    case 12:
      /* IEEE single precision (32 bit).  */
      name = "float";
      rettype = debug_make_float_type (dhandle, 4);
      break;
    case 13:
      /* IEEE double precision (64 bit).  */
      name = "double";
      rettype = debug_make_float_type (dhandle, 8);
      break;
    case 14:
      /* This is an IEEE double on the RS/6000, and different machines
        with different sizes for "long double" should use different
        negative type numbers.  See stabs.texinfo.  */
      name = "long double";
      rettype = debug_make_float_type (dhandle, 8);
      break;
    case 15:
      name = "integer";
      rettype = debug_make_int_type (dhandle, 4, FALSE);
      break;
    case 16:
      name = "boolean";
      rettype = debug_make_bool_type (dhandle, 4);
      break;
    case 17:
      name = "short real";
      rettype = debug_make_float_type (dhandle, 4);
      break;
    case 18:
      name = "real";
      rettype = debug_make_float_type (dhandle, 8);
      break;
    case 19:
      /* FIXME */
      name = "stringptr";
      rettype = NULL;
      break;
    case 20:
      /* FIXME */
      name = "character";
      rettype = debug_make_int_type (dhandle, 1, TRUE);
      break;
    case 21:
      name = "logical*1";
      rettype = debug_make_bool_type (dhandle, 1);
      break;
    case 22:
      name = "logical*2";
      rettype = debug_make_bool_type (dhandle, 2);
      break;
    case 23:
      name = "logical*4";
      rettype = debug_make_bool_type (dhandle, 4);
      break;
    case 24:
      name = "logical";
      rettype = debug_make_bool_type (dhandle, 4);
      break;
    case 25:
      /* Complex type consisting of two IEEE single precision values.  */
      name = "complex";
      rettype = debug_make_complex_type (dhandle, 8);
      break;
    case 26:
      /* Complex type consisting of two IEEE double precision values.  */
      name = "double complex";
      rettype = debug_make_complex_type (dhandle, 16);
      break;
    case 27:
      name = "integer*1";
      rettype = debug_make_int_type (dhandle, 1, FALSE);
      break;
    case 28:
      name = "integer*2";
      rettype = debug_make_int_type (dhandle, 2, FALSE);
      break;
    case 29:
      name = "integer*4";
      rettype = debug_make_int_type (dhandle, 4, FALSE);
      break;
    case 30:
      /* FIXME */
      name = "wchar";
      rettype = debug_make_int_type (dhandle, 2, FALSE);
      break;
    case 31:
      name = "long long";
      rettype = debug_make_int_type (dhandle, 8, FALSE);
      break;
    case 32:
      name = "unsigned long long";
      rettype = debug_make_int_type (dhandle, 8, TRUE);
      break;
    case 33:
      name = "logical*8";
      rettype = debug_make_bool_type (dhandle, 8);
      break;
    case 34:
      name = "integer*8";
      rettype = debug_make_int_type (dhandle, 8, FALSE);
      break;
    default:
      abort ();
    }

  rettype = debug_name_type (dhandle, name, rettype);

  info->xcoff_types[-typenum] = rettype;

  return rettype;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void* start_stab ( void *dhandle  ATTRIBUTE_UNUSED,
bfd abfd,
bfd_boolean  sections,
asymbol **  syms,
long  symcount 
)

Definition at line 354 of file stabs.c.

{
  struct stab_handle *ret;

  ret = (struct stab_handle *) xmalloc (sizeof *ret);
  memset (ret, 0, sizeof *ret);
  ret->abfd = abfd;
  ret->sections = sections;
  ret->syms = syms;
  ret->symcount = symcount;
  ret->files = 1;
  ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types);
  ret->file_types[0] = NULL;
  ret->function_end = (bfd_vma) -1;
  return (void *) ret;
}

Here is the call graph for this function:

static void warn_stab ( const char *  p,
const char *  err 
) [static]

Definition at line 346 of file stabs.c.

{
  fprintf (stderr, _("Warning: %s: %s\n"), err, p);
}

Here is the call graph for this function:

Here is the caller graph for this function: