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().

01495 {
01496   struct pr_handle *info = (struct pr_handle *) p;
01497   char *method_type;
01498   char *context_type;
01499 
01500   assert (info->stack != NULL);
01501   assert (info->stack->next != NULL);
01502 
01503   /* Put the const and volatile qualifiers on the type.  */
01504   if (volatilep)
01505     {
01506       if (! append_type (info, " volatile"))
01507         return false;
01508     }
01509   if (constp)
01510     {
01511       if (! append_type (info, " const"))
01512         return false;
01513     }
01514 
01515   /* Stick the name of the method into its type.  */
01516   if (! substitute_type (info,
01517                          (context
01518                           ? info->stack->next->next->method
01519                           : info->stack->next->method)))
01520     return false;
01521 
01522   /* Get the type.  */
01523   method_type = pop_type (info);
01524   if (method_type == NULL)
01525     return false;
01526 
01527   /* Pull off the context type if there is one.  */
01528   if (! context)
01529     context_type = NULL;
01530   else
01531     {
01532       context_type = pop_type (info);
01533       if (context_type == NULL)
01534         return false;
01535     }
01536 
01537   /* Now the top of the stack is the class.  */
01538 
01539   if (! pr_fix_visibility (info, visibility))
01540     return false;
01541 
01542   if (! append_type (info, method_type)
01543       || ! append_type (info, " /* ")
01544       || ! append_type (info, physname)
01545       || ! append_type (info, " "))
01546     return false;
01547   if (context || voffset != 0)
01548     {
01549       char ab[20];
01550 
01551       if (context)
01552         {
01553           if (! append_type (info, "context ")
01554               || ! append_type (info, context_type)
01555               || ! append_type (info, " "))
01556             return false;
01557         }
01558       print_vma (voffset, ab, true, false);
01559       if (! append_type (info, "voffset ")
01560           || ! append_type (info, ab))
01561         return false;
01562     }
01563 
01564   return (append_type (info, " */;\n")
01565           && indent_type (info));
01566 }

static boolean pr_class_start_method PTR  p,
const char *  name
[static]
 

Definition at line 1472 of file pstack.c.

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

01475 {
01476   struct pr_handle *info = (struct pr_handle *) p;
01477 
01478   assert (info->stack != NULL);
01479   info->stack->method = name;
01480   return true;
01481 }

static boolean pr_class_static_member PTR  p,
const char *  name,
const char *  physname,
enum debug_visibility  visibility
[static]
 

Definition at line 1341 of file pstack.c.

References append_type(), indent_type(), info, NULL, pop_type(), pr_fix_visibility(), prepend_type(), and substitute_type().

01346 {
01347   struct pr_handle *info = (struct pr_handle *) p;
01348   char *t;
01349 
01350   if (! substitute_type (info, name))
01351     return false;
01352 
01353   if (! prepend_type (info, "static ")
01354       || ! append_type (info, "; /* ")
01355       || ! append_type (info, physname)
01356       || ! append_type (info, " */\n")
01357       || ! indent_type (info))
01358     return false;
01359 
01360   t = pop_type (info);
01361   if (t == NULL)
01362     return false;
01363 
01364   if (! pr_fix_visibility (info, visibility))
01365     return false;
01366 
01367   return append_type (info, t);
01368 }

static boolean pr_class_static_method_variant PTR  p,
const char *  physname,
enum debug_visibility  visibility,
boolean  constp,
boolean  volatilep
[static]
 

Definition at line 1571 of file pstack.c.

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

01577 {
01578   struct pr_handle *info = (struct pr_handle *) p;
01579   char *method_type;
01580 
01581   assert (info->stack != NULL);
01582   assert (info->stack->next != NULL);
01583   assert (info->stack->next->method != NULL);
01584 
01585   /* Put the const and volatile qualifiers on the type.  */
01586   if (volatilep)
01587     {
01588       if (! append_type (info, " volatile"))
01589         return false;
01590     }
01591   if (constp)
01592     {
01593       if (! append_type (info, " const"))
01594         return false;
01595     }
01596 
01597   /* Mark it as static.  */
01598   if (! prepend_type (info, "static "))
01599     return false;
01600 
01601   /* Stick the name of the method into its type.  */
01602   if (! substitute_type (info, info->stack->next->method))
01603     return false;
01604 
01605   /* Get the type.  */
01606   method_type = pop_type (info);
01607   if (method_type == NULL)
01608     return false;
01609 
01610   /* Now the top of the stack is the class.  */
01611 
01612   if (! pr_fix_visibility (info, visibility))
01613     return false;
01614 
01615   return (append_type (info, method_type)
01616           && append_type (info, " /* ")
01617           && append_type (info, physname)
01618           && append_type (info, " */;\n")
01619           && indent_type (info));
01620 }

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

Definition at line 607 of file pstack.c.

References info, pr_float_type(), and prepend_type().

00610 {
00611   struct pr_handle *info = (struct pr_handle *) p;
00612 
00613   if (! pr_float_type (p, size))
00614     return false;
00615 
00616   return prepend_type (info, "complex ");
00617 }

static boolean pr_const_type PTR  p  )  [static]
 

Definition at line 1039 of file pstack.c.

References info, and substitute_type().

01041 {
01042   struct pr_handle *info = (struct pr_handle *) p;
01043 
01044   return substitute_type (info, "const |");
01045 }

static boolean pr_empty_type PTR  p  )  [static]
 

Definition at line 551 of file pstack.c.

References info, and push_type().

00553 {
00554   struct pr_handle *info = (struct pr_handle *) p;
00555 
00556   return push_type (info, "<undefined>");
00557 }

static boolean pr_end_block PTR  p,
bfd_vma  addr
[static]
 

Definition at line 2061 of file pstack.c.

References assert, pr_handle::block, debug_block_st::end_addr, pr_handle::f, indent(), pr_handle::indent, info, debug_block_st::parent, print_vma(), and TRACE_FPRINTF.

02064 {
02065         struct pr_handle *info = (struct pr_handle *) p;
02066 
02067 #if 0
02068   char ab[20];
02069 
02070   info->indent -= 2;
02071   indent (info);
02072   print_vma (addr, ab, true, true);
02073   TRACE_FPRINTF( (info->f, "} /* %s */\n", ab));
02074 #else /* 0 */
02075         assert(info->block!=0);
02076         info->block->end_addr = addr;
02077         info->block = info->block->parent;
02078 #endif /* !0 */
02079 
02080         return true;
02081 }

static boolean pr_end_class_type PTR  p  )  [static]
 

Definition at line 1637 of file pstack.c.

References pr_end_struct_type().

01639 {
01640   return pr_end_struct_type (p);
01641 }

static boolean pr_end_function PTR  p  )  [static]
 

Definition at line 2087 of file pstack.c.

References assert, pr_handle::block, pr_handle::function, info, and NULL.

02089 {
02090         struct pr_handle *info = (struct pr_handle *) p;
02091         assert(info->block==0);
02092         info->function = NULL;
02093         return true;
02094 }

static boolean pr_end_struct_type PTR  p  )  [static]
 

Definition at line 1224 of file pstack.c.

References assert, pr_handle::indent, info, NULL, pr_handle::stack, and pr_stack::type.

Referenced by pr_end_class_type().

