stabs.c File Reference

#include <stdio.h>
#include <ctype.h>
#include <bfd.h>
#include "bucomm.h"
#include <libiberty.h>
#include "demangle.h"
#include "debug.h"
#include "budbg.h"
#include "aout/aout64.h"
#include "aout/stab_gnu.h"

Include dependency graph for stabs.c:

Include dependency graph

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 BYTES_IN_WORD   4
#define XCOFF_TYPE_COUNT   34
#define STAB_TYPES_SLOTS   (16)
#define LLLOW   "01000000000000000000000;"
#define LLHIGH   "0777777777777777777777;"
#define ULLHIGH   "01777777777777777777777;"

Functions

char *savestring PARAMS ((const char *, int))
bfd_vma parse_number PARAMS ((const char **, bfd_boolean *))
void bad_stab PARAMS ((const char *))
void warn_stab PARAMS ((const char *, const char *))
bfd_boolean parse_stab_string PARAMS ((PTR, struct stab_handle *, int, int, bfd_vma, const char *))
debug_type parse_stab_type PARAMS ((PTR, struct stab_handle *, const char *, const char **, debug_type **))
bfd_boolean parse_stab_type_number PARAMS ((const char **, int *))
debug_type parse_stab_range_type PARAMS ((PTR, struct stab_handle *, const char *, const char **, const int *))
debug_type parse_stab_sun_builtin_type PARAMS ((PTR, const char **))
debug_type parse_stab_struct_type PARAMS ((PTR, struct stab_handle *, const char *, const char **, bfd_boolean, const int *))
bfd_boolean parse_stab_baseclasses PARAMS ((PTR, struct stab_handle *, const char **, debug_baseclass **))
bfd_boolean parse_stab_struct_fields PARAMS ((PTR, struct stab_handle *, const char **, debug_field **, bfd_boolean *))
bfd_boolean parse_stab_cpp_abbrev PARAMS ((PTR, struct stab_handle *, const char **, debug_field *))
bfd_boolean parse_stab_one_struct_field PARAMS ((PTR, struct stab_handle *, const char **, const char *, debug_field *, bfd_boolean *))
bfd_boolean parse_stab_members PARAMS ((PTR, struct stab_handle *, const char *, const char **, const int *, debug_method **))
debug_type parse_stab_argtypes PARAMS ((PTR, struct stab_handle *, debug_type, const char *, const char *, debug_type, const char *, bfd_boolean, bfd_boolean, const char **))
bfd_boolean parse_stab_tilde_field PARAMS ((PTR, struct stab_handle *, const char **, const int *, debug_type *, bfd_boolean *))
debug_type parse_stab_array_type PARAMS ((PTR, struct stab_handle *, const char **, bfd_boolean))
void push_bincl PARAMS ((struct stab_handle *, const char *, bfd_vma))
const char *pop_bincl PARAMS ((struct stab_handle *))
bfd_boolean stab_record_variable PARAMS ((PTR, struct stab_handle *, const char *, debug_type, enum debug_var_kind, bfd_vma))
bfd_boolean stab_emit_pending_vars PARAMS ((PTR, struct stab_handle *))
debug_type *stab_find_slot PARAMS ((struct stab_handle *, const int *))
debug_type stab_find_type PARAMS ((PTR, struct stab_handle *, const int *))
bfd_boolean stab_record_type PARAMS ((PTR, struct stab_handle *, const int *, debug_type))
debug_type stab_xcoff_builtin_type PARAMS ((PTR, struct stab_handle *, int))
debug_type stab_find_tagged_type PARAMS ((PTR, struct stab_handle *, const char *, int, enum debug_type_kind))
debug_type *stab_demangle_argtypes PARAMS ((PTR, struct stab_handle *, const char *, bfd_boolean *))
char * savestring (char *start, int len) const
bfd_vma parse_number (char **pp, bfd_boolean *poverflow) const
void bad_stab (char *p) const
void warn_stab (char *p, const char *err) const
PTR start_stab (PTR dhandle, bfd *abfd, bfd_boolean sections, asymbol **syms, long symcount)
bfd_boolean finish_stab (PTR dhandle, PTR handle)
bfd_boolean parse_stab (PTR dhandle, PTR handle, int type, int desc, bfd_vma value, const char *string)
bfd_boolean parse_stab_string (PTR dhandle, struct stab_handle *info, int stabtype, int desc, bfd_vma value, const char *string)
debug_type parse_stab_type (PTR dhandle, struct stab_handle *info, const char *typename, const char **pp, debug_type **slotp)
bfd_boolean parse_stab_type_number (char **pp, int *typenums) const
debug_type parse_stab_range_type (PTR dhandle, struct stab_handle *info, const char *typename, const char **pp, const int *typenums)
debug_type parse_stab_sun_builtin_type (PTR dhandle, const char **pp)
debug_type parse_stab_sun_floating_type (PTR dhandle, const char **pp)
debug_type parse_stab_enum_type (PTR dhandle, const char **pp)
debug_type parse_stab_struct_type (PTR dhandle, struct stab_handle *info, const char *tagname, const char **pp, bfd_boolean structp, const int *typenums)
bfd_boolean parse_stab_baseclasses (PTR dhandle, struct stab_handle *info, const char **pp, debug_baseclass **retp)
bfd_boolean parse_stab_struct_fields (PTR dhandle, struct stab_handle *info, const char **pp, debug_field **retp, bfd_boolean *staticsp)
bfd_boolean parse_stab_cpp_abbrev (PTR dhandle, struct stab_handle *info, const char **pp, debug_field *retp)
bfd_boolean parse_stab_one_struct_field (PTR dhandle, struct stab_handle *info, const char **pp, const char *p, debug_field *retp, bfd_boolean *staticsp)
bfd_boolean parse_stab_members (PTR dhandle, struct stab_handle *info, const char *tagname, const char **pp, const int *typenums, debug_method **retp)
debug_type parse_stab_argtypes (PTR 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)
bfd_boolean parse_stab_tilde_field (PTR dhandle, struct stab_handle *info, const char **pp, const int *typenums, debug_type *retvptrbase, bfd_boolean *retownvptr)
debug_type parse_stab_array_type (PTR dhandle, struct stab_handle *info, const char **pp, bfd_boolean stringp)
void push_bincl (struct stab_handle *info, const char *name, bfd_vma hash)
const char * pop_bincl (struct stab_handle *info)
bfd_boolean find_excl (struct stab_handle *info, const char *name, bfd_vma hash)
bfd_boolean stab_record_variable (PTR dhandle, struct stab_handle *info, const char *name, debug_type type, enum debug_var_kind kind, bfd_vma val)
bfd_boolean stab_emit_pending_vars (PTR dhandle, struct stab_handle *info)
debug_typestab_find_slot (struct stab_handle *info, const int *typenums)
debug_type stab_find_type (PTR dhandle, struct stab_handle *info, const int *typenums)
bfd_boolean stab_record_type (PTR dhandle, struct stab_handle *info, const int *typenums, debug_type type)
debug_type stab_xcoff_builtin_type (PTR dhandle, struct stab_handle *info, int typenum)
debug_type stab_find_tagged_type (PTR dhandle, struct stab_handle *info, const char *p, int len, enum debug_type_kind kind)
unsigned int stab_demangle_count PARAMS ((const char **))
bfd_boolean stab_demangle_get_count PARAMS ((const char **, unsigned int *))
bfd_boolean stab_demangle_prefix PARAMS ((struct stab_demangle_info *, const char **))
bfd_boolean stab_demangle_function_name PARAMS ((struct stab_demangle_info *, const char **, const char *))
bfd_boolean stab_demangle_qualified PARAMS ((struct stab_demangle_info *, const char **, debug_type *))
bfd_boolean stab_demangle_class PARAMS ((struct stab_demangle_info *, const char **, const char **))
bfd_boolean stab_demangle_args PARAMS ((struct stab_demangle_info *, const char **, debug_type **, bfd_boolean *))
bfd_boolean stab_demangle_arg PARAMS ((struct stab_demangle_info *, const char **, debug_type **, unsigned int *, unsigned int *))
bfd_boolean stab_demangle_remember_type PARAMS ((struct stab_demangle_info *, const char *, int))
void stab_bad_demangle (char *s) const
unsigned int stab_demangle_count (char **pp) const
bfd_boolean stab_demangle_get_count (char **pp, unsigned int *pi) const
debug_typestab_demangle_argtypes (PTR dhandle, struct stab_handle *info, const char *physname, bfd_boolean *pvarargs)
bfd_boolean stab_demangle_prefix (struct stab_demangle_info *minfo, const char **pp)
bfd_boolean stab_demangle_function_name (struct stab_demangle_info *minfo, const char **pp, const char *scan)
bfd_boolean stab_demangle_signature (struct stab_demangle_info *minfo, const char **pp)
bfd_boolean stab_demangle_qualified (struct stab_demangle_info *minfo, const char **pp, debug_type *ptype)
bfd_boolean stab_demangle_template (struct stab_demangle_info *minfo, const char **pp)
bfd_boolean stab_demangle_class (struct stab_demangle_info *minfo, const char **pp, const char **pstart)
bfd_boolean stab_demangle_args (struct stab_demangle_info *minfo, const char **pp, debug_type **pargs, bfd_boolean *pvarargs)
bfd_boolean stab_demangle_arg (struct stab_demangle_info *minfo, const char **pp, debug_type **pargs, unsigned int *pcount, unsigned int *palloc)
bfd_boolean stab_demangle_type (struct stab_demangle_info *minfo, const char **pp, debug_type *ptype)
bfd_boolean stab_demangle_fund_type (struct stab_demangle_info *minfo, const char **pp, debug_type *ptype)
bfd_boolean stab_demangle_remember_type (struct stab_demangle_info *minfo, const char *p, int len)

