📄 stabsread.c
字号:
p++; /* Determine the type of name being defined. */ /* The Acorn RISC machine's compiler can put out locals that don't start with "234=" or "(3,4)=", so assume anything other than the deftypes we know how to handle is a local. */ if (!strchr ("cfFGpPrStTvVXCR", *p)) deftype = 'l'; else deftype = *p++; /* c is a special case, not followed by a type-number. SYMBOL:c=iVALUE for an integer constant symbol. SYMBOL:c=rVALUE for a floating constant symbol. SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol. e.g. "b:c=e6,0" for "const b = blob1" (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */ if (deftype == 'c') { if (*p++ != '=') error ("Invalid symbol data at symtab pos %d.", symnum); switch (*p++) { case 'r': { double d = atof (p); char *dbl_valu; SYMBOL_TYPE (sym) = lookup_fundamental_type (objfile, FT_DBL_PREC_FLOAT); dbl_valu = (char *) obstack_alloc (&objfile -> symbol_obstack, sizeof (double)); memcpy (dbl_valu, &d, sizeof (double)); SWAP_TARGET_AND_HOST (dbl_valu, sizeof (double)); SYMBOL_VALUE_BYTES (sym) = dbl_valu; SYMBOL_CLASS (sym) = LOC_CONST_BYTES; } break; case 'i': { SYMBOL_TYPE (sym) = lookup_fundamental_type (objfile, FT_INTEGER); SYMBOL_VALUE (sym) = atoi (p); SYMBOL_CLASS (sym) = LOC_CONST; } break; case 'e': /* SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol. e.g. "b:c=e6,0" for "const b = blob1" (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */ { int typenums[2]; read_type_number (&p, typenums); if (*p++ != ',') error ("Invalid symbol data: no comma in enum const symbol"); SYMBOL_TYPE (sym) = *dbx_lookup_type (typenums); SYMBOL_VALUE (sym) = atoi (p); SYMBOL_CLASS (sym) = LOC_CONST; } break; default: error ("Invalid symbol data at symtab pos %d.", symnum); } SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &file_symbols); return sym; } /* Now usually comes a number that says which data type, and possibly more stuff to define the type (all of which is handled by read_type) */ if (deftype == 'p' && *p == 'F') /* pF is a two-letter code that means a function parameter in Fortran. The type-number specifies the type of the return value. Translate it into a pointer-to-function type. */ { p++; SYMBOL_TYPE (sym) = lookup_pointer_type (lookup_function_type (read_type (&p, objfile))); } else { /* The symbol class letter is followed by a type (typically the type of the symbol, or its return-type, or etc). Read it. */ synonym = *p == 't'; if (synonym) { p += 1; type_synonym_name = obsavestring (SYMBOL_NAME (sym), strlen (SYMBOL_NAME (sym)), &objfile -> symbol_obstack); } /* Here we save the name of the symbol for read_range_type, which ends up reading in the basic types. In stabs, unfortunately there is no distinction between "int" and "long" types except their names. Until we work out a saner type policy (eliminating most builtin types and using the names specified in the files), we save away the name so that far away from here in read_range_type, we can examine it to decide between "int" and "long". FIXME. */ long_kludge_name = SYMBOL_NAME (sym); SYMBOL_TYPE (sym) = read_type (&p, objfile); } switch (deftype) { case 'C': /* The name of a caught exception. */ SYMBOL_CLASS (sym) = LOC_LABEL; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_VALUE_ADDRESS (sym) = valu; add_symbol_to_list (sym, &local_symbols); break; case 'f': /* A static function definition. */ SYMBOL_CLASS (sym) = LOC_BLOCK; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &file_symbols); /* fall into process_function_types. */ process_function_types: /* Function result types are described as the result type in stabs. We need to convert this to the function-returning-type-X type in GDB. E.g. "int" is converted to "function returning int". */ if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_FUNC) {#if 0 /* This code doesn't work -- it needs to realloc and can't. */ /* Attempt to set up to record a function prototype... */ struct type *new = alloc_type (objfile); /* Generate a template for the type of this function. The types of the arguments will be added as we read the symbol table. */ *new = *lookup_function_type (SYMBOL_TYPE(sym)); SYMBOL_TYPE(sym) = new; TYPE_OBJFILE (new) = objfile; in_function_type = new;#else SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));#endif } /* fall into process_prototype_types */ process_prototype_types: /* Sun acc puts declared types of arguments here. We don't care about their actual types (FIXME -- we should remember the whole function prototype), but the list may define some new types that we have to remember, so we must scan it now. */ while (*p == ';') { p++; read_type (&p, objfile); } break; case 'F': /* A global function definition. */ SYMBOL_CLASS (sym) = LOC_BLOCK; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &global_symbols); goto process_function_types; case 'G': /* For a class G (global) symbol, it appears that the value is not correct. It is necessary to search for the corresponding linker definition to find the value. These definitions appear at the end of the namelist. */ i = hashname (SYMBOL_NAME (sym)); SYMBOL_VALUE_CHAIN (sym) = global_sym_chain[i]; global_sym_chain[i] = sym; SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &global_symbols); break; /* This case is faked by a conditional above, when there is no code letter in the dbx data. Dbx data never actually contains 'l'. */ case 'l': SYMBOL_CLASS (sym) = LOC_LOCAL; SYMBOL_VALUE (sym) = valu; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &local_symbols); break; case 'p': /* Normally this is a parameter, a LOC_ARG. On the i960, it can also be a LOC_LOCAL_ARG depending on symbol type. */#ifndef DBX_PARM_SYMBOL_CLASS#define DBX_PARM_SYMBOL_CLASS(type) LOC_ARG#endif SYMBOL_CLASS (sym) = DBX_PARM_SYMBOL_CLASS (type); SYMBOL_VALUE (sym) = valu; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;#if 0 /* This doesn't work yet. */ add_param_to_type (&in_function_type, sym);#endif add_symbol_to_list (sym, &local_symbols); /* If it's gcc-compiled, if it says `short', believe it. */ if (processing_gcc_compilation || BELIEVE_PCC_PROMOTION) break;#if defined(BELIEVE_PCC_PROMOTION_TYPE) /* This macro is defined on machines (e.g. sparc) where we should believe the type of a PCC 'short' argument, but shouldn't believe the address (the address is the address of the corresponding int). Note that this is only different from the BELIEVE_PCC_PROMOTION case on big-endian machines. My guess is that this correction, as opposed to changing the parameter to an 'int' (as done below, for PCC on most machines), is the right thing to do on all machines, but I don't want to risk breaking something that already works. On most PCC machines, the sparc problem doesn't come up because the calling function has to zero the top bytes (not knowing whether the called function wants an int or a short), so there is no practical difference between an int and a short (except perhaps what happens when the GDB user types "print short_arg = 0x10000;"). Hacked for SunOS 4.1 by gnu@cygnus.com. In 4.1, the compiler actually produces the correct address (we don't need to fix it up). I made this code adapt so that it will offset the symbol if it was pointing at an int-aligned location and not otherwise. This way you can use the same gdb for 4.0.x and 4.1 systems. If the parameter is shorter than an int, and is integral (e.g. char, short, or unsigned equivalent), and is claimed to be passed on an integer boundary, don't believe it! Offset the parameter's address to the tail-end of that integer. */ temptype = lookup_fundamental_type (objfile, FT_INTEGER); if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype) && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype)) { SYMBOL_VALUE (sym) += TYPE_LENGTH (temptype) - TYPE_LENGTH (SYMBOL_TYPE (sym)); } break;#else /* no BELIEVE_PCC_PROMOTION_TYPE. */ /* If PCC says a parameter is a short or a char, it is really an int. */ temptype = lookup_fundamental_type (objfile, FT_INTEGER); if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype) && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT) { SYMBOL_TYPE (sym) = TYPE_UNSIGNED (SYMBOL_TYPE (sym)) ? lookup_fundamental_type (objfile, FT_UNSIGNED_INTEGER) : temptype; } break;#endif /* no BELIEVE_PCC_PROMOTION_TYPE. */ case 'P': /* acc seems to use P to delare the prototypes of functions that are referenced by this file. gdb is not prepared to deal with this extra information. FIXME, it ought to. */ if (type == N_FUN) goto process_prototype_types; /* Parameter which is in a register. */ SYMBOL_CLASS (sym) = LOC_REGPARM; SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); if (SYMBOL_VALUE (sym) >= NUM_REGS) { complain (®_value_complaint, SYMBOL_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &local_symbols); break; case 'R': case 'r': /* Register variable (either global or local). */ /* XXX */#ifdef sparc if (! processing_gcc_compilation) { struct symbol *s0; /* * If we see a parm decl immediately followed by a reg decl of * the same name (and in the same block), we change it to a * single instance of a reg parm. Sun's cc will generate these. */ if (local_symbols && (s0 = local_symbols->symbol[local_symbols->nsyms - 1]) && SYMBOL_CLASS(s0) == LOC_ARG && strcmp(SYMBOL_NAME(s0), SYMBOL_NAME(sym)) == 0) { SYMBOL_CLASS (s0) = LOC_REGPARM; SYMBOL_VALUE (s0) = STAB_REG_TO_REGNUM (valu); SYMBOL_NAMESPACE (s0) = VAR_NAMESPACE; return s0; } }#endif SYMBOL_CLASS (sym) = LOC_REGISTER; SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu); if (SYMBOL_VALUE (sym) >= NUM_REGS) { complain (®_value_complaint, SYMBOL_NAME (sym)); SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */ } SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; if (within_function) add_symbol_to_list (sym, &local_symbols); else add_symbol_to_list (sym, &file_symbols); break; case 'S': /* Static symbol at top level of file */ SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = valu; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &file_symbols); break; case 't': /* For a nameless type, we don't want a create a symbol, thus we did not use `sym'. Return without further processing. */ if (nameless) return NULL; SYMBOL_CLASS (sym) = LOC_TYPEDEF; SYMBOL_VALUE (sym) = valu; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; /* C++ vagaries: we may have a type which is derived from a base type which did not have its name defined when the derived class was output. We fill in the derived class's base part member's name here in that case. */ if (TYPE_NAME (SYMBOL_TYPE (sym)) != NULL) if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION) && TYPE_N_BASECLASSES (SYMBOL_TYPE (sym))) { int j; for (j = TYPE_N_BASECLASSES (SYMBOL_TYPE (sym)) - 1; j >= 0; j--) if (TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), j) == 0) TYPE_BASECLASS_NAME (SYMBOL_TYPE (sym), j) = type_name_no_tag (TYPE_BASECLASS (SYMBOL_TYPE (sym), j)); } add_symbol_to_list (sym, &file_symbols); break; case 'T': /* For a nameless type, we don't want a create a symbol, thus we did not use `sym'. Return without further processing. */ if (nameless) return NULL; SYMBOL_CLASS (sym) = LOC_TYPEDEF; SYMBOL_VALUE (sym) = valu; SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) TYPE_NAME (SYMBOL_TYPE (sym)) = obconcat (&objfile -> type_obstack, "", (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM ? "enum " : (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT ? "struct " : "union ")), SYMBOL_NAME (sym)); add_symbol_to_list (sym, &file_symbols); if (synonym) { register struct symbol *typedef_sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol)); memset (typedef_sym, 0, sizeof (struct symbol)); SYMBOL_NAME (typedef_sym) = SYMBOL_NAME (sym); SYMBOL_TYPE (typedef_sym) = SYMBOL_TYPE (sym); SYMBOL_CLASS (typedef_sym) = LOC_TYPEDEF; SYMBOL_VALUE (typedef_sym) = valu; SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE; add_symbol_to_list (typedef_sym, &file_symbols); } break; case 'V': /* Static symbol of local scope */ SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = valu; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &local_symbols); break; case 'v': /* Reference parameter */ SYMBOL_CLASS (sym) = LOC_REF_ARG; SYMBOL_VALUE (sym) = valu; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &local_symbols); 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. */ SYMBOL_CLASS (sym) = LOC_LOCAL; SYMBOL_VALUE (sym) = valu; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; add_symbol_to_list (sym, &local_symbols); break; default: error ("Invalid symbol data: unknown symbol-type code `%c' at symtab pos %d.", deftype, symnum); } return sym;}/* Skip rest of this symbol and return an error type. General notes on error recovery: error_type always skips to the end of the symbol (modulo cretinous dbx symbol name continuation). Thus code like this: if (*(*pp)++ != ';') return error_type (pp); is wrong because if *pp starts out pointing at '\0' (typically as the result of an earlier error), it will be incremented to point to the start of the next symbol, which might produce strange results, at least if you run off the end of the string table. Instead use if (**pp != ';') return error_type (pp); ++*pp; or
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -