pstack.c File Reference

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <asm/ptrace.h>
#include <assert.h>
#include <fcntl.h>
#include <link.h>
#include <malloc.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#include <limits.h>
#include <bfd.h>
#include "libiberty.h"
#include "pstack.h"
#include "budbg.h"
#include "bucomm.h"
#include "debug.h"
#include "linuxthreads.h"

Go to the source code of this file.

Data Structures

struct  debug_block_st
struct  debug_function_t
struct  debug_lineno_t
struct  debug_parameter_t
struct  pr_handle
struct  pr_stack
struct  signal_regs_t
struct  symbol_data_t

Defines

#define MAXARGS   6

Typedefs

typedef debug_block_st debug_block_t

Functions

static boolean append_type (struct pr_handle *info, const char *s)
static int compare_debug_function_t (const void *ap, const void *bp)
static int compare_symbols (const void *ap, const void *bp)
static void decode_symbol (symbol_data_t *symbol_data, const unsigned long addr, char *buf, const int bufsize)
int fdprintf (int fd, const char *fmt,...)
int fdputc (char c, int fd)
int fdputs (const char *s, int fd)
static debug_function_tfind_debug_function_t (symbol_data_t *symbol_data, const pid_t pid, const unsigned long fp, const unsigned long addr, char *buf, const int bufsize)
static void indent (struct pr_handle *info)
static boolean indent_type (struct pr_handle *info)
static bfd * load_bfd (const int pid)
static int my_crawl (int pid, symbol_data_t *symbol_data, int fout)
static int my_ptrace (int request, int pid, int addr, int data)
static int open_log_file (const pthread_t tid, const pid_t pid)
static void indent PARAMS ((struct pr_handle *))
static char * pop_type (struct pr_handle *info)
static boolean pr_array_type (PTR p, bfd_signed_vma lower, bfd_signed_vma upper, boolean stringp)
static boolean pr_bool_type (PTR p, unsigned int size)
static boolean pr_class_baseclass (PTR p, bfd_vma bitpos, boolean virtual, enum debug_visibility visibility)
static boolean pr_class_end_method (PTR p)
static boolean pr_class_method_variant (PTR p, const char *physname, enum debug_visibility visibility, boolean constp, boolean volatilep, bfd_vma voffset, boolean context)
static boolean pr_class_start_method (PTR p, const char *name)
static boolean pr_class_static_member (PTR p, const char *name, const char *physname, enum debug_visibility visibility)
static boolean pr_class_static_method_variant (PTR p, const char *physname, enum debug_visibility visibility, boolean constp, boolean volatilep)
static boolean pr_complex_type (PTR p, unsigned int size)
static boolean pr_const_type (PTR p)
static boolean pr_empty_type (PTR p)
static boolean pr_end_block (PTR p, bfd_vma addr)
static boolean pr_end_class_type (PTR p)
static boolean pr_end_function (PTR p)
static boolean pr_end_struct_type (PTR p)
static boolean pr_enum_type (PTR p, const char *tag, const char **names, bfd_signed_vma *values)
static boolean pr_fix_visibility (struct pr_handle *info, enum debug_visibility visibility)
static boolean pr_float_constant (PTR p, const char *name, double val)
static boolean pr_float_type (PTR p, unsigned int size)
static boolean pr_function_parameter (PTR p, const char *name, enum debug_parm_kind kind, bfd_vma val)
static boolean pr_function_type (PTR p, int argcount, boolean varargs)
static boolean pr_int_constant (PTR p, const char *name, bfd_vma val)
static boolean pr_int_type (PTR p, unsigned int size, boolean unsignedp)
static boolean pr_lineno (PTR p, const char *filename, unsigned long lineno, bfd_vma addr)
static boolean pr_method_type (PTR p, boolean domain, int argcount, boolean varargs)
static boolean pr_offset_type (PTR p)
static boolean pr_pointer_type (PTR p)
static boolean pr_range_type (PTR p, bfd_signed_vma lower, bfd_signed_vma upper)
static boolean pr_reference_type (PTR p)
static boolean pr_set_type (PTR p, boolean bitstringp)
static boolean pr_start_block (PTR p, bfd_vma addr)
static boolean pr_start_class_type (PTR p, const char *tag, unsigned int id, boolean structp, unsigned int size, boolean vptr, boolean ownvptr)
static boolean pr_start_compilation_unit (PTR p, const char *filename)
static boolean pr_start_function (PTR p, const char *name, boolean global)
static boolean pr_start_source (PTR p, const char *filename)
static boolean pr_start_struct_type (PTR p, const char *tag, unsigned int id, boolean structp, unsigned int size)
static boolean pr_struct_field (PTR p, const char *name, bfd_vma bitpos, bfd_vma bitsize, enum debug_visibility visibility)
static boolean pr_tag (PTR p, const char *name)
static boolean pr_tag_type (PTR p, const char *name, unsigned int id, enum debug_type_kind kind)
static boolean pr_typdef (PTR p, const char *name)
static boolean pr_typed_constant (PTR p, const char *name, bfd_vma val)
static boolean pr_typedef_type (PTR p, const char *name)
static boolean pr_variable (PTR p, const char *name, enum debug_var_kind kind, bfd_vma val)
static boolean pr_void_type (PTR p)
static boolean pr_volatile_type (PTR p)
static boolean prepend_type (struct pr_handle *info, const char *s)
static void print_vma (bfd_vma vma, char *buf, boolean unsignedp, boolean hexp)
int pstack_install_segv_action (const char *path_format_)
static boolean push_type (struct pr_handle *info, const char *type)
static long remove_useless_symbols (asymbol **symbols, long count)
static void report_action (int signo, siginfo_t *siginfo, void *ptr)
static void segv_action (int signo, siginfo_t *siginfo, void *ptr)
static void show_regs (signal_regs_t *regs, int fd)
static boolean substitute_type (struct pr_handle *info, const char *s)