Define Documentation

#define BYTES_IN_WORD   4
 

#define LLHIGH   "0777777777777777777777;"
 

#define LLLOW   "01000000000000000000000;"
 

#define STAB_TYPES_SLOTS   (16)
 

#define ULLHIGH   "01777777777777777777777;"
 

#define XCOFF_TYPE_COUNT   34
 


Function Documentation

void bad_stab char *  p  )  const [static]
 

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

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

03221 {
03222   struct bincl_file *l;
03223 
03224   ++info->files;
03225   info->file_types = ((struct stab_types **)
03226                       xrealloc ((PTR) info->file_types,
03227                                 (info->files
03228                                  * sizeof *info->file_types)));
03229 
03230   for (l = info->bincl_list; l != NULL; l = l->next)
03231     if (l->hash == hash && strcmp (l->name, name) == 0)
03232       break;
03233   if (l == NULL)
03234     {
03235       warn_stab (name, "Undefined N_EXCL");
03236       info->file_types[info->files - 1] = NULL;
03237       return true;
03238     }
03239 
03240   info->file_types[info->files - 1] = l->file_types;
03241 
03242   return true;
03243 }

bfd_boolean finish_stab PTR  dhandle,
PTR  handle
 

00388 {
00389   struct stab_handle *info = (struct stab_handle *) handle;
00390   struct stab_tag *st;
00391 
00392   if (info->within_function)
00393     {
00394       if (! stab_emit_pending_vars (dhandle, info)
00395           || ! debug_end_function (dhandle, info->function_end))
00396         return false;
00397       info->within_function = false;
00398       info->function_end = (bfd_vma) -1;
00399     }
00400 
00401   for (st = info->tags; st != NULL; st = st->next)
00402     {
00403       enum debug_type_kind kind;
00404 
00405       kind = st->kind;
00406       if (kind == DEBUG_KIND_ILLEGAL)
00407         kind = DEBUG_KIND_STRUCT;
00408       st->slot = debug_make_undefined_tagged_type (dhandle, st->name, kind);
00409       if (st->slot == DEBUG_TYPE_NULL)
00410         return false;
00411     }
00412 
00413   return true;
00414 }

