wrstabs.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,416 行 · 第 1/4 页
C
2,416 行
if (contextp) { sprintf (info->type_stack->methods + strlen (info->type_stack->methods), "%ld;%s;", (long) voffset, context); free (context); } if (definition) info->type_stack->definition = true; return true;}/* Add a variant to the current method. */static booleanstab_class_method_variant (p, physname, visibility, constp, volatilep, voffset, contextp) PTR p; const char *physname; enum debug_visibility visibility; boolean constp; boolean volatilep; bfd_vma voffset; boolean contextp;{ struct stab_write_handle *info = (struct stab_write_handle *) p; return stab_class_method_var (info, physname, visibility, false, constp, volatilep, voffset, contextp);}/* Add a static variant to the current method. */static booleanstab_class_static_method_variant (p, physname, visibility, constp, volatilep) PTR p; const char *physname; enum debug_visibility visibility; boolean constp; boolean volatilep;{ struct stab_write_handle *info = (struct stab_write_handle *) p; return stab_class_method_var (info, physname, visibility, true, constp, volatilep, 0, false);}/* Finish up a method. */static booleanstab_class_end_method (p) PTR p;{ struct stab_write_handle *info = (struct stab_write_handle *) p; assert (info->type_stack != NULL && info->type_stack->methods != NULL); /* We allocated enough room on info->type_stack->methods to add the trailing semicolon. */ strcat (info->type_stack->methods, ";"); return true;}/* Finish up a class. */static booleanstab_end_class_type (p) PTR p;{ struct stab_write_handle *info = (struct stab_write_handle *) p; size_t len; unsigned int i = 0; char *buf; assert (info->type_stack != NULL && info->type_stack->fields != NULL); /* Work out the size we need to allocate for the class definition. */ len = (strlen (info->type_stack->string) + strlen (info->type_stack->fields) + 10); if (info->type_stack->baseclasses != NULL) { len += 20; for (i = 0; info->type_stack->baseclasses[i] != NULL; i++) len += strlen (info->type_stack->baseclasses[i]); } if (info->type_stack->methods != NULL) len += strlen (info->type_stack->methods); if (info->type_stack->vtable != NULL) len += strlen (info->type_stack->vtable); /* Build the class definition. */ buf = (char *) xmalloc (len); strcpy (buf, info->type_stack->string); if (info->type_stack->baseclasses != NULL) { sprintf (buf + strlen (buf), "!%u,", i); for (i = 0; info->type_stack->baseclasses[i] != NULL; i++) { strcat (buf, info->type_stack->baseclasses[i]); free (info->type_stack->baseclasses[i]); } free (info->type_stack->baseclasses); info->type_stack->baseclasses = NULL; } strcat (buf, info->type_stack->fields); free (info->type_stack->fields); info->type_stack->fields = NULL; if (info->type_stack->methods != NULL) { strcat (buf, info->type_stack->methods); free (info->type_stack->methods); info->type_stack->methods = NULL; } strcat (buf, ";"); if (info->type_stack->vtable != NULL) { strcat (buf, info->type_stack->vtable); free (info->type_stack->vtable); info->type_stack->vtable = NULL; } /* Replace the string on the top of the stack with the complete class definition. */ free (info->type_stack->string); info->type_stack->string = buf; return true;}/* Push a typedef which was previously defined. */static booleanstab_typedef_type (p, name) PTR p; const char *name;{ struct stab_write_handle *info = (struct stab_write_handle *) p; struct string_hash_entry *h; h = string_hash_lookup (&info->typedef_hash, name, false, false); assert (h != NULL && h->index > 0); return stab_push_defined_type (info, h->index, h->size);}/* Push a struct, union or class tag. */static booleanstab_tag_type (p, name, id, kind) PTR p; const char *name; unsigned int id; enum debug_type_kind kind;{ struct stab_write_handle *info = (struct stab_write_handle *) p; long index; unsigned int size; index = stab_get_struct_index (info, name, id, kind, &size); if (index < 0) return false; return stab_push_defined_type (info, index, size);}/* Define a typedef. */static booleanstab_typdef (p, name) PTR p; const char *name;{ struct stab_write_handle *info = (struct stab_write_handle *) p; long index; unsigned int size; char *s, *buf; struct string_hash_entry *h; index = info->type_stack->index; size = info->type_stack->size; s = stab_pop_type (info); buf = (char *) xmalloc (strlen (name) + strlen (s) + 20); if (index > 0) sprintf (buf, "%s:t%s", name, s); else { index = info->type_index; ++info->type_index; sprintf (buf, "%s:t%ld=%s", name, index, s); } free (s); if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) return false; free (buf); h = string_hash_lookup (&info->typedef_hash, name, true, false); if (h == NULL) { non_fatal (_("string_hash_lookup failed: %s"), bfd_errmsg (bfd_get_error ())); return false; } /* I don't think we care about redefinitions. */ h->index = index; h->size = size; return true;}/* Define a tag. */static booleanstab_tag (p, tag) PTR p; const char *tag;{ struct stab_write_handle *info = (struct stab_write_handle *) p; char *s, *buf; s = stab_pop_type (info); buf = (char *) xmalloc (strlen (tag) + strlen (s) + 3); sprintf (buf, "%s:T%s", tag, s); free (s); if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) return false; free (buf); return true;}/* Define an integer constant. */static booleanstab_int_constant (p, name, val) PTR p; const char *name; bfd_vma val;{ struct stab_write_handle *info = (struct stab_write_handle *) p; char *buf; buf = (char *) xmalloc (strlen (name) + 20); sprintf (buf, "%s:c=i%ld", name, (long) val); if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) return false; free (buf); return true;}/* Define a floating point constant. */static booleanstab_float_constant (p, name, val) PTR p; const char *name; double val;{ struct stab_write_handle *info = (struct stab_write_handle *) p; char *buf; buf = (char *) xmalloc (strlen (name) + 20); sprintf (buf, "%s:c=f%g", name, val); if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) return false; free (buf); return true;}/* Define a typed constant. */static booleanstab_typed_constant (p, name, val) PTR p; const char *name; bfd_vma val;{ struct stab_write_handle *info = (struct stab_write_handle *) p; char *s, *buf; s = stab_pop_type (info); buf = (char *) xmalloc (strlen (name) + strlen (s) + 20); sprintf (buf, "%s:c=e%s,%ld", name, s, (long) val); free (s); if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) return false; free (buf); return true;}/* Record a variable. */static booleanstab_variable (p, name, kind, val) PTR p; const char *name; enum debug_var_kind kind; bfd_vma val;{ struct stab_write_handle *info = (struct stab_write_handle *) p; char *s, *buf; int stab_type; const char *kindstr; s = stab_pop_type (info); switch (kind) { default: abort (); case DEBUG_GLOBAL: stab_type = N_GSYM; kindstr = "G"; break; case DEBUG_STATIC: stab_type = N_STSYM; kindstr = "S"; break; case DEBUG_LOCAL_STATIC: stab_type = N_STSYM; kindstr = "V"; break; case DEBUG_LOCAL: stab_type = N_LSYM; kindstr = ""; /* Make sure that this is a type reference or definition. */ if (! isdigit ((unsigned char) *s)) { char *n; long index; index = info->type_index; ++info->type_index; n = (char *) xmalloc (strlen (s) + 20); sprintf (n, "%ld=%s", index, s); free (s); s = n; } break; case DEBUG_REGISTER: stab_type = N_RSYM; kindstr = "r"; break; } buf = (char *) xmalloc (strlen (name) + strlen (s) + 3); sprintf (buf, "%s:%s%s", name, kindstr, s); free (s); if (! stab_write_symbol (info, stab_type, 0, val, buf)) return false; free (buf); return true;}/* Start outputting a function. */static booleanstab_start_function (p, name, globalp) PTR p; const char *name; boolean globalp;{ struct stab_write_handle *info = (struct stab_write_handle *) p; char *rettype, *buf; assert (info->nesting == 0 && info->fun_offset == -1); rettype = stab_pop_type (info); buf = (char *) xmalloc (strlen (name) + strlen (rettype) + 3); sprintf (buf, "%s:%c%s", name, globalp ? 'F' : 'f', rettype); /* We don't know the value now, so we set it in start_block. */ info->fun_offset = info->symbols_size; if (! stab_write_symbol (info, N_FUN, 0, 0, buf)) return false; free (buf); return true;}/* Output a function parameter. */static booleanstab_function_parameter (p, name, kind, val) PTR p; const char *name; enum debug_parm_kind kind; bfd_vma val;{ struct stab_write_handle *info = (struct stab_write_handle *) p; char *s, *buf; int stab_type; char kindc; s = stab_pop_type (info); switch (kind) { default: abort (); case DEBUG_PARM_STACK: stab_type = N_PSYM; kindc = 'p'; break; case DEBUG_PARM_REG: stab_type = N_RSYM; kindc = 'P'; break; case DEBUG_PARM_REFERENCE: stab_type = N_PSYM; kindc = 'v'; break; case DEBUG_PARM_REF_REG: stab_type = N_RSYM; kindc = 'a'; break; } buf = (char *) xmalloc (strlen (name) + strlen (s) + 3); sprintf (buf, "%s:%c%s", name, kindc, s); free (s); if (! stab_write_symbol (info, stab_type, 0, val, buf)) return false; free (buf); return true;}/* Start a block. */static booleanstab_start_block (p, addr) PTR p; bfd_vma addr;{ struct stab_write_handle *info = (struct stab_write_handle *) p; /* Fill in any slots which have been waiting for the first known text address. */ if (info->so_offset != -1) { bfd_put_32 (info->abfd, addr, info->symbols + info->so_offset + 8); info->so_offset = -1; } if (info->fun_offset != -1) { bfd_put_32 (info->abfd, addr, info->symbols + info->fun_offset + 8); info->fun_offset = -1; } ++info->nesting; /* We will be called with a top level block surrounding the function, but stabs information does not output that block, so we ignore it. */ if (info->nesting == 1) { info->fnaddr = addr; return true; } /* We have to output the LBRAC symbol after any variables which are declared inside the block. We postpone the LBRAC until the next start_block or end_block. */ /* If we have postponed an LBRAC, output it now. */ if (info->pending_lbrac != (bfd_vma) -1) { if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac, (const char *) NULL)) return false; } /* Remember the address and output it later. */ info->pending_lbrac = addr - info->fnaddr; return true;}/* End a block. */static booleanstab_end_block (p, addr) PTR p; bfd_vma addr;{ struct stab_write_handle *info = (struct stab_write_handle *) p; if (addr > info->last_text_address) info->last_text_address = addr; /* If we have postponed an LBRAC, output it now. */ if (info->pending_lbrac != (bfd_vma) -1) { if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac, (const char *) NULL)) return false; info->pending_lbrac = (bfd_vma) -1; } assert (info->nesting > 0); --info->nesting; /* We ignore the outermost block. */ if (info->nesting == 0) return true; return stab_write_symbol (info, N_RBRAC, 0, addr - info->fnaddr, (const char *) NULL);}/* End a function. *//*ARGSUSED*/static booleanstab_end_function (p) PTR p ATTRIBUTE_UNUSED;{ return true;}/* Output a line number. */static booleanstab_lineno (p, file, lineno, addr) PTR p; const char *file; unsigned long lineno; bfd_vma addr;{ struct stab_write_handle *info = (struct stab_write_handle *) p; assert (info->lineno_filename != NULL); if (addr > info->last_text_address) info->last_text_address = addr; if (strcmp (file, info->lineno_filename) != 0) { if (! stab_write_symbol (info, N_SOL, 0, addr, file)) return false; info->lineno_filename = file; } return stab_write_symbol (info, N_SLINE, lineno, addr - info->fnaddr, (const char *) NULL);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?