Variables

static bfd * abfd = 0
static PTR dhandle = 0
static debug_function_t ** functions = 0
static int functions_size = 0
static const char * path_format = "stack-trace-on-segv-%d.txt"
static const struct debug_write_fns pr_fns
signal_regs_tptrace_regs = 0
static pid_t segv_pid
static pthread_t segv_tid
static int sigreport = SIGUSR1
static long sorted_symcount = 0
static asymbol ** sorted_syms = 0
static long symcount = 0
static asymbol ** syms = 0


Define Documentation

#define MAXARGS   6
 

Definition at line 2162 of file pstack.c.


Typedef Documentation

typedef struct debug_block_st debug_block_t
 


Function Documentation

static boolean append_type struct pr_handle info,
const char *  s
[static]
 

Definition at line 389 of file pstack.c.

References assert, len, NULL, and xrealloc().

Referenced by indent_type(), pr_array_type(), pr_class_baseclass(), pr_class_method_variant(), pr_class_static_member(), pr_class_static_method_variant(), pr_enum_type(), pr_fix_visibility(), pr_offset_type(), pr_range_type(), pr_set_type(), pr_start_class_type(), pr_start_struct_type(), pr_struct_field(), pr_tag_type(), and substitute_type().

00392 {
00393   unsigned int len;
00394 
00395   if (s == NULL)
00396     return false;
00397 
00398   assert (info->stack != NULL);
00399 
00400   len = strlen (info->stack->type);
00401   info->stack->type = (char *) xrealloc (info->stack->type,
00402                                          len + strlen (s) + 1);
00403   strcpy (info->stack->type + len, s);
00404 
00405   return true;
00406 }

static int compare_debug_function_t const void *  ap,
const void *  bp
[static]
 

Definition at line 2491 of file pstack.c.

References assert, debug_block_st::begin_addr, and debug_function_t::block.

Referenced by pstack_install_segv_action().

02493 {
02494         const debug_function_t *a = *(const debug_function_t **)ap;
02495         const debug_function_t *b = *(const debug_function_t **)bp;
02496         assert(a->block!=0);
02497         assert(b->block!=0);
02498         {
02499                 const bfd_vma   addr1 = a->block->begin_addr;
02500                 const bfd_vma   addr2 = b->block->begin_addr;
02501                 if (addr1 > addr2)
02502                         return 1;
02503                 else if (addr2 > addr1)
02504                         return -1;
02505         }
02506         return 0;
02507 }

static int compare_symbols const void *  ap,
const void *  bp
[static]
 

Definition at line 2475 of file pstack.c.

Referenced by pstack_install_segv_action().