bfd_boolean stab_demangle_remember_type PARAMS (struct stab_demangle_info *, const char *, int)   )  [static]
 

bfd_boolean stab_demangle_arg PARAMS (struct stab_demangle_info *, const char **, debug_type **, unsigned int *, unsigned int *)   )  [static]
 

bfd_boolean stab_demangle_args PARAMS (struct stab_demangle_info *, const char **, debug_type **, bfd_boolean *)   )  [static]
 

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

bfd_boolean stab_demangle_fund_type PARAMS (struct stab_demangle_info *, const char **, debug_type *)   )  [static]
 

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

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

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

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

debug_type* stab_demangle_argtypes PARAMS (PTR, struct stab_handle *, const char *, bfd_boolean *)   )  [static]
 

debug_type stab_find_tagged_type PARAMS (PTR, struct stab_handle *, const char *, int, enum debug_type_kind  )  [static]
 

debug_type stab_xcoff_builtin_type PARAMS (PTR, struct stab_handle *, int)   )  [static]
 

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

debug_type stab_find_type PARAMS (PTR, struct stab_handle *, const int *)   )  [static]
 

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

bfd_boolean stab_emit_pending_vars PARAMS (PTR, struct stab_handle *)   )  [static]
 

bfd_boolean stab_record_variable PARAMS (PTR, struct stab_handle *, const char *, debug_type, enum debug_var_kind, bfd_vma)   )  [static]
 

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