01226 {
01227   struct pr_handle *info = (struct pr_handle *) p;
01228   char *s;
01229 
01230   assert (info->stack != NULL);
01231   assert (info->indent >= 2);
01232 
01233   info->indent -= 2;
01234 
01235   /* Change the trailing indentation to have a close brace.  */
01236   s = info->stack->type + strlen (info->stack->type) - 2;
01237   assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
01238 
01239   *s++ = '}';
01240   *s = '\0';
01241 
01242   return true;
01243 }

static boolean pr_enum_type PTR  p,
const char *  tag,
const char **  names,
bfd_signed_vma *  values
[static]
 

Definition at line 637 of file pstack.c.

References append_type(), info, NULL, print_vma(), push_type(), and val.

00642 {
00643   struct pr_handle *info = (struct pr_handle *) p;
00644   unsigned int i;
00645   bfd_signed_vma val;
00646 
00647   if (! push_type (info, "enum "))
00648     return false;
00649   if (tag != NULL)
00650     {
00651       if (! append_type (info, tag)
00652           || ! append_type (info, " "))
00653         return false;
00654     }
00655   if (! append_type (info, "{ "))
00656     return false;
00657 
00658   if (names == NULL)
00659     {
00660       if (! append_type (info, "/* undefined */"))
00661         return false;
00662     }
00663   else
00664     {
00665       val = 0;
00666       for (i = 0; names[i] != NULL; i++)
00667         {
00668           if (i > 0)
00669             {
00670               if (! append_type (info, ", "))
00671                 return false;
00672             }
00673 
00674           if (! append_type (info, names[i]))
00675             return false;
00676 
00677           if (values[i] != val)
00678             {
00679               char ab[20];
00680 
00681               print_vma (values[i], ab, false, false);
00682               if (! append_type (info, " = ")
00683                   || ! append_type (info, ab))
00684                 return false;
00685               val = values[i];
00686             }
00687 
00688           ++val;
00689         }
00690     }
00691 
00692   return append_type (info, " }");
00693 }

static boolean pr_fix_visibility struct pr_handle info,
enum debug_visibility  visibility
[static]
 

Definition at line 1123 of file pstack.c.

References abort(), append_type(), assert, DEBUG_VISIBILITY_IGNORE, DEBUG_VISIBILITY_PRIVATE, DEBUG_VISIBILITY_PROTECTED, DEBUG_VISIBILITY_PUBLIC, indent_type(), len, and NULL.

Referenced by pr_class_method_variant(), pr_class_static_member(), pr_class_static_method_variant(), and pr_struct_field().

01126 {
01127   const char *s;
01128   char *t;
01129   unsigned int len;
01130 
01131   assert (info->stack != NULL);
01132 
01133   if (info->stack->visibility == visibility)
01134     return true;
01135 
01136   assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
01137 
01138   switch (visibility)
01139     {
01140     case DEBUG_VISIBILITY_PUBLIC:
01141       s = "public";
01142       break;
01143     case DEBUG_VISIBILITY_PRIVATE:
01144       s = "private";
01145       break;
01146     case DEBUG_VISIBILITY_PROTECTED:
01147       s = "protected";
01148       break;
01149     case DEBUG_VISIBILITY_IGNORE:
01150       s = "/* ignore */";
01151       break;
01152     default:
01153       abort ();
01154       return false;
01155     }
01156 
01157   /* Trim off a trailing space in the struct string, to make the
01158      output look a bit better, then stick on the visibility string.  */
01159 
01160   t = info->stack->type;
01161   len = strlen (t);
01162   assert (t[len - 1] == ' ');
01163   t[len - 1] = '\0';
01164 
01165   if (! append_type (info, s)
01166       || ! append_type (info, ":\n")
01167       || ! indent_type (info))
01168     return false;
01169 
01170   info->stack->visibility = visibility;
01171 
01172   return true;
01173 }

static boolean pr_float_constant PTR  p,
const char *  name,
double  val
[static]
 

Definition at line 1782 of file pstack.c.

01786 {
01787 /*
01788   struct pr_handle *info = (struct pr_handle *) p;
01789   indent (info);
01790   TRACE_FPRINTF( (info->f, "const double %s = %g;\n", name, val));
01791  */
01792   return true;
01793 }

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

Definition at line 588 of file pstack.c.

References info, and push_type().

Referenced by pr_complex_type().

00591 {
00592   struct pr_handle *info = (struct pr_handle *) p;
00593   char ab[10];
00594 
00595   if (size == 4)
00596     return push_type (info, "float");
00597   else if (size == 8)
00598     return push_type (info, "double");
00599 
00600   sprintf (ab, "float%d", size * 8);
00601   return push_type (info, ab);
00602 }

static boolean pr_function_parameter PTR  p,
const char *  name,
enum debug_parm_kind  kind,
bfd_vma  val
[static]
 

Definition at line 1922 of file pstack.c.

References debug_function_t::argc, debug_function_t::argv, assert, DEBUG_PARM_REF_REG, DEBUG_PARM_REFERENCE, DEBUG_PARM_REG, f(), free, pr_handle::function, info, debug_function_t::max_argc, debug_parameter_t::name, NULL, debug_parameter_t::offset, pop_type(), pr_reference_type(), print_vma(), realloc, substitute_type(), TRACE_FPRINTF, and xmalloc().

01927 {
01928   struct pr_handle *info = (struct pr_handle *) p;
01929   debug_function_t*     f = info->function;
01930   char *t;
01931   char ab[20];
01932   (void)ab;
01933 
01934   if (kind == DEBUG_PARM_REFERENCE
01935       || kind == DEBUG_PARM_REF_REG)
01936     {
01937       if (! pr_reference_type (p))
01938         return false;
01939     }
01940 
01941   if (! substitute_type (info, name))
01942     return false;
01943 
01944   t = pop_type (info);
01945   if (t == NULL)
01946     return false;
01947 
01948 #if 0
01949   if (info->parameter != 1)
01950     TRACE_FPRINTF( (info->f, ", "));
01951 
01952   if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
01953     TRACE_FPRINTF( (info->f, "register "));
01954 
01955   print_vma (val, ab, true, true);
01956   TRACE_FPRINTF( (info->f, "%s /* %s */", t, ab));
01957   free (t);
01958   ++info->parameter;
01959 #else /* 0 */
01960         assert(f!=NULL);
01961         if (f->argv==NULL) {
01962                 f->max_argc = 7; /* rarely anyone has more than that many args... */
01963                 f->argv = xmalloc(sizeof(debug_parameter_t)*f->max_argc);
01964         } else if (f->argc==f->max_argc) {
01965                 f->max_argc *= 2;
01966                 f->argv = realloc(f->argv,sizeof(debug_parameter_t)*f->max_argc);
01967         }
01968         f->argv[f->argc].offset = val;
01969         f->argv[f->argc].name = t;
01970         ++f->argc;
01971 #endif /* !0 */
01972         return true;
01973 }

static boolean pr_function_type PTR  p,
int  argcount,
boolean  varargs
[static]
 

Definition at line 715 of file pstack.c.

References assert, free, info, len, NULL, pop_type(), pr_handle::stack, substitute_type(), and xmalloc().