02477 {
02478         const asymbol *a = *(const asymbol **)ap;
02479         const asymbol *b = *(const asymbol **)bp;
02480         if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
02481                 return 1;
02482         else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
02483                 return -1;
02484         return 0;
02485 }

static void decode_symbol symbol_data_t symbol_data,
const unsigned long  addr,
char *  buf,
const int  bufsize
[static]
 

Definition at line 2178 of file pstack.c.

References name, symbol_data_t::symcount, symcount, symbol_data_t::syms, syms, and top.

Referenced by my_crawl().

02182 {
02183         asymbol**       syms = symbol_data->syms;
02184         const int       symcount = symbol_data->symcount;
02185         int             bottom = 0;
02186         int             top = symcount - 1;
02187         int             i;
02188         if (symcount==0) {
02189                 sprintf(buf, "????");
02190                 return;
02191         }
02192         while (top>bottom+1) {
02193                 i = (top+bottom) / 2;
02194                 if (bfd_asymbol_value(syms[i])==addr) {
02195                         sprintf(buf, "%s", syms[i]->name);
02196                         return;
02197                 } else if (bfd_asymbol_value(syms[i]) > addr)
02198                         top = i;
02199                 else
02200                         bottom = i;
02201         }
02202         i = bottom;
02203         if (addr<bfd_asymbol_value(syms[i]) || addr>(syms[i]->section->vma+syms[i]->section->_cooked_size))
02204                 sprintf(buf, "????");
02205         else
02206                 sprintf(buf, "%s + 0x%lx", syms[i]->name, addr-bfd_asymbol_value(syms[i]));
02207 }

int fdprintf int  fd,
const char *  fmt,
  ...
 

Definition at line 83 of file pstack.c.

References vsnprintf, and write().

Referenced by my_crawl(), report_action(), segv_action(), and show_regs().

00085 {
00086         char    xbuf[2048];// FIXME: enough?
00087         va_list ap;
00088         int     r;
00089         if (fd<0)
00090                 return -1;
00091         va_start(ap, fmt);
00092         r = vsnprintf(xbuf, sizeof(xbuf), fmt, ap);
00093         va_end(ap);
00094         return write(fd, xbuf, r);
00095 }

int fdputc char  c,
int  fd
 

Definition at line 98 of file pstack.c.

References write().

Referenced by my_crawl().

00100 {
00101         if (fd<0)
00102                 return -1;
00103         return write(fd, &c, sizeof(c));
00104 }

int fdputs const char *  s,
int  fd
 

Definition at line 107 of file pstack.c.

References write().

Referenced by my_crawl().

00109 {
00110         if (fd<0)
00111                 return -1;
00112         return write(fd, s, strlen(s));
00113 }

static debug_function_t* find_debug_function_t symbol_data_t symbol_data,
const pid_t  pid,
const unsigned long  fp,
const unsigned long  addr,
char *  buf,
const int  bufsize
[static]
 

Definition at line 2215 of file pstack.c.

References debug_lineno_t::addr, arg, debug_function_t::argc, debug_function_t::argv, assert, debug_block_st::begin_addr, debug_function_t::block, yaSSL::block, debug_block_st::end_addr, errno, f(), debug_function_t::filename, symbol_data_t::functions, symbol_data_t::functions_size, debug_lineno_t::lineno, lineno, debug_function_t::lines, debug_function_t::lines_count, my_ptrace(), debug_parameter_t::name, debug_function_t::name, NULL, debug_parameter_t::offset, symcount, syms, and top.

Referenced by my_crawl().