bfd_boolean find_excl PARAMS (struct stab_handle *, const char *, bfd_vma)   )  [static]
 

debug_type parse_stab_array_type PARAMS (PTR, struct stab_handle *, const char **, bfd_boolean)   )  [static]
 

bfd_boolean parse_stab_tilde_field PARAMS (PTR, struct stab_handle *, const char **, const int *, debug_type *, bfd_boolean *)   )  [static]
 

debug_type parse_stab_argtypes PARAMS (PTR, struct stab_handle *, debug_type, const char *, const char *, debug_type, const char *, bfd_boolean, bfd_boolean, const char **)   )  [static]
 

bfd_boolean parse_stab_members PARAMS (PTR, struct stab_handle *, const char *, const char **, const int *, debug_method **)   )  [static]
 

bfd_boolean parse_stab_one_struct_field PARAMS (PTR, struct stab_handle *, const char **, const char *, debug_field *, bfd_boolean *)   )  [static]
 

bfd_boolean parse_stab_cpp_abbrev PARAMS (PTR, struct stab_handle *, const char **, debug_field *)   )  [static]
 

bfd_boolean parse_stab_struct_fields PARAMS (PTR, struct stab_handle *, const char **, debug_field **, bfd_boolean *)   )  [static]
 

bfd_boolean parse_stab_baseclasses PARAMS (PTR, struct stab_handle *, const char **, debug_baseclass **)   )  [static]
 

debug_type parse_stab_struct_type PARAMS (PTR, struct stab_handle *, const char *, const char **, bfd_boolean, const int *)   )  [static]
 

debug_type parse_stab_enum_type PARAMS (PTR, const char **)   )  [static]
 

debug_type parse_stab_range_type PARAMS (PTR, struct stab_handle *, const char *, const char **, const int *)   )  [static]
 

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

debug_type parse_stab_type PARAMS (PTR, struct stab_handle *, const char *, const char **, debug_type **)   )  [static]
 

bfd_boolean parse_stab_string PARAMS (PTR, struct stab_handle *, int, int, bfd_vma, const char *)   )  [static]
 

void warn_stab PARAMS (const char *, const char *)   )  [static]
 

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

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

char* savestring PARAMS (const char *, int)   )  [static]
 

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