00719 {
00720   struct pr_handle *info = (struct pr_handle *) p;
00721   char **arg_types;
00722   unsigned int len;
00723   char *s;
00724 
00725   assert (info->stack != NULL);
00726 
00727   len = 10;
00728 
00729   if (argcount <= 0)
00730     {
00731       arg_types = NULL;
00732       len += 15;
00733     }
00734   else
00735     {
00736       int i;
00737 
00738       arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
00739       for (i = argcount - 1; i >= 0; i--)
00740         {
00741           if (! substitute_type (info, ""))
00742             return false;
00743           arg_types[i] = pop_type (info);
00744           if (arg_types[i] == NULL)
00745             return false;
00746           len += strlen (arg_types[i]) + 2;
00747         }
00748       if (varargs)
00749         len += 5;
00750     }
00751 
00752   /* Now the return type is on the top of the stack.  */
00753 
00754   s = (char *) xmalloc (len);
00755   strcpy (s, "(|) (");
00756 
00757   if (argcount < 0)
00758     {
00759 #if 0
00760       /* Turn off unknown arguments. */
00761       strcat (s, "/* unknown */");
00762 #endif
00763     }
00764   else
00765     {
00766       int i;
00767 
00768       for (i = 0; i < argcount; i++)
00769         {
00770           if (i > 0)
00771             strcat (s, ", ");
00772           strcat (s, arg_types[i]);
00773         }
00774       if (varargs)
00775         {
00776           if (i > 0)
00777             strcat (s, ", ");
00778           strcat (s, "...");
00779         }
00780       if (argcount > 0)
00781         free (arg_types);
00782     }
00783 
00784   strcat (s, ")");
00785 
00786   if (! substitute_type (info, s))
00787     return false;
00788 
00789   free (s);
00790 
00791   return true;
00792 }

static boolean pr_int_constant PTR  p,
const char *  name,
bfd_vma  val
[static]
 

Definition at line 1764 of file pstack.c.

01768 {
01769 /*
01770   struct pr_handle *info = (struct pr_handle *) p;
01771   char ab[20];
01772   indent (info);
01773   print_vma (val, ab, false, false);
01774   TRACE_FPRINTF( (info->f, "const int %s = %s;\n", name, ab));
01775  */
01776   return true;
01777 }

static boolean pr_int_type PTR  p,
unsigned int  size,
boolean  unsignedp
[static]
 

Definition at line 573 of file pstack.c.

References info, and push_type().

00577 {
00578   struct pr_handle *info = (struct pr_handle *) p;
00579   char ab[10];
00580 
00581   sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
00582   return push_type (info, ab);
00583 }

static boolean pr_lineno PTR  p,
const char *  filename,
unsigned long  lineno,
bfd_vma  addr
[static]
 

Definition at line 2021 of file pstack.c.

References debug_lineno_t::addr, assert, pr_handle::f, f(), debug_function_t::filename, pr_handle::function, indent(), info, debug_lineno_t::lineno, debug_function_t::lines, debug_function_t::lines_count, debug_function_t::max_lines_count, NULL, print_vma(), TRACE_FPRINTF, xmalloc(), and xrealloc().

02026 {
02027         struct pr_handle *info = (struct pr_handle *) p;
02028         char ab[20];
02029         debug_function_t*       f = info->function;
02030         (void)ab;
02031 
02032 #if 0
02033   indent (info);
02034   print_vma (addr, ab, true, true);
02035   TRACE_FPRINTF( (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab));
02036 #else /* 0 */
02037         if (f==NULL)    /* FIXME: skips junk silently. */
02038                 return true;
02039         /* assert(f!=NULL); */
02040         if (f->filename==NULL) {
02041                 f->filename = filename;
02042                 assert(f->lines==0);
02043                 f->max_lines_count = 4;
02044                 f->lines = xmalloc(sizeof(debug_lineno_t)*f->max_lines_count);
02045         }
02046         if (f->lines_count==f->max_lines_count) {
02047                 f->max_lines_count *= 2;
02048                 f->lines = xrealloc(f->lines, sizeof(debug_lineno_t)*f->max_lines_count);
02049         }
02050         f->lines[f->lines_count].lineno = lineno;
02051         f->lines[f->lines_count].addr = addr;
02052         ++f->lines_count;
02053 #endif /* !0 */
02054 
02055   return true;
02056 }

static boolean pr_method_type PTR  p,
boolean  domain,
int  argcount,
boolean  varargs
[static]
 

Definition at line 938 of file pstack.c.

References free, info, len, NULL, pop_type(), strchr(), substitute_type(), and xmalloc().

00943 {
00944   struct pr_handle *info = (struct pr_handle *) p;
00945   unsigned int len;
00946   char *domain_type;
00947   char **arg_types;
00948   char *s;
00949 
00950   len = 10;
00951 
00952   if (! domain)
00953     domain_type = NULL;
00954   else
00955     {
00956       if (! substitute_type (info, ""))
00957         return false;
00958       domain_type = pop_type (info);
00959       if (domain_type == NULL)
00960         return false;
00961       if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0
00962           && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
00963         domain_type += sizeof "class " - 1;
00964       else if (strncmp (domain_type, "union class ",
00965                         sizeof "union class ") == 0
00966                && (strchr (domain_type + sizeof "union class " - 1, ' ')
00967                    == NULL))
00968         domain_type += sizeof "union class " - 1;
00969       len += strlen (domain_type);
00970     }
00971 
00972   if (argcount <= 0)
00973     {
00974       arg_types = NULL;
00975       len += 15;
00976     }
00977   else
00978     {
00979       int i;
00980 
00981       arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
00982       for (i = argcount - 1; i >= 0; i--)
00983         {
00984           if (! substitute_type (info, ""))
00985             return false;
00986           arg_types[i] = pop_type (info);
00987           if (arg_types[i] == NULL)
00988             return false;
00989           len += strlen (arg_types[i]) + 2;
00990         }
00991       if (varargs)
00992         len += 5;
00993     }
00994 
00995   /* Now the return type is on the top of the stack.  */
00996 
00997   s = (char *) xmalloc (len);
00998   if (! domain)
00999     *s = '\0';
01000   else
01001     strcpy (s, domain_type);
01002   strcat (s, "::| (");
01003 
01004   if (argcount < 0)
01005     strcat (s, "/* unknown */");
01006   else
01007     {
01008       int i;
01009 
01010       for (i = 0; i < argcount; i++)
01011         {
01012           if (i > 0)
01013             strcat (s, ", ");
01014           strcat (s, arg_types[i]);
01015         }
01016       if (varargs)
01017         {
01018           if (i > 0)
01019             strcat (s, ", ");
01020           strcat (s, "...");
01021         }
01022       if (argcount > 0)
01023         free (arg_types);
01024     }
01025 
01026   strcat (s, ")");
01027 
01028   if (! substitute_type (info, s))
01029     return false;
01030 
01031   free (s);
01032 
01033   return true;
01034 }

static boolean pr_offset_type PTR  p  )  [static]
 

Definition at line 916 of file pstack.c.

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

00918 {
00919   struct pr_handle *info = (struct pr_handle *) p;
00920   char *t;
00921 
00922   if (! substitute_type (info, ""))
00923     return false;
00924 
00925   t = pop_type (info);
00926   if (t == NULL)
00927     return false;
00928 
00929   return (substitute_type (info, "")
00930           && prepend_type (info, " ")
00931           && prepend_type (info, t)
00932           && append_type (info, "::|"));
00933 }