02220                                                                 : not used! */
02221 {
02222         debug_function_t**      syms = symbol_data->functions;
02223         debug_function_t*       f = NULL;
02224         debug_block_t*          block = NULL;
02225         debug_lineno_t*         lineno = NULL;
02226         const int               symcount = symbol_data->functions_size;
02227         int                     bottom = 0;
02228         int                     top = symcount - 1;
02229         int                     i;
02230         char*                   bufptr = buf;
02231 
02232         if (symcount==0) {
02233                 sprintf(buf, "????");
02234                 return NULL;
02235         }
02236         while (top>bottom+1) {
02237                 i = (top+bottom) / 2;
02238                 if (syms[i]->block->begin_addr==addr) {
02239                         f = syms[i];
02240                         break;
02241                 } else if (syms[i]->block->begin_addr > addr)
02242                                 top = i;
02243                 else
02244                         if (syms[i]->block->end_addr >= addr) {
02245                                 f = syms[i];
02246                                 break;
02247                         } else
02248                                 bottom = i;
02249         }
02250         i = bottom;
02251         if (f!=0)
02252                 block = f->block;
02253         else {
02254                 block = syms[i]->block;
02255                 if (block->begin_addr>=addr && block->end_addr<=addr)
02256                         f = syms[i];
02257         }
02258         if (f==0)
02259                 sprintf(buf, "????");
02260         else {
02261                 /*
02262                  * Do the backtrace the GDB way...
02263                  */
02264                 unsigned long   arg;
02265                 /* assert(f->lines_count>0); */
02266                 if (f->lines_count>0) {
02267                         lineno = &f->lines[f->lines_count-1];
02268                         for (i=1; i<f->lines_count; ++i)
02269                                 if (f->lines[i].addr>addr) {
02270                                         lineno = &f->lines[i-1];
02271                                         break;
02272                                 }
02273                 }
02274                 bufptr[0] = 0;
02275                 bufptr += sprintf(bufptr, "%s+0x%lx (", f->name, addr-block->begin_addr);
02276                 for (i=0; i<f->argc; ++i) {
02277                         bufptr += sprintf(bufptr, "%s = ", f->argv[i].name);
02278                         /* FIXME: better parameter printing */
02279                         errno = 0;
02280                         arg = my_ptrace(PTRACE_PEEKDATA, pid, fp+f->argv[i].offset, 0);
02281                         assert(errno==0);
02282                         bufptr += sprintf(bufptr, "0x%x", arg);
02283                         if (i!=f->argc-1)
02284                                 bufptr += sprintf(bufptr, ", ");
02285                 }
02286                 if (lineno!=0)
02287                         bufptr += sprintf(bufptr, ") at %s:%d", f->filename, lineno->lineno);
02288         }
02289         return f;
02290 }

static void indent struct pr_handle info  )  [static]
 

Definition at line 334 of file pstack.c.

References TRACE_PUTC.

Referenced by indent_type(), pr_end_block(), pr_lineno(), pr_start_block(), pr_start_function(), and pr_variable().

00336 {
00337   unsigned int i;
00338 
00339   for (i = 0; i < info->indent; i++)
00340     TRACE_PUTC ((' ', info->f));
00341 }

static boolean indent_type struct pr_handle info  )  [static]
 

Definition at line 457 of file pstack.c.

References append_type(), and indent().

Referenced by pr_class_method_variant(), pr_class_static_member(), pr_class_static_method_variant(), pr_fix_visibility(), pr_start_class_type(), pr_start_struct_type(), and pr_struct_field().

00459 {
00460   unsigned int i;
00461 
00462   for (i = 0; i < info->indent; i++)
00463     {
00464       if (! append_type (info, " "))
00465         return false;
00466     }
00467 
00468   return true;
00469 }

static bfd* load_bfd const int  pid  )  [static]
 

Definition at line 2435 of file pstack.c.

References abfd, assert, bfd_nonfatal(), filename, free, list_matching_formats(), and NULL.

Referenced by pstack_install_segv_action().

02436 {
02437         char    filename[512];
02438         bfd*    abfd = 0;
02439 
02440         /* Get the contents from procfs. */
02441 #if 1
02442         sprintf(filename, "/proc/%d/exe", pid);
02443 #else
02444         sprintf(filename, "crashing");
02445 #endif 
02446 
02447         if ((abfd = bfd_openr (filename, 0))== NULL)
02448                 bfd_nonfatal (filename);
02449         else {
02450                 char**  matching;
02451                 assert(bfd_check_format(abfd, bfd_archive)!=true);
02452 
02453                 /*
02454                  * There is no indication in BFD documentation that it should be done.
02455                  * God knows why...
02456                  */
02457                 if (!bfd_check_format_matches (abfd, bfd_object, &matching)) {
02458                         bfd_nonfatal (bfd_get_filename (abfd));
02459                         if (bfd_get_error () == bfd_error_file_ambiguously_recognized) {
02460                                 list_matching_formats (matching);
02461                                 free (matching);
02462                         }
02463                 }
02464         }
02465         return abfd;
02466 }

