stabs.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,559 行 · 第 1/5 页
C
2,559 行
if (dtype == DEBUG_TYPE_NULL) return false; if (slot != NULL) *slot = dtype; break; case 'T': /* Struct, union, or enum tag. For GNU C++, this can be be followed by 't' which means we are typedef'ing it as well. */ if (*p != 't') { synonym = false; /* FIXME: gdb sets synonym to true if the current language is C++. */ } else { synonym = true; ++p; } dtype = parse_stab_type (dhandle, info, name, &p, &slot); if (dtype == DEBUG_TYPE_NULL) return false; if (name == NULL) return true; /* INFO->SELF_CROSSREF is set by parse_stab_type if this type is a cross reference to itself. These are generated by some versions of g++. */ self_crossref = info->self_crossref; dtype = debug_tag_type (dhandle, name, dtype); if (dtype == DEBUG_TYPE_NULL) return false; if (slot != NULL) *slot = dtype; /* See if we have a cross reference to this tag which we can now fill in. Avoid filling in a cross reference to ourselves, because that would lead to circular debugging information. */ if (! self_crossref) { register struct stab_tag **pst; for (pst = &info->tags; *pst != NULL; pst = &(*pst)->next) { if ((*pst)->name[0] == name[0] && strcmp ((*pst)->name, name) == 0) { (*pst)->slot = dtype; *pst = (*pst)->next; break; } } } if (synonym) { dtype = debug_name_type (dhandle, name, dtype); if (dtype == DEBUG_TYPE_NULL) return false; if (slot != NULL) *slot = dtype; } break; case 'V': /* Static symbol of local scope */ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, (debug_type **) NULL); if (dtype == DEBUG_TYPE_NULL) return false; /* FIXME: gdb checks os9k_stabs here. */ if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL_STATIC, value)) return false; break; case 'v': /* Reference parameter. */ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, (debug_type **) NULL); if (dtype == DEBUG_TYPE_NULL) return false; if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE, value)) return false; break; case 'a': /* Reference parameter which is in a register. */ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, (debug_type **) NULL); if (dtype == DEBUG_TYPE_NULL) return false; if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG, value)) return false; break; case 'X': /* This is used by Sun FORTRAN for "function result value". Sun claims ("dbx and dbxtool interfaces", 2nd ed) that Pascal uses it too, but when I tried it Pascal used "x:3" (local symbol) instead. */ dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, (debug_type **) NULL); if (dtype == DEBUG_TYPE_NULL) return false; if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL, value)) return false; break; default: bad_stab (string); return false; } /* FIXME: gdb converts structure values to structure pointers in a couple of cases, depending upon the target. */ return true;}/* Parse a stabs type. The typename argument is non-NULL if this is a typedef or a tag definition. The pp argument points to the stab string, and is updated. The slotp argument points to a place to store the slot used if the type is being defined. */static debug_typeparse_stab_type (dhandle, info, typename, pp, slotp) PTR dhandle; struct stab_handle *info; const char *typename; const char **pp; debug_type **slotp;{ const char *orig; int typenums[2]; int size; boolean stringp; int descriptor; debug_type dtype; if (slotp != NULL) *slotp = NULL; orig = *pp; size = -1; stringp = false; info->self_crossref = false; /* Read type number if present. The type number may be omitted. for instance in a two-dimensional array declared with type "ar1;1;10;ar1;1;10;4". */ if (! isdigit ((unsigned char) **pp) && **pp != '(' && **pp != '-') { /* 'typenums=' not present, type is anonymous. Read and return the definition, but don't put it in the type vector. */ typenums[0] = typenums[1] = -1; } else { if (! parse_stab_type_number (pp, typenums)) return DEBUG_TYPE_NULL; if (**pp != '=') { /* Type is not being defined here. Either it already exists, or this is a forward reference to it. */ return stab_find_type (dhandle, info, typenums); } /* Only set the slot if the type is being defined. This means that the mapping from type numbers to types will only record the name of the typedef which defines a type. If we don't do this, then something like typedef int foo; int i; will record that i is of type foo. Unfortunately, stabs information is ambiguous about variable types. For this code, typedef int foo; int i; foo j; the stabs information records both i and j as having the same type. This could be fixed by patching the compiler. */ if (slotp != NULL && typenums[0] >= 0 && typenums[1] >= 0) *slotp = stab_find_slot (info, typenums); /* Type is being defined here. */ /* Skip the '='. */ ++*pp; while (**pp == '@') { const char *p = *pp + 1; const char *attr; if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-') { /* Member type. */ break; } /* Type attributes. */ attr = p; for (; *p != ';'; ++p) { if (*p == '\0') { bad_stab (orig); return DEBUG_TYPE_NULL; } } *pp = p + 1; switch (*attr) { case 's': size = atoi (attr + 1); size /= 8; /* Size is in bits. We store it in bytes. */ if (size <= 0) size = -1; break; case 'S': stringp = true; break; default: /* Ignore unrecognized type attributes, so future compilers can invent new ones. */ break; } } } descriptor = **pp; ++*pp; switch (descriptor) { case 'x': { enum debug_type_kind code; const char *q1, *q2, *p; /* A cross reference to another type. */ switch (**pp) { case 's': code = DEBUG_KIND_STRUCT; break; case 'u': code = DEBUG_KIND_UNION; break; case 'e': code = DEBUG_KIND_ENUM; break; default: /* Complain and keep going, so compilers can invent new cross-reference types. */ warn_stab (orig, _("unrecognized cross reference type")); code = DEBUG_KIND_STRUCT; break; } ++*pp; q1 = strchr (*pp, '<'); p = strchr (*pp, ':'); if (p == NULL) { bad_stab (orig); return DEBUG_TYPE_NULL; } if (q1 != NULL && p > q1 && p[1] == ':') { int nest = 0; for (q2 = q1; *q2 != '\0'; ++q2) { if (*q2 == '<') ++nest; else if (*q2 == '>') --nest; else if (*q2 == ':' && nest == 0) break; } p = q2; if (*p != ':') { bad_stab (orig); return DEBUG_TYPE_NULL; } } /* Some versions of g++ can emit stabs like fleep:T20=xsfleep: which define structures in terms of themselves. We need to tell the caller to avoid building a circular structure. */ if (typename != NULL && strncmp (typename, *pp, p - *pp) == 0 && typename[p - *pp] == '\0') info->self_crossref = true; dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code); *pp = p + 1; } break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '(': { const char *hold; int xtypenums[2]; /* This type is defined as another type. */ (*pp)--; hold = *pp; /* Peek ahead at the number to detect void. */ if (! parse_stab_type_number (pp, xtypenums)) return DEBUG_TYPE_NULL; if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1]) { /* This type is being defined as itself, which means that it is void. */ dtype = debug_make_void_type (dhandle); } else { *pp = hold; /* Go back to the number and have parse_stab_type get it. This means that we can deal with something like t(1,2)=(3,4)=... which the Lucid compiler uses. */ dtype = parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL); if (dtype == DEBUG_TYPE_NULL) return DEBUG_TYPE_NULL; } if (typenums[0] != -1) { if (! stab_record_type (dhandle, info, typenums, dtype)) return DEBUG_TYPE_NULL; } break; } case '*': dtype = debug_make_pointer_type (dhandle, parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL)); break; case '&': /* Reference to another type. */ dtype = (debug_make_reference_type (dhandle, parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL))); break; case 'f': /* Function returning another type. */ /* FIXME: gdb checks os9k_stabs here. */ dtype = (debug_make_function_type (dhandle, parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL), (debug_type *) NULL, false)); break; case 'k': /* Const qualifier on some type (Sun). */ /* FIXME: gdb accepts 'c' here if os9k_stabs. */ dtype = debug_make_const_type (dhandle, parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL)); break; case 'B': /* Volatile qual on some type (Sun). */ /* FIXME: gdb accepts 'i' here if os9k_stabs. */ dtype = (debug_make_volatile_type (dhandle, parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL))); break; case '@': /* Offset (class & variable) type. This is used for a pointer relative to an object. */ { debug_type domain; debug_type memtype; /* Member type. */ domain = parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL); if (domain == DEBUG_TYPE_NULL) return DEBUG_TYPE_NULL; if (**pp != ',') { bad_stab (orig); return DEBUG_TYPE_NULL; } ++*pp; memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL); if (memtype == DEBUG_TYPE_NULL) return DEBUG_TYPE_NULL; dtype = debug_make_offset_type (dhandle, domain, memtype); } break; case '#': /* Method (class & fn) type. */ if (**pp == '#') { debug_type return_type; ++*pp; return_type = parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL); if (return_type == DEBUG_TYPE_NULL) return DEBUG_TYPE_NULL; if (**pp != ';') { bad_stab (orig); return DEBUG_TYPE_NULL; } ++*pp; dtype = debug_make_method_type (dhandle, return_type, DEBUG_TYPE_NULL, (debug_type *) NULL, false); } else { debug_type domain; debug_type return_type; debug_type *args; unsigned int n; unsigned int alloc; boolean varargs; domain = parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL); if (domain == DEBUG_TYPE_NULL) return DEBUG_TYPE_NULL; if (**pp != ',') { bad_stab (orig); return DEBUG_TYPE_NULL; } ++*pp; return_type = parse_stab_type (dhandle, info, (const char *) NULL, pp, (debug_type **) NULL); if (return_type == DEBUG_TYPE_NULL) return DEBUG_TYPE_NULL; alloc = 10; args = (debug_type *) xmalloc (alloc * sizeof *args); n = 0; while (**pp != ';') { if (**pp != ',') { bad_stab (orig); return DEBUG_TYPE_NULL; } ++*pp; if (n + 1 >= alloc) { alloc += 10; args = ((debug_type *)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?