static boolean pr_pointer_type PTR  p  )  [static]
 

Definition at line 698 of file pstack.c.

References assert, info, NULL, pr_handle::stack, strchr(), substitute_type(), and pr_stack::type.

00700 {
00701   struct pr_handle *info = (struct pr_handle *) p;
00702   char *s;
00703 
00704   assert (info->stack != NULL);
00705 
00706   s = strchr (info->stack->type, '|');
00707   if (s != NULL && s[1] == '[')
00708     return substitute_type (info, "(*|)");
00709   return substitute_type (info, "*|");
00710 }

static boolean pr_range_type PTR  p,
bfd_signed_vma  lower,
bfd_signed_vma  upper
[static]
 

Definition at line 810 of file pstack.c.

References append_type(), assert, info, NULL, prepend_type(), print_vma(), pr_handle::stack, and substitute_type().

00814 {
00815   struct pr_handle *info = (struct pr_handle *) p;
00816   char abl[20], abu[20];
00817 
00818   assert (info->stack != NULL);
00819 
00820   if (! substitute_type (info, ""))
00821     return false;
00822 
00823   print_vma (lower, abl, false, false);
00824   print_vma (upper, abu, false, false);
00825 
00826   return (prepend_type (info, "range (")
00827           && append_type (info, "):")
00828           && append_type (info, abl)
00829           && append_type (info, ":")
00830           && append_type (info, abu));
00831 }

static boolean pr_reference_type PTR  p  )  [static]
 

Definition at line 797 of file pstack.c.

References assert, info, NULL, pr_handle::stack, and substitute_type().

Referenced by pr_function_parameter().

00799 {
00800   struct pr_handle *info = (struct pr_handle *) p;
00801 
00802   assert (info->stack != NULL);
00803 
00804   return substitute_type (info, "&|");
00805 }

static boolean pr_set_type PTR  p,
boolean  bitstringp
[static]
 

Definition at line 891 of file pstack.c.

References append_type(), info, prepend_type(), and substitute_type().

00894 {
00895   struct pr_handle *info = (struct pr_handle *) p;
00896 
00897   if (! substitute_type (info, ""))
00898     return false;
00899 
00900   if (! prepend_type (info, "set { ")
00901       || ! append_type (info, " }"))
00902     return false;
00903 
00904   if (bitstringp)
00905     {
00906       if (! append_type (info, "/* bitstring */"))
00907         return false;
00908     }
00909 
00910   return true;
00911 }

static boolean pr_start_block PTR  p,
bfd_vma  addr
[static]
 

Definition at line 1978 of file pstack.c.

References debug_block_st::begin_addr, debug_function_t::block, pr_handle::block, yaSSL::block, debug_block_st::childs, debug_block_st::childs_count, debug_block_st::end_addr, pr_handle::f, pr_handle::function, pr_handle::indent, indent(), info, NULL, pr_handle::parameter, debug_block_st::parent, print_vma(), TRACE_FPRINTF, xmalloc(), and xrealloc().

01981 {
01982         struct pr_handle *info = (struct pr_handle *) p;
01983         char ab[20];
01984         debug_block_t*  block = 0;
01985         (void)ab;
01986 #if 0
01987   if (info->parameter > 0)
01988     {
01989       TRACE_FPRINTF( (info->f, ")\n"));
01990       info->parameter = 0;
01991     }
01992   indent (info);
01993   print_vma (addr, ab, true, true);
01994   TRACE_FPRINTF( (info->f, "{ /* %s */\n", ab));
01995   info->indent += 2;
01996 #else
01997         if (info->block) {
01998                 if (info->block->childs_count==0)
01999                         info->block->childs = xmalloc(sizeof(debug_block_t));
02000                 else
02001                         info->block->childs = xrealloc(info->block->childs,
02002                                                 info->block->childs_count*sizeof(debug_block_t));
02003                 block = &info->block->childs[info->block->childs_count];
02004         } else {
02005                 block = xmalloc(sizeof(debug_block_t));
02006                 info->function->block = block;
02007         }
02008         block->begin_addr = addr;
02009         block->end_addr = 0;
02010         block->parent = info->block;
02011         block->childs = NULL;
02012         block->childs_count = 0;
02013         info->block = block;
02014 #endif
02015         return true;
02016 }

static boolean pr_start_class_type PTR  p,
const char *  tag,
unsigned int  id,
boolean  structp,
unsigned int  size,
boolean  vptr,
boolean  ownvptr
[static]
 

Definition at line 1248 of file pstack.c.

References append_type(), DEBUG_VISIBILITY_PRIVATE, pr_handle::indent, indent_type(), info, NULL, pop_type(), and push_type().

01256 {
01257   struct pr_handle *info = (struct pr_handle *) p;
01258   char *tv = NULL;
01259 
01260   info->indent += 2;
01261 
01262   if (vptr && ! ownvptr)
01263     {
01264       tv = pop_type (info);
01265       if (tv == NULL)
01266         return false;
01267     }
01268 
01269   if (! push_type (info, structp ? "class " : "union class "))
01270     return false;
01271   if (tag != NULL)
01272     {
01273       if (! append_type (info, tag))
01274         return false;
01275     }
01276   else
01277     {
01278       char idbuf[20];
01279 
01280       sprintf (idbuf, "%%anon%u", id);
01281       if (! append_type (info, idbuf))
01282         return false;
01283     }
01284 
01285   if (! append_type (info, " {"))
01286     return false;
01287   if (size != 0 || vptr || ownvptr || tag != NULL)
01288     {
01289       if (! append_type (info, " /*"))
01290         return false;
01291 
01292       if (size != 0)
01293         {
01294           char ab[20];
01295 
01296           sprintf (ab, "%u", size);
01297           if (! append_type (info, " size ")
01298               || ! append_type (info, ab))
01299             return false;
01300         }
01301 
01302       if (vptr)
01303         {
01304           if (! append_type (info, " vtable "))
01305             return false;
01306           if (ownvptr)
01307             {
01308               if (! append_type (info, "self "))
01309                 return false;
01310             }
01311           else
01312             {
01313               if (! append_type (info, tv)
01314                   || ! append_type (info, " "))
01315                 return false;
01316             }
01317         }
01318 
01319       if (tag != NULL)
01320         {
01321           char ab[30];
01322 
01323           sprintf (ab, " id %u", id);
01324           if (! append_type (info, ab))
01325             return false;
01326         }
01327 
01328       if (! append_type (info, " */"))
01329         return false;
01330     }
01331 
01332   info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
01333 
01334   return (append_type (info, "\n")
01335           && indent_type (info));
01336 }

static boolean pr_start_compilation_unit PTR  p,
const char *  filename
[static]
 

Definition at line 519 of file pstack.c.

References assert, pr_handle::indent, and info.

00522 {
00523   struct pr_handle *info = (struct pr_handle *) p;
00524 
00525   assert (info->indent == 0);
00526 /*
00527   TRACE_FPRINTF( (info->f, "%s:\n", filename));
00528 */
00529   return true;
00530 }

static boolean pr_start_function PTR  p,
const char *  name,
boolean  global
[static]
 

Definition at line 1874 of file pstack.c.

References assert, indent(), info, NULL, pop_type(), substitute_type(), TRACE_FPRINTF, and xrealloc().