static int my_crawl int  pid,
symbol_data_t symbol_data,
int  fout
[static]
 

Definition at line 2296 of file pstack.c.

References arg, buf, decode_symbol(), errno, f(), fdprintf(), fdputc(), fdputs(), find_debug_function_t(), fp, MAXARGS, my_ptrace(), and perror().

Referenced by report_action(), and segv_action().

02299 {
02300         unsigned long           pc = 0;
02301         unsigned long           fp = 0;
02302         unsigned long           nextfp;
02303         unsigned long           nargs;
02304         unsigned long           i;
02305         unsigned long           arg;
02306         char                    buf[8096];      // FIXME: enough?
02307         debug_function_t*       f = 0;
02308 
02309         errno = 0;
02310 
02311         pc = my_ptrace(PTRACE_PEEKUSER, pid, EIP * 4, 0);
02312         if (!errno)
02313                 fp = my_ptrace(PTRACE_PEEKUSER, pid, EBP * 4, 0);
02314 
02315         if (!errno) {
02316 #if 1
02317                 f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
02318                 fdprintf(fout,"0x%08lx: %s", pc, buf);
02319                 for ( ; !errno && fp; ) {
02320                         nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
02321                         if (errno)
02322                                 break;
02323 
02324                         if (f==0) {
02325                                 nargs = (nextfp - fp - 8) / 4;
02326                                 if (nargs > MAXARGS)
02327                                         nargs = MAXARGS;
02328                                 if (nargs > 0) {
02329                                         fdputs(" (", fout);
02330                                         for (i = 1; i <= nargs; i++) {
02331                                                 arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
02332                                                 if (errno)
02333                                                         break;
02334                                                 fdprintf(fout,"%lx", arg);
02335                                                 if (i < nargs)
02336                                                         fdputs(", ", fout);
02337                                         }
02338                                         fdputc(')', fout);
02339                                         nargs = nextfp - fp - 8 - (4 * nargs);
02340                                         if (!errno && nargs > 0)
02341                                                 fdprintf(fout," + %lx\n", nargs);
02342                                         else
02343                                                 fdputc('\n', fout);
02344                                 } else
02345                                         fdputc('\n', fout);
02346                         } else
02347                                 fdputc('\n', fout);
02348 
02349                         if (errno || !nextfp)
02350                                 break;
02351                         pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
02352                         fp = nextfp;
02353                         if (errno)
02354                                 break;
02355                         f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
02356                         fdprintf(fout,"0x%08lx: %s", pc, buf);
02357                 }
02358 #else /* 1 */
02359                 decode_symbol(symbol_data, pc, buf, sizeof(buf));
02360                 fdprintf(fout,"0x%08lx: %s", pc, buf);
02361                 for ( ; !errno && fp; ) {
02362                         nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
02363                         if (errno)
02364                                 break;
02365 
02366                         nargs = (nextfp - fp - 8) / 4;
02367                         if (nargs > MAXARGS)
02368                                 nargs = MAXARGS;
02369                         if (nargs > 0) {
02370                                 fputs(" (", fout);
02371                                 for (i = 1; i <= nargs; i++) {
02372                                         arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
02373                                         if (errno)
02374                                                 break;
02375                                         fdprintf(fout,"%lx", arg);
02376                                         if (i < nargs)
02377                                                 fputs(", ", fout);
02378                                 }
02379                                 fdputc(')', fout);
02380                                 nargs = nextfp - fp - 8 - (4 * nargs);
02381                                 if (!errno && nargs > 0)
02382                                         fdprintf(fout," + %lx\n", nargs);
02383                                 else
02384                                         fdputc('\n', fout);
02385                         } else
02386                                 fdputc('\n', fout);
02387 
02388                         if (errno || !nextfp)
02389                                 break;
02390                         pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
02391                         fp = nextfp;
02392                         if (errno)
02393                                 break;
02394                         decode_symbol(symbol_data, pc, buf, sizeof(buf));
02395                         fdprintf(fout,"0x%08lx: %s", pc, buf);
02396                 }
02397 #endif /* !1 */
02398         }
02399         if (errno)
02400                 perror("my_crawl");
02401         return errno;
02402 }

static int my_ptrace int  request,
int  pid,
int  addr,
int  data
[static]
 