00234 {
00235   unsigned long ul;
00236   const char *orig;
00237 
00238   if (poverflow != NULL)
00239     *poverflow = false;
00240 
00241   orig = *pp;
00242 
00243   errno = 0;
00244   ul = strtoul (*pp, (char **) pp, 0);
00245   if (ul + 1 != 0 || errno == 0)
00246     return (bfd_vma) ul;
00247 
00248   /* Note that even though strtoul overflowed, it should have set *pp
00249      to the end of the number, which is where we want it.  */
00250 
00251   if (sizeof (bfd_vma) > sizeof (unsigned long))
00252     {
00253       const char *p;
00254       boolean neg;
00255       int base;
00256       bfd_vma over, lastdig;
00257       boolean overflow;
00258       bfd_vma v;
00259 
00260       /* Our own version of strtoul, for a bfd_vma.  */
00261 
00262       p = orig;
00263 
00264       neg = false;
00265       if (*p == '+')
00266         ++p;
00267       else if (*p == '-')
00268         {
00269           neg = true;
00270           ++p;
00271         }
00272 
00273       base = 10;
00274       if (*p == '0')
00275         {
00276           if (p[1] == 'x' || p[1] == 'X')
00277             {
00278               base = 16;
00279               p += 2;
00280             }
00281           else
00282             {
00283               base = 8;
00284               ++p;
00285             }
00286         }
00287 
00288       over = ((bfd_vma) (bfd_signed_vma) -1) / (bfd_vma) base;
00289       lastdig = ((bfd_vma) (bfd_signed_vma) -1) % (bfd_vma) base;
00290 
00291       overflow = false;
00292       v = 0;
00293       while (1)
00294         {
00295           int d;
00296 
00297           d = *p++;
00298           if (isdigit ((unsigned char) d))
00299             d -= '0';
00300           else if (isupper ((unsigned char) d))
00301             d -= 'A';
00302           else if (islower ((unsigned char) d))
00303             d -= 'a';
00304           else
00305             break;
00306 
00307           if (d >= base)
00308             break;
00309 
00310           if (v > over || (v == over && (bfd_vma) d > lastdig))
00311             {
00312               overflow = true;
00313               break;
00314             }
00315         }
00316 
00317       if (! overflow)
00318         {
00319           if (neg)
00320             v = - v;
00321           return v;
00322         }
00323     }
00324 
00325   /* If we get here, the number is too large to represent in a
00326      bfd_vma.  */
00327 
00328   if (poverflow != NULL)
00329     *poverflow = true;
00330   else
00331     warn_stab (orig, "numeric overflow");
00332 
00333   return 0;
00334 }

bfd_boolean parse_stab PTR  dhandle,
PTR  handle,
int  type,
int  desc,
bfd_vma  value,
const char *  string
 