01878 {
01879   struct pr_handle *info = (struct pr_handle *) p;
01880   char *t;
01881 
01882   if (! substitute_type (info, name))
01883     return false;
01884 
01885   t = pop_type (info);
01886   if (t == NULL)
01887     return false;
01888 
01889 #if 0
01890   indent (info);
01891   if (! global)
01892     TRACE_FPRINTF( (info->f, "static "));
01893   TRACE_FPRINTF( (info->f, "%s (", t));
01894   info->parameter = 1;
01895 #else /* 0 */
01896         if (info->functions_size==info->functions_maxsize) {
01897                 info->functions_maxsize *= 2;
01898                 info->functions = xrealloc(info->functions,
01899                         info->functions_maxsize*sizeof(debug_function_t));
01900                 assert(info->functions!=0);
01901         }
01902         /* info->functions[info->functions_size] = xmalloc(sizeof(debug_function_t)); */
01903         info->function = &info->functions[info->functions_size];
01904         ++info->functions_size;
01905         info->function->symbol = NULL;
01906         info->function->lines = NULL;
01907         info->function->lines_count = 0;
01908         info->function->max_lines_count = 0;
01909         info->function->name = t;
01910         info->function->filename = NULL;
01911         info->function->block = NULL;
01912         info->function->argv = NULL;
01913         info->function->argc = 0;
01914         info->function->max_argc = 0;
01915 #endif /* !0 */
01916         return true;
01917 }

static boolean pr_start_source PTR  p,
const char *  filename
[static]
 

Definition at line 535 of file pstack.c.

References assert, pr_handle::indent, and info.

00538 {
00539   struct pr_handle *info = (struct pr_handle *) p;
00540 
00541   assert (info->indent == 0);
00542 /*
00543   TRACE_FPRINTF( (info->f, " %s:\n", filename));
00544 */
00545   return true;
00546 }

static boolean pr_start_struct_type PTR  p,
const char *  tag,
unsigned int  id,
boolean  structp,
unsigned int  size
[static]
 

Definition at line 1061 of file pstack.c.

References append_type(), DEBUG_VISIBILITY_PUBLIC, pr_handle::indent, indent_type(), info, NULL, and push_type().

01067 {
01068   struct pr_handle *info = (struct pr_handle *) p;
01069 
01070   info->indent += 2;
01071 
01072   if (! push_type (info, structp ? "struct " : "union "))
01073     return false;
01074   if (tag != NULL)
01075     {
01076       if (! append_type (info, tag))
01077         return false;
01078     }
01079   else
01080     {
01081       char idbuf[20];
01082 
01083       sprintf (idbuf, "%%anon%u", id);
01084       if (! append_type (info, idbuf))
01085         return false;
01086     }
01087 
01088   if (! append_type (info, " {"))
01089     return false;
01090   if (size != 0 || tag != NULL)
01091     {
01092       char ab[30];
01093 
01094       if (! append_type (info, " /*"))
01095         return false;
01096 
01097       if (size != 0)
01098         {
01099           sprintf (ab, " size %u", size);
01100           if (! append_type (info, ab))
01101             return false;
01102         }
01103       if (tag != NULL)
01104         {
01105           sprintf (ab, " id %u", id);
01106           if (! append_type (info, ab))
01107             return false;
01108         }
01109       if (! append_type (info, " */"))
01110         return false;
01111     }
01112   if (! append_type (info, "\n"))
01113     return false;
01114 
01115   info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
01116 
01117   return indent_type (info);
01118 }

static boolean pr_struct_field PTR  p,
const char *  name,
bfd_vma  bitpos,
bfd_vma  bitsize,
enum debug_visibility  visibility
[static]
 

Definition at line 1178 of file pstack.c.

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

01184 {
01185   struct pr_handle *info = (struct pr_handle *) p;
01186   char ab[20];
01187   char *t;
01188 
01189   if (! substitute_type (info, name))
01190     return false;
01191 
01192   if (! append_type (info, "; /* "))
01193     return false;
01194 
01195   if (bitsize != 0)
01196     {
01197       print_vma (bitsize, ab, true, false);
01198       if (! append_type (info, "bitsize ")
01199           || ! append_type (info, ab)
01200           || ! append_type (info, ", "))
01201         return false;
01202     }
01203 
01204   print_vma (bitpos, ab, true, false);
01205   if (! append_type (info, "bitpos ")
01206       || ! append_type (info, ab)
01207       || ! append_type (info, " */\n")
01208       || ! indent_type (info))
01209     return false;
01210 
01211   t = pop_type (info);
01212   if (t == NULL)
01213     return false;
01214 
01215   if (! pr_fix_visibility (info, visibility))
01216     return false;
01217 
01218   return append_type (info, t);
01219 }

static boolean pr_tag PTR  p,
const char *  name
[static]
 

Definition at line 1742 of file pstack.c.

References free, info, NULL, and pop_type().

01745 {
01746   struct pr_handle *info = (struct pr_handle *) p;
01747   char *t;
01748 
01749   t = pop_type (info);
01750   if (t == NULL)
01751     return false;
01752 /*
01753   indent (info);
01754   TRACE_FPRINTF( (info->f, "%s;\n", t));
01755 */
01756   free (t);
01757 
01758   return true;
01759 }

static boolean pr_tag_type PTR  p,
const char *  name,
unsigned int  id,
enum debug_type_kind  kind
[static]
 

Definition at line 1658 of file pstack.c.

References abort(), append_type(), DEBUG_KIND_CLASS, DEBUG_KIND_ENUM, DEBUG_KIND_STRUCT, DEBUG_KIND_UNION, DEBUG_KIND_UNION_CLASS, info, NULL, and push_type().

01663 {
01664   struct pr_handle *info = (struct pr_handle *) p;
01665   const char *t, *tag;
01666   char idbuf[30];
01667 
01668   switch (kind)
01669     {
01670     case DEBUG_KIND_STRUCT:
01671       t = "struct ";
01672       break;
01673     case DEBUG_KIND_UNION:
01674       t = "union ";
01675       break;
01676     case DEBUG_KIND_ENUM:
01677       t = "enum ";
01678       break;
01679     case DEBUG_KIND_CLASS:
01680       t = "class ";
01681       break;
01682     case DEBUG_KIND_UNION_CLASS:
01683       t = "union class ";
01684       break;
01685     default:
01686       abort ();
01687       return false;
01688     }
01689 
01690   if (! push_type (info, t))
01691     return false;
01692   if (name != NULL)
01693     tag = name;
01694   else
01695     {
01696       sprintf (idbuf, "%%anon%u", id);
01697       tag = idbuf;
01698     }
01699 
01700   if (! append_type (info, tag))
01701     return false;
01702   if (name != NULL && kind != DEBUG_KIND_ENUM)
01703     {
01704       sprintf (idbuf, " /* id %u */", id);
01705       if (! append_type (info, idbuf))
01706         return false;
01707     }
01708 
01709   return true;
01710 }

static boolean pr_typdef PTR  p,
const char *  name
[static]
 

Definition at line 1715 of file pstack.c.

References free, info, NULL, pop_type(), and substitute_type().