Definition at line 2136 of file pstack.c.

References assert, signal_regs_t::ebp, signal_regs_t::eip, and errno.

Referenced by find_debug_function_t(), and my_crawl().

02140 {
02141         if (ptrace_regs==0)
02142                 return ptrace(request, pid, addr, data);
02143         /* we are tracing ourselves! */
02144         switch (request) {
02145         case PTRACE_ATTACH:     return 0;
02146         case PTRACE_CONT:       return 0;
02147         case PTRACE_DETACH:     return 0;
02148         case PTRACE_PEEKUSER:
02149                                 switch (addr / 4) {
02150                                 case EIP:       return ptrace_regs->eip;
02151                                 case EBP:       return ptrace_regs->ebp;
02152                                 default:        assert(0);
02153                                 }
02154         case PTRACE_PEEKTEXT:   /* FALLTHROUGH */
02155         case PTRACE_PEEKDATA:   return *(int*)(addr);
02156         default:                assert(0);
02157         }
02158         errno = 1;      /* what to do here? */
02159         return 1;       /* failed?! */
02160 }

static int open_log_file const pthread_t  tid,
const pid_t  pid
[static]
 

Definition at line 121 of file pstack.c.

References open(), path_format, perror(), S_IRUSR, S_IWUSR, and snprintf.

Referenced by report_action(), and segv_action().

00123 {
00124         char    fname[PATH_MAX];
00125         int     r;
00126         snprintf(fname, sizeof(fname), path_format, tid, pid);
00127         r = open(fname, O_WRONLY|O_CREAT|O_TRUNC,
00128                         S_IRUSR|S_IWUSR);
00129         if (r<0)
00130                 perror("open");
00131         return r;
00132 }

static void indent PARAMS (struct pr_handle *)   )  [static]
 

static char* pop_type struct pr_handle info  )  [static]
 

Definition at line 474 of file pstack.c.

References assert, free, pr_stack::next, NULL, and pr_stack::type.

Referenced by pr_array_type(), pr_class_baseclass(), pr_class_method_variant(), pr_class_static_member(), pr_class_static_method_variant(), pr_function_parameter(), pr_function_type(), pr_method_type(), pr_offset_type(), pr_start_class_type(), pr_start_function(), pr_struct_field(), pr_tag(), pr_typdef(), pr_typed_constant(), and pr_variable().

00476 {
00477   struct pr_stack *o;
00478   char *ret;
00479 
00480   assert (info->stack != NULL);
00481 
00482   o = info->stack;
00483   info->stack = o->next;
00484   ret = o->type;
00485   free (o);
00486 
00487   return ret;
00488 }

static boolean pr_array_type PTR  p,
bfd_signed_vma  lower,
bfd_signed_vma  upper,
boolean  stringp
[static]
 

Definition at line 837 of file pstack.c.

References append_type(), info, NULL, pop_type(), print_vma(), and substitute_type().

00842 {
00843   struct pr_handle *info = (struct pr_handle *) p;
00844   char *range_type;
00845   char abl[20], abu[20], ab[50];
00846 
00847   range_type = pop_type (info);
00848   if (range_type == NULL)
00849     return false;
00850 
00851   if (lower == 0)
00852     {
00853       if (upper == -1)
00854         sprintf (ab, "|[]");
00855       else
00856         {
00857           print_vma (upper + 1, abu, false, false);
00858           sprintf (ab, "|[%s]", abu);
00859         }
00860     }
00861   else
00862     {
00863       print_vma (lower, abl, false, false);
00864       print_vma (upper, abu, false, false);
00865       sprintf (ab, "|[%s:%s]", abl, abu);
00866     }
00867 
00868   if (! substitute_type (info, ab))
00869     return false;
00870 
00871   if (strcmp (range_type, "int") != 0)
00872     {
00873       if (! append_type (info, ":")
00874           || ! append_type (info, range_type))
00875         return false;
00876     }
00877 
00878   if (stringp)
00879     {
00880       if (! append_type (info, " /* string */"))
00881         return false;
00882     }
00883 
00884   return true;
00885 }

static boolean pr_bool_type PTR  p,
unsigned int  size
[static]
 

Definition at line 622 of file pstack.c.

References info, and push_type().