00426 {
00427   struct stab_handle *info = (struct stab_handle *) handle;
00428 
00429   /* gcc will emit two N_SO strings per compilation unit, one for the
00430      directory name and one for the file name.  We just collect N_SO
00431      strings as we see them, and start the new compilation unit when
00432      we see a non N_SO symbol.  */
00433   if (info->so_string != NULL
00434       && (type != N_SO || *string == '\0' || value != info->so_value))
00435     {
00436       if (! debug_set_filename (dhandle, info->so_string))
00437         return false;
00438       info->main_filename = info->so_string;
00439 
00440       info->gcc_compiled = 0;
00441       info->n_opt_found = false;
00442 
00443       /* Generally, for stabs in the symbol table, the N_LBRAC and
00444          N_RBRAC symbols are relative to the N_SO symbol value.  */
00445       if (! info->sections)
00446         info->file_start_offset = info->so_value;
00447 
00448       /* We need to reset the mapping from type numbers to types.  We
00449          can't free the old mapping, because of the use of
00450          debug_make_indirect_type.  */
00451       info->files = 1;
00452       info->file_types = ((struct stab_types **)
00453                           xmalloc (sizeof *info->file_types));
00454       info->file_types[0] = NULL;
00455 
00456       info->so_string = NULL;
00457 
00458       /* Now process whatever type we just got.  */
00459     }
00460 
00461   switch (type)
00462     {
00463     case N_FN:
00464     case N_FN_SEQ:
00465       break;
00466 
00467     case N_LBRAC:
00468       /* Ignore extra outermost context from SunPRO cc and acc.  */
00469       if (info->n_opt_found && desc == 1)
00470         break;
00471 
00472       if (! info->within_function)
00473         {
00474           fprintf (stderr, "N_LBRAC not within function\n");
00475           return false;
00476         }
00477 
00478       /* Start an inner lexical block.  */
00479       if (! debug_start_block (dhandle,
00480                                (value
00481                                 + info->file_start_offset
00482                                 + info->function_start_offset)))
00483         return false;
00484 
00485       /* Emit any pending variable definitions.  */
00486       if (! stab_emit_pending_vars (dhandle, info))
00487         return false;
00488 
00489       ++info->block_depth;
00490       break;
00491 
00492     case N_RBRAC:
00493       /* Ignore extra outermost context from SunPRO cc and acc.  */
00494       if (info->n_opt_found && desc == 1)
00495         break;
00496 
00497       /* We shouldn't have any pending variable definitions here, but,
00498          if we do, we probably need to emit them before closing the
00499          block.  */
00500       if (! stab_emit_pending_vars (dhandle, info))
00501         return false;
00502 
00503       /* End an inner lexical block.  */
00504       if (! debug_end_block (dhandle,
00505                              (value
00506                               + info->file_start_offset
00507                               + info->function_start_offset)))
00508         return false;
00509 
00510       --info->block_depth;
00511       if (info->block_depth < 0)
00512         {
00513           fprintf (stderr, "Too many N_RBRACs\n");
00514           return false;
00515         }
00516       break;
00517 
00518     case N_SO:
00519       /* This always ends a function.  */
00520       if (info->within_function)
00521         {
00522           bfd_vma endval;
00523 
00524           endval = value;
00525           if (*string != '\0'
00526               && info->function_end != (bfd_vma) -1
00527               && info->function_end < endval)
00528             endval = info->function_end;
00529           if (! stab_emit_pending_vars (dhandle, info)
00530               || ! debug_end_function (dhandle, endval))
00531             return false;
00532           info->within_function = false;
00533           info->function_end = (bfd_vma) -1;
00534         }
00535 
00536       /* An empty string is emitted by gcc at the end of a compilation
00537          unit.  */
00538       if (*string == '\0')
00539         return true;
00540 
00541       /* Just accumulate strings until we see a non N_SO symbol.  If
00542          the string starts with '/', we discard the previously
00543          accumulated strings.  */
00544       if (info->so_string == NULL)
00545         info->so_string = xstrdup (string);
00546       else
00547         {
00548           char *f;
00549 
00550           f = info->so_string;
00551           if (*string == '/')
00552             info->so_string = xstrdup (string);
00553           else
00554             info->so_string = concat (info->so_string, string,
00555                                       (const char *) NULL);
00556           free (f);
00557         }
00558 
00559       info->so_value = value;
00560 
00561       break;
00562 
00563     case N_SOL:
00564       /* Start an include file.  */
00565       if (! debug_start_source (dhandle, string))
00566         return false;
00567       break;
00568 
00569     case N_BINCL:
00570       /* Start an include file which may be replaced.  */
00571       push_bincl (info, string, value);
00572       if (! debug_start_source (dhandle, string))
00573         return false;
00574       break;
00575 
00576     case N_EINCL:
00577       /* End an N_BINCL include.  */
00578       if (! debug_start_source (dhandle, pop_bincl (info)))
00579         return false;
00580       break;
00581 
00582     case N_EXCL:
00583       /* This is a duplicate of a header file named by N_BINCL which
00584          was eliminated by the linker.  */
00585       if (! find_excl (info, string, value))
00586         return false;
00587       break;
00588 
00589     case N_SLINE:
00590       if (! debug_record_line (dhandle, desc,
00591                                value + info->function_start_offset))
00592         return false;
00593       break;
00594 
00595     case N_BCOMM:
00596       if (! debug_start_common_block (dhandle, string))
00597         return false;
00598       break;
00599 
00600     case N_ECOMM:
00601       if (! debug_end_common_block (dhandle, string))
00602         return false;
00603       break;
00604 
00605     case N_FUN:
00606       if (*string == '\0')
00607         {
00608           if (info->within_function)
00609             {
00610               /* This always marks the end of a function; we don't
00611                  need to worry about info->function_end.  */
00612               if (info->sections)
00613                 value += info->function_start_offset;
00614               if (! stab_emit_pending_vars (dhandle, info)
00615                   || ! debug_end_function (dhandle, value))
00616                 return false;
00617               info->within_function = false;
00618               info->function_end = (bfd_vma) -1;
00619             }
00620           break;
00621         }
00622 
00623       /* A const static symbol in the .text section will have an N_FUN
00624          entry.  We need to use these to mark the end of the function,
00625          in case we are looking at gcc output before it was changed to
00626          always emit an empty N_FUN.  We can't call debug_end_function
00627          here, because it might be a local static symbol.  */
00628       if (info->within_function
00629           && (info->function_end == (bfd_vma) -1
00630               || value < info->function_end))
00631         info->function_end = value;
00632 
00633       /* Fall through.  */
00634       /* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM
00635          symbols, and if it does not start with :S, gdb relocates the
00636          value to the start of the section.  gcc always seems to use
00637          :S, so we don't worry about this.  */
00638       /* Fall through.  */
00639     default:
00640       {
00641         const char *colon;
00642 
00643         colon = strchr (string, ':');
00644         if (colon != NULL
00645             && (colon[1] == 'f' || colon[1] == 'F'))
00646           {
00647             if (info->within_function)
00648               {
00649                 bfd_vma endval;
00650 
00651                 endval = value;
00652                 if (info->function_end != (bfd_vma) -1
00653                     && info->function_end < endval)
00654                   endval = info->function_end;
00655                 if (! stab_emit_pending_vars (dhandle, info)
00656                     || ! debug_end_function (dhandle, endval))
00657                   return false;
00658                 info->function_end = (bfd_vma) -1;
00659               }
00660             /* For stabs in sections, line numbers and block addresses
00661                are offsets from the start of the function.  */
00662             if (info->sections)
00663               info->function_start_offset = value;
00664             info->within_function = true;
00665           }
00666 
00667         if (! parse_stab_string (dhandle, info, type, desc, value, string))
00668           return false;
00669       }
00670       break;
00671 
00672     case N_OPT:
00673       if (string != NULL && strcmp (string, "gcc2_compiled.") == 0)
00674         info->gcc_compiled = 2;
00675       else if (string != NULL && strcmp (string, "gcc_compiled.") == 0)
00676         info->gcc_compiled = 1;
00677       else
00678         info->n_opt_found = true;
00679       break;
00680 
00681     case N_OBJ:
00682     case N_ENDM:
00683     case N_MAIN:
00684       break;
00685     }
00686 
00687   return true;
00688 }