01718 {
01719   struct pr_handle *info = (struct pr_handle *) p;
01720   char *s;
01721 
01722   if (! substitute_type (info, name))
01723     return false;
01724 
01725   s = pop_type (info);
01726   if (s == NULL)
01727     return false;
01728 /*
01729   indent (info);
01730   TRACE_FPRINTF( (info->f, "typedef %s;\n", s));
01731 */
01732   free (s);
01733 
01734   return true;
01735 }

static boolean pr_typed_constant PTR  p,
const char *  name,
bfd_vma  val
[static]
 

Definition at line 1798 of file pstack.c.

References free, info, NULL, and pop_type().

01802 {
01803   struct pr_handle *info = (struct pr_handle *) p;
01804   char *t;
01805 
01806   t = pop_type (info);
01807   if (t == NULL)
01808     return false;
01809 /*
01810   char ab[20];
01811   indent (info);
01812   print_vma (val, ab, false, false);
01813   TRACE_FPRINTF( (info->f, "const %s %s = %s;\n", t, name, ab));
01814 */
01815   free (t);
01816 
01817   return true;
01818 }

static boolean pr_typedef_type PTR  p,
const char *  name
[static]
 

Definition at line 1646 of file pstack.c.

References info, and push_type().

01649 {
01650   struct pr_handle *info = (struct pr_handle *) p;
01651 
01652   return push_type (info, name);
01653 }

static boolean pr_variable PTR  p,
const char *  name,
enum debug_var_kind  kind,
bfd_vma  val
[static]
 

Definition at line 1823 of file pstack.c.

References DEBUG_LOCAL_STATIC, DEBUG_REGISTER, DEBUG_STATIC, free, indent(), info, NULL, pop_type(), print_vma(), substitute_type(), and TRACE_FPRINTF.

01828 {
01829   struct pr_handle *info = (struct pr_handle *) p;
01830   char *t;
01831   char ab[20];
01832   (void)ab;
01833 
01834   if (! substitute_type (info, name))
01835     return false;
01836 
01837   t = pop_type (info);
01838   if (t == NULL)
01839     return false;
01840 
01841 #if 0
01842   indent (info);
01843   switch (kind)
01844     {
01845     case DEBUG_STATIC:
01846     case DEBUG_LOCAL_STATIC:
01847       TRACE_FPRINTF( (info->f, "static "));
01848       break;
01849     case DEBUG_REGISTER:
01850       TRACE_FPRINTF( (info->f, "register "));
01851       break;
01852     default:
01853       break;
01854     }
01855   print_vma (val, ab, true, true);
01856   TRACE_FPRINTF( (info->f, "%s /* %s */;\n", t, ab));
01857 #else /* 0 */
01858 #if 0
01859         if (kind==DEBUG_STATIC || kind==DEBUG_LOCAL_STATIC) {
01860                 print_vma (val, ab, true, true);
01861                 TRACE_FPRINTF( (info->f, "STATIC_VAR: %s /* %s */;\n", t, ab));
01862         }
01863 #endif /* 0 */
01864 #endif /* !0 */
01865 
01866   free (t);
01867 
01868   return true;
01869 }

static boolean pr_void_type PTR  p  )  [static]
 

Definition at line 562 of file pstack.c.

References info, and push_type().

00564 {
00565   struct pr_handle *info = (struct pr_handle *) p;
00566 
00567   return push_type (info, "void");
00568 }

static boolean pr_volatile_type PTR  p  )  [static]
 

Definition at line 1050 of file pstack.c.

References info, and substitute_type().

01052 {
01053   struct pr_handle *info = (struct pr_handle *) p;
01054 
01055   return substitute_type (info, "volatile |");
01056 }

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

Definition at line 370 of file pstack.c.

References assert, free, n, NULL, and xmalloc().

Referenced by pr_class_baseclass(), pr_class_static_member(), pr_class_static_method_variant(), pr_complex_type(), pr_offset_type(), pr_range_type(), pr_set_type(), and substitute_type().

00373 {
00374   char *n;
00375 
00376   assert (info->stack != NULL);
00377 
00378   n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
00379   sprintf (n, "%s%s", s, info->stack->type);
00380   free (info->stack->type);
00381   info->stack->type = n;
00382 
00383   return true;
00384 }

static void print_vma bfd_vma  vma,
char *  buf,
boolean  unsignedp,
boolean  hexp
[static]
 

Definition at line 493 of file pstack.c.

Referenced by pr_array_type(), pr_class_baseclass(), pr_class_method_variant(), pr_end_block(), pr_enum_type(), pr_function_parameter(), pr_lineno(), pr_range_type(), pr_start_block(), pr_struct_field(), and pr_variable().

00498 {
00499   if (sizeof (vma) <= sizeof (unsigned long))
00500     {
00501       if (hexp)
00502         sprintf (buf, "0x%lx", (unsigned long) vma);
00503       else if (unsignedp)
00504         sprintf (buf, "%lu", (unsigned long) vma);
00505       else
00506         sprintf (buf, "%ld", (long) vma);
00507     }
00508   else
00509     {
00510       buf[0] = '0';
00511       buf[1] = 'x';
00512       sprintf_vma (buf + 2, vma);
00513     }
00514 }

int pstack_install_segv_action const char *  path_format_  ) 
 

Definition at line 2630 of file pstack.c.

References assert, pr_handle::block, compare_debug_function_t(), compare_symbols(), debug_write(), pr_handle::f, pr_handle::function, pr_handle::functions, pr_handle::functions_maxsize, pr_handle::functions_size, pr_handle::indent, list_supported_targets(), load_bfd(), memcpy, name, NULL, pr_handle::parameter, path_format, perror(), program_name, qsort(), read_debugging_info(), remove_useless_symbols(), report_action(), segv_action(), set_default_bfd_target(), sigemptyset, pr_handle::stack, TRACE_FPRINTF, value, and xmalloc().

Referenced by signal_hand().