00625 {
00626   struct pr_handle *info = (struct pr_handle *) p;
00627   char ab[10];
00628 
00629   sprintf (ab, "bool%d", size * 8);
00630 
00631   return push_type (info, ab);
00632 }

static boolean pr_class_baseclass PTR  p,
bfd_vma  bitpos,
boolean  virtual,
enum debug_visibility  visibility
[static]
 

Definition at line 1373 of file pstack.c.

References append_type(), assert, DEBUG_VISIBILITY_PRIVATE, DEBUG_VISIBILITY_PROTECTED, DEBUG_VISIBILITY_PUBLIC, free, info, memcpy, n, pr_stack::next, NULL, pop_type(), prepend_type(), print_vma(), push_type(), pr_handle::stack, strchr(), substitute_type(), and xmalloc().

01378 {
01379   struct pr_handle *info = (struct pr_handle *) p;
01380   char *t;
01381   const char *prefix;
01382   char ab[20];
01383   char *s, *l, *n;
01384 
01385   assert (info->stack != NULL && info->stack->next != NULL);
01386 
01387   if (! substitute_type (info, ""))
01388     return false;
01389 
01390   t = pop_type (info);
01391   if (t == NULL)
01392     return false;
01393 
01394   if (strncmp (t, "class ", sizeof "class " - 1) == 0)
01395     t += sizeof "class " - 1;
01396 
01397   /* Push it back on to take advantage of the prepend_type and
01398      append_type routines.  */
01399   if (! push_type (info, t))
01400     return false;
01401 
01402   if (virtual)
01403     {
01404       if (! prepend_type (info, "virtual "))
01405         return false;
01406     }
01407 
01408   switch (visibility)
01409     {
01410     case DEBUG_VISIBILITY_PUBLIC:
01411       prefix = "public ";
01412       break;
01413     case DEBUG_VISIBILITY_PROTECTED:
01414       prefix = "protected ";
01415       break;
01416     case DEBUG_VISIBILITY_PRIVATE:
01417       prefix = "private ";
01418       break;
01419     default:
01420       prefix = "/* unknown visibility */ ";
01421       break;
01422     }
01423 
01424   if (! prepend_type (info, prefix))
01425     return false;
01426 
01427   if (bitpos != 0)
01428     {
01429       print_vma (bitpos, ab, true, false);
01430       if (! append_type (info, " /* bitpos ")
01431           || ! append_type (info, ab)
01432           || ! append_type (info, " */"))
01433         return false;
01434     }
01435 
01436   /* Now the top of the stack is something like "public A / * bitpos
01437      10 * /".  The next element on the stack is something like "class
01438      xx { / * size 8 * /\n...".  We want to substitute the top of the
01439      stack in before the {.  */
01440   s = strchr (info->stack->next->type, '{');
01441   assert (s != NULL);
01442   --s;
01443 
01444   /* If there is already a ':', then we already have a baseclass, and
01445      we must append this one after a comma.  */
01446   for (l = info->stack->next->type; l != s; l++)
01447     if (*l == ':')
01448       break;
01449   if (! prepend_type (info, l == s ? " : " : ", "))
01450     return false;
01451 
01452   t = pop_type (info);
01453   if (t == NULL)
01454     return false;
01455 
01456   n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
01457   memcpy (n, info->stack->type, s - info->stack->type);
01458   strcpy (n + (s - info->stack->type), t);
01459   strcat (n, s);
01460 
01461   free (info->stack->type);
01462   info->stack->type = n;
01463 
01464   free (t);
01465 
01466   return true;
01467 }

static boolean pr_class_end_method PTR  p  )  [static]
 

Definition at line 1625 of file pstack.c.

References info, pr_stack::method, NULL, and pr_handle::stack.

01627 {
01628   struct pr_handle *info = (struct pr_handle *) p;
01629 
01630   info->stack->method = NULL;
01631   return true;
01632 }

static boolean pr_class_method_variant PTR  p,
const char *  physname,
enum debug_visibility  visibility,
boolean  constp,
boolean  volatilep,
bfd_vma  voffset,
boolean  context
[static]
 

Definition at line 1486 of file pstack.c.

References append_type(), assert, indent_type(), info, pr_stack::next, NULL, pop_type(), pr_fix_visibility(), print_vma(), pr_handle::stack, and substitute_type(