debug_type parse_stab_argtypes PTR  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]
 

02857 {
02858   boolean is_full_physname_constructor;
02859   boolean is_constructor;
02860   boolean is_destructor;
02861   debug_type *args;
02862   boolean varargs;
02863 
02864   /* Constructors are sometimes handled specially.  */
02865   is_full_physname_constructor = ((argtypes[0] == '_'
02866                                    && argtypes[1] == '_'
02867                                    && (isdigit ((unsigned char) argtypes[2])
02868                                        || argtypes[2] == 'Q'
02869                                        || argtypes[2] == 't'))
02870                                   || strncmp (argtypes, "__ct", 4) == 0);
02871 
02872   is_constructor = (is_full_physname_constructor
02873                     || (tagname != NULL
02874                         && strcmp (fieldname, tagname) == 0));
02875   is_destructor = ((argtypes[0] == '_'
02876                     && (argtypes[1] == '$' || argtypes[1] == '.')
02877                     && argtypes[2] == '_')
02878                    || strncmp (argtypes, "__dt", 4) == 0);
02879 
02880   if (is_destructor || is_full_physname_constructor)
02881     *pphysname = argtypes;
02882   else
02883     {
02884       unsigned int len;
02885       const char *const_prefix;
02886       const char *volatile_prefix;
02887       char buf[20];
02888       unsigned int mangled_name_len;
02889       char *physname;
02890 
02891       len = tagname == NULL ? 0 : strlen (tagname);
02892       const_prefix = constp ? "C" : "";
02893       volatile_prefix = volatilep ? "V" : "";
02894 
02895       if (len == 0)
02896         sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
02897       else if (tagname != NULL && strchr (tagname, '<') != NULL)
02898         {
02899           /* Template methods are fully mangled.  */
02900           sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
02901           tagname = NULL;
02902           len = 0;
02903         }
02904       else
02905         sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
02906 
02907       mangled_name_len = ((is_constructor ? 0 : strlen (fieldname))
02908                           + strlen (buf)
02909                           + len
02910                           + strlen (argtypes)
02911                           + 1);
02912 
02913       if (fieldname[0] == 'o'
02914           && fieldname[1] == 'p'
02915           && (fieldname[2] == '$' || fieldname[2] == '.'))
02916         {
02917           const char *opname;
02918 
02919           opname = cplus_mangle_opname (fieldn