02631 {
02632         const int               pid = getpid();
02633         struct sigaction        act;
02634 
02635         /* Store what we have to for later usage. */
02636         path_format = path_format_;
02637 
02638         /* We need a signal action for SIGSEGV and sigreport ! */
02639         sigreport = SIGUSR1;
02640         act.sa_handler = 0;
02641         sigemptyset(&act.sa_mask);
02642         act.sa_flags = SA_SIGINFO|SA_ONESHOT;   /* Just one SIGSEGV. */
02643         act.sa_sigaction = segv_action;
02644         act.sa_restorer = NULL;
02645         if (sigaction(SIGSEGV, &act, NULL)!=0) {
02646                 perror("sigaction");
02647                 return 1;
02648         }
02649         act.sa_sigaction = report_action;
02650         act.sa_flags = SA_SIGINFO;              /* But many sigreports. */
02651         if (sigaction(sigreport, &act, NULL)!=0) {
02652                 perror("sigaction");
02653                 return 1;
02654         }
02655 
02656         /* And a little setup for libiberty. */
02657         program_name = "crashing";
02658         xmalloc_set_program_name (program_name);
02659 
02660         /* Umm, and initialize BFD, too */
02661         bfd_init();
02662 #if 0
02663         list_supported_targets(0, stdout);
02664         set_default_bfd_target(); 
02665 #endif /* 0 */
02666 
02667         if ((abfd = load_bfd(pid))==0)
02668                 fprintf(stderr, "BFD load failed..\n");
02669         else {
02670                 long    storage_needed= (bfd_get_file_flags(abfd) & HAS_SYMS) ?
02671                   bfd_get_symtab_upper_bound (abfd) : 0;
02672                 long    i;
02673                 (void)i;
02674 
02675                 if (storage_needed < 0)
02676                         fprintf(stderr, "Symbol table size estimation failure.\n");
02677                 else if (storage_needed > 0) {
02678                         syms = (asymbol **) xmalloc (storage_needed);
02679                         symcount = bfd_canonicalize_symtab (abfd, syms);
02680 
02681                         TRACE_FPRINTF((stderr, "TOTAL: %ld SYMBOLS.\n", symcount));
02682                         /* We need debugging info, too! */
02683                         if (symcount==0 || (dhandle = read_debugging_info (abfd, syms, symcount))==0)
02684                                 fprintf(stderr, "NO DEBUGGING INFORMATION FOUND.\n");
02685 
02686                         /* We make a copy of syms to sort.  We don't want to sort syms
02687                         because that will screw up the relocs.  */
02688                         sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
02689                         memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
02690 
02691 #if 0
02692                         for (i=0; i<symcount; ++i)
02693                                 if (syms[i]->name!=0 && strlen(syms[i]->name)>0 && syms[i]->value!=0)
02694                                         printf("%08lx T %s\n", syms[i]->section->vma + syms[i]->value, syms[i]->name);
02695 #endif
02696                         sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
02697                         TRACE_FPRINTF((stderr, "SORTED: %ld SYMBOLS.\n", sorted_symcount));
02698 
02699                         /* Sort the symbols into section and symbol order */
02700                         qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
02701 #if 0
02702                         for (i=0; i<sorted_symcount; ++i)
02703                                 if (sorted_syms[i]->name!=0 && strlen(sorted_syms[i]->name)>0 && sorted_syms[i]->value!=0)
02704                                         printf("%08lx T %s\n", sorted_syms[i]->section->vma + sorted_syms[i]->value, sorted_syms[i]->name);
02705 #endif
02706                         /* We have symbols, we need debugging info somehow sorted out. */
02707                         if (dhandle==0) {
02708                                 fprintf(stderr, "STACK TRACE WILL BE UNCOMFORTABLE.\n");
02709                         } else {
02710                                 /* Start collecting the debugging information.... */
02711                                 struct pr_handle info;
02712 
02713                                 info.f = stdout;
02714                                 info.indent = 0;
02715                                 info.stack = NULL;
02716                                 info.parameter = 0;
02717                                 info.block = NULL;
02718                                 info.function = NULL;
02719                                 info.functions_size = 0;
02720                                 info.functions_maxsize = 1000;
02721                                 info.functions = (debug_function_t*)xmalloc(sizeof(debug_function_t)*info.functions_maxsize);
02722                                 debug_write (dhandle, &pr_fns, (PTR) &info);
02723                                 TRACE_FPRINTF((stdout, "\n%d DEBUG SYMBOLS\n", info.functions_size));
02724                                 assert(info.functions_size!=0);
02725                                 functions = xmalloc(sizeof(debug_function_t*)*info.functions_size);
02726                                 functions_size = info.functions_size;
02727                                 for (i=0; i<functions_size; ++i)
02728                                         functions[i] = &info.functions[i];
02729                                 /* Sort the symbols into section and symbol order */
02730                                 qsort (functions, functions_size, sizeof(debug_function_t*),
02731                                         compare_debug_function_t);
02732 #if 0
02733                                 for (i=0; i<info.functions_size; ++i)
02734                                         fprintf(stdout, "%08lx T %s\n", info.functions[i].block->begin_addr, info.functions[i].name);
02735 #endif
02736                                 fflush(stdout);
02737                         }
02738                 } else /* storage_needed == 0 */
02739                         fprintf(stderr, "NO SYMBOLS FOUND.\n");
02740         }
02741         return 0;
02742 }

static boolean push_type struct pr_handle info,
const char *  type
[static]
 

Definition at line 346 of file pstack.c.

References DEBUG_VISIBILITY_IGNORE, memset, n, NULL, and xmalloc().

Referenced by pr_bool_type(), pr_class_baseclass(), pr_empty_type(), pr_enum_type(), pr_float_type(), pr_int_type(), pr_start_class_type(), pr_start_struct_type(), pr_tag_type(), pr_typedef_type(), and pr_void_type().

00349 {
00350   struct pr_stack *n;
00351 
00352   if (type == NULL)
00353     return false;
00354 
00355   n = (struct pr_stack *) xmalloc (sizeof *n);
00356   memset (n, 0, sizeof *n);
00357 
00358   n->type = xstrdup (type);
00359   n->visibility = DEBUG_VISIBILITY_IGNORE;
00360   n->method = NULL;
00361   n->next = info->stack;
00362   info->stack = n;
00363 
00364   return true;
00365 }

static long remove_useless_symbols asymbol **  symbols,
long  count
[static]
 

Definition at line 2516 of file pstack.c.

References NULL.

Referenced by pstack_install_segv_action().

02518 {
02519         asymbol**       in_ptr = symbols;
02520         asymbol**       out_ptr = symbols;
02521 
02522         while (--count >= 0) {
02523                 asymbol *sym = *in_ptr++;
02524 
02525                 if (sym->name == NULL || sym->name[0] == '\0' || sym->value==0)
02526                         continue;
02527                 if (sym->flags & (BSF_DEBUGGING))
02528                         continue;
02529                 if (bfd_is_und_section (sym->section) || bfd_is_com_section (sym->section))
02530                         continue;
02531                 *out_ptr++ = sym;
02532         }
02533         return out_ptr - symbols;
02534 }

static void report_action int  signo,
siginfo_t *  siginfo,
void *  ptr
[static]
 

Definition at line 2589 of file pstack.c.

References assert, close(), fdprintf(), symbol_data_t::functions, symbol_data_t::functions_size, my_crawl(), open_log_file(), show_regs(), symbol_data_t::symcount, and symbol_data_t::syms.

Referenced by pstack_install_segv_action().

02590 {
02591         const int       pid = getpid();
02592         pthread_t       tid = pthread_self();
02593         symbol_data_t   symbol_data;
02594         int             fd;
02595         if (pthread_equal(tid, segv_tid)) {
02596                 /* We have already printed our stack trace... */
02597                 return;
02598         }
02599 
02600         fd = open_log_file(tid, pid);
02601         fdprintf(fd, "REPORT: CURRENT PROCESS:%d, THREAD:%d\n", getpid(), pthread_self());
02602         /* signal(SIGSEGV, SIG_DFL); */
02603         ptrace_regs = (signal_regs_t*)ptr;
02604         assert(ptrace_regs!=0);
02605 
02606         /* Show user how guilty we are. */
02607         fdprintf(fd,"--------- STACK TRACE FOR PROCESS %d, THREAD %d ---------------\n", pid, pthread_self());
02608         show_regs(ptrace_regs, fd);
02609 
02610         /* Some form of stack trace, too. */
02611         fdprintf(fd, "STACK TRACE:\n");
02612 
02613         symbol_data.syms = sorted_syms;
02614         symbol_data.symcount = sorted_symcount;
02615         symbol_data.functions = functions;
02616         symbol_data.functions_size = functions_size;
02617         my_crawl(pid, &symbol_data, fd);
02618         //fflush(stdout);
02619         close(fd);
02620         /* Tell segv_thread to proceed after pause(). */
02621         /*pthread_kill(segv_tid, sigreport);
02622         kill(segv_pid, sigreport);
02623         pthread_cancel(tid); */
02624 }

