#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_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 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_t * | ptrace_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 |
|
|
|
|
|
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||
|
Definition at line 98 of file pstack.c. References write(). Referenced by my_crawl().
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
|
|
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||||||||||||||||||||||
|
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( |