static void segv_action int  signo,
siginfo_t *  siginfo,
void *  ptr
[static]
 

Definition at line 2558 of file pstack.c.

References assert, close(), fdprintf(), symbol_data_t::functions, symbol_data_t::functions_size, linuxthreads_notify_others(), my_crawl(), open_log_file(), show_regs(), symbol_data_t::symcount, and symbol_data_t::syms.

Referenced by pstack_install_segv_action().

02559 {
02560         symbol_data_t           symbol_data;
02561         int                     fd = -1;
02562 
02563         segv_pid = getpid();
02564         segv_tid = pthread_self();
02565         fd = open_log_file(segv_tid, segv_pid);
02566         /* signal(SIGSEGV, SIG_DFL); */
02567         ptrace_regs = (signal_regs_t*)ptr;
02568         assert(ptrace_regs!=0);
02569 
02570         /* Show user how guilty we are. */
02571         fdprintf(fd,"--------- SEGV in PROCESS %d, THREAD %d ---------------\n", segv_pid, pthread_self());
02572         show_regs(ptrace_regs, fd);
02573 
02574         /* Some form of stack trace, too. */
02575         fdprintf(fd, "STACK TRACE:\n");
02576 
02577         symbol_data.syms = sorted_syms;
02578         symbol_data.symcount = sorted_symcount;
02579         symbol_data.functions = functions;
02580         symbol_data.functions_size = functions_size;
02581         my_crawl(segv_pid, &symbol_data, fd);
02582         //fflush(stdout);
02583         close(fd);
02584         linuxthreads_notify_others(sigreport);
02585 }

static void show_regs signal_regs_t regs,
int  fd
[static]
 

Definition at line 2406 of file pstack.c.

References signal_regs_t::eax, signal_regs_t::ebp, signal_regs_t::ebx, signal_regs_t::ecx, signal_regs_t::edi, signal_regs_t::edx, signal_regs_t::eip, signal_regs_t::esi, signal_regs_t::esp, signal_regs_t::fault_addr, fdprintf(), signal_regs_t::xcs, signal_regs_t::xds, signal_regs_t::xes, and signal_regs_t::xss.

Referenced by report_action(), and segv_action().

02408 {
02409         /* long cr0 = 0L, cr2 = 0L, cr3 = 0L; */
02410 
02411         fdprintf(fd,"\n");
02412         fdprintf(fd,"FAULT ADDR: %08x\n", regs->fault_addr);
02413         fdprintf(fd,"EIP: %04x:[<%08x>]",0xffff & regs->xcs,regs->eip);
02414         if (regs->xcs & 3)
02415                 fdprintf(fd," ESP: %04x:%08x",0xffff & regs->xss,regs->esp);
02416         /*fdprintf(fd," EFLAGS: %08lx\n",regs->eflags); */
02417         fdprintf(fd, "\n");
02418         fdprintf(fd,"EAX: %08x EBX: %08x ECX: %08x EDX: %08x\n",
02419                 regs->eax,regs->ebx,regs->ecx,regs->edx);
02420         fdprintf(fd,"ESI: %08x EDI: %08x EBP: %08x",
02421                 regs->esi, regs->edi, regs->ebp);
02422         fdprintf(fd," DS: %04x ES: %04x\n",
02423                 0xffff & regs->xds,0xffff & regs->xes);
02424         /*
02425         __asm__("movl %%cr0, %0": "=r" (cr0));
02426         __asm__("movl %%cr2, %0": "=r" (cr2));
02427         __asm__("movl %%cr3, %0": "=r" (cr3));
02428         fprintf(stderr,"CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3); */
02429 }

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

Definition at line 413 of file pstack.c.

References append_type(), assert, free, memcpy, n, NULL, prepend_type(), strchr(), and xmalloc().

Referenced by pr_array_type(), pr_class_baseclass(), pr_class_method_variant(), pr_class_static_member(), pr_class_static_method_variant(), pr_const_type(), pr_function_parameter(), pr_function_type(), pr_method_type(), pr_offset_type(), pr_pointer_type(), pr_range_type(), pr_reference_type(), pr_set_type(), pr_start_function(), pr_struct_field(), pr_typdef(), pr_variable(), and pr_volatile_type().

00416 {
00417   char *u;
00418 
00419   assert (info->stack != NULL);
00420 
00421   u = strchr (info->stack->type, '|');
00422   if (u != NULL)
00423     {
00424       char *n;
00425 
00426       n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));
00427 
00428       memcpy (n, info->stack->type, u - info->stack->type);
00429       strcpy (n + (u - info->stack->type), s);
00430       strcat (n, u + 1);
00431 
00432       free (info->stack->type);
00433       info->stack->type = n;
00434 
00435       return true;
00436     }
00437 
00438   if (strchr (s, '|') != NULL
00439       && (strchr (info->stack->type, '{') != NULL
00440           || strchr (info->stack->type, '(') != NULL))
00441     {
00442       if (! prepend_type (info, "(")
00443           || ! append_type (info, ")"))
00444         return false;
00445     }
00446 
00447   if (*s == '\0')
00448     return true;
00449 
00450   return (append_type (info, " ")
00451           && append_type (info, s));
00452 }


Variable Documentation

bfd* abfd = 0 [static]
 

Definition at line 2539 of file pstack.c.

Referenced by ieee_finish_compilation_unit(), and load_bfd().

PTR dhandle = 0 [static]
 

Definition at line 2540 of file pstack.c.

Referenced by ieee_builtin_type(), ieee_read_cxx_class(), ieee_read_cxx_defaults(), parse_ieee_atn(), parse_ieee_ty(), and read_debugging_info().

debug_function_t** functions = 0 [static]
 

Definition at line 2545 of file pstack.c.

Referenced by _db_keyword_(), _db_pop_(), _db_push_(), DoTrace(), and PushState().

int functions_size = 0 [static]
 

Definition at line 2546 of file pstack.c.

const char* path_format = "stack-trace-on-segv-%d.txt" [static]
 

Definition at line 119 of file pstack.c.

Referenced by open_log_file(), and pstack_install_segv_action().

const struct debug_write_fns pr_fns [static]
 

Definition at line 282 of file pstack.c.

signal_regs_t* ptrace_regs = 0
 

Definition at line 2129 of file pstack.c.

pid_t segv_pid [static]
 

Definition at line 2549 of file pstack.c.

pthread_t segv_tid [static]
 

Definition at line 2548 of file pstack.c.

int sigreport = SIGUSR1 [static]
 

Definition at line 2547 of file pstack.c.

long sorted_symcount = 0 [static]
 

Definition at line 2544 of file pstack.c.

asymbol** sorted_syms = 0 [static]
 

Definition at line 2543 of file pstack.c.

long symcount = 0 [static]
 

Definition at line 2542 of file pstack.c.

Referenced by decode_symbol(), and find_debug_function_t().

asymbol** syms = 0 [static]
 

Definition at line 2541 of file pstack.c.

Referenced by decode_symbol(), and find_debug_function_t().


Generated on Wed Jul 20 21:10:10 2005 for MySQL 5.0.9 Beta by  doxygen 1.4.3