📄 coffread.c
字号:
/* If no string table is needed, then the file may end immediately after the symbols. Just return with `stringtab' set to null. */ if (val != sizeof length || length < sizeof length) return 0; stringtab = (char *) xmalloc (length); if (stringtab == NULL) return -1; memcpy (stringtab, &length, sizeof length); if (length == sizeof length) /* Empty table -- just the count */ return 0; val = myread (chan, stringtab + sizeof length, length - sizeof length); if (val != length - sizeof length || stringtab[length - 1] != '\0') return -1; return 0;}static voidfree_stringtab (){ if (stringtab) free (stringtab); stringtab = NULL;}static char *getsymname (symbol_entry) struct internal_syment *symbol_entry;{ static char buffer[SYMNMLEN+1]; char *result; if (symbol_entry->_n._n_n._n_zeroes == 0) { result = stringtab + symbol_entry->_n._n_n._n_offset; } else { strncpy (buffer, symbol_entry->_n._n_name, SYMNMLEN); buffer[SYMNMLEN] = '\0'; result = buffer; } return result;}static char *getfilename (aux_entry) union internal_auxent *aux_entry;{ static char buffer[BUFSIZ]; register char *temp; char *result;#ifndef COFF_NO_LONG_FILE_NAMES#if defined (x_zeroes) /* Data General. */ if (aux_entry->x_zeroes == 0) strcpy (buffer, stringtab + aux_entry->x_offset);#else /* no x_zeroes */ if (aux_entry->x_file.x_n.x_zeroes == 0) strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset);#endif /* no x_zeroes */ else#endif /* COFF_NO_LONG_FILE_NAMES */ {#if defined (x_name) /* Data General. */ strncpy (buffer, aux_entry->x_name, FILNMLEN);#else strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);#endif buffer[FILNMLEN] = '\0'; } result = buffer; if ((temp = strrchr (result, '/')) != NULL) result = temp + 1; return (result);}/* Support for line number handling */static char *linetab = NULL;static long linetab_offset;static unsigned long linetab_size;/* Read in all the line numbers for fast lookups later. Leave them in external (unswapped) format in memory; we'll swap them as we enter them into GDB's data structures. */ static intinit_lineno (chan, offset, size) int chan; long offset; int size;{ int val; linetab_offset = offset; linetab_size = size; if (size == 0) return 0; if (lseek (chan, offset, 0) < 0) return -1; /* Allocate the desired table, plus a sentinel */ linetab = (char *) xmalloc (size + local_linesz); val = myread (chan, linetab, size); if (val != size) return -1; /* Terminate it with an all-zero sentinel record */ memset (linetab + size, 0, local_linesz); make_cleanup (free, linetab); /* Be sure it gets de-allocated. */ return 0;}#if !defined (L_LNNO32)#define L_LNNO32(lp) ((lp)->l_lnno)#endifstatic voidenter_linenos (file_offset, first_line, last_line) long file_offset; register int first_line; register int last_line;{ register char *rawptr; struct internal_lineno lptr; if (file_offset < linetab_offset) { complain (&lineno_complaint, (char *) file_offset); if (file_offset > linetab_size) /* Too big to be an offset? */ return; file_offset += linetab_offset; /* Try reading at that linetab offset */ } rawptr = &linetab[file_offset - linetab_offset]; /* skip first line entry for each function */ rawptr += local_linesz; /* line numbers start at one for the first line of the function */ first_line--; for (;;) { bfd_coff_swap_lineno_in (symfile_bfd, rawptr, &lptr); rawptr += local_linesz; /* The next function, or the sentinel, will have L_LNNO32 zero; we exit. */ if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line) coff_record_line (first_line + L_LNNO32 (&lptr), lptr.l_addr.l_paddr); else break; } }static voidpatch_type (type, real_type) struct type *type; struct type *real_type;{ register struct type *target = TYPE_TARGET_TYPE (type); register struct type *real_target = TYPE_TARGET_TYPE (real_type); int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field); TYPE_LENGTH (target) = TYPE_LENGTH (real_target); TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target); TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target, field_size); memcpy (TYPE_FIELDS (target), TYPE_FIELDS (real_target), field_size); if (TYPE_NAME (real_target)) { if (TYPE_NAME (target)) free (TYPE_NAME (target)); TYPE_NAME (target) = concat (TYPE_NAME (real_target), NULL); }}/* Patch up all appropriate typedef symbols in the opaque_type_chains so that they can be used to print out opaque data structures properly. */static voidpatch_opaque_types (s) struct symtab *s;{ register struct block *b; register int i; register struct symbol *real_sym; /* Go through the per-file symbols only */ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--) { /* Find completed typedefs to use to fix opaque ones. Remove syms from the chain when their types are stored, but search the whole chain, as there may be several syms from different files with the same name. */ real_sym = BLOCK_SYM (b, i); if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF && SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE && TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0) { register char *name = SYMBOL_NAME (real_sym); register int hash = hashname (name); register struct symbol *sym, *prev; prev = 0; for (sym = opaque_type_chain[hash]; sym;) { if (name[0] == SYMBOL_NAME (sym)[0] && !strcmp (name + 1, SYMBOL_NAME (sym) + 1)) { if (prev) { SYMBOL_VALUE_CHAIN (prev) = SYMBOL_VALUE_CHAIN (sym); } else { opaque_type_chain[hash] = SYMBOL_VALUE_CHAIN (sym); } patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym)); if (prev) { sym = SYMBOL_VALUE_CHAIN (prev); } else { sym = opaque_type_chain[hash]; } } else { prev = sym; sym = SYMBOL_VALUE_CHAIN (sym); } } } }}static struct symbol *process_coff_symbol (cs, aux, objfile) register struct coff_symbol *cs; register union internal_auxent *aux; struct objfile *objfile;{ register struct symbol *sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); char *name;#ifdef NAMES_HAVE_UNDERSCORE int offset = 1;#else int offset = 0;#endif struct type *temptype; memset (sym, 0, sizeof (struct symbol)); name = cs->c_name; name = (name[0] == '_' ? name + offset : name); SYMBOL_NAME (sym) = obstack_copy0 (&objfile->symbol_obstack, name, strlen (name)); /* default assumptions */ SYMBOL_VALUE (sym) = cs->c_value; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; if (ISFCN (cs->c_type)) {#if 0 /* FIXME: This has NOT been tested. The DBX version has.. */ /* Generate a template for the type of this function. The types of the arguments will be added as we read the symbol table. */ struct type *new = (struct type *) obstack_alloc (&objfile->symbol_obstack, sizeof (struct type)); memcpy (new, lookup_function_type (decode_function_type (cs, cs->c_type, aux)), sizeof(struct type)); SYMBOL_TYPE (sym) = new; in_function_type = SYMBOL_TYPE(sym);#else SYMBOL_TYPE(sym) = lookup_function_type (decode_function_type (cs, cs->c_type, aux));#endif SYMBOL_CLASS (sym) = LOC_BLOCK; if (cs->c_sclass == C_STAT) coff_add_symbol_to_list (sym, &coff_file_symbols); else if (cs->c_sclass == C_EXT) coff_add_symbol_to_list (sym, &coff_global_symbols); } else { SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux); switch (cs->c_sclass) { case C_NULL: break; case C_AUTO: SYMBOL_CLASS (sym) = LOC_LOCAL; coff_add_symbol_to_list (sym, &coff_local_symbols); break; case C_EXT: SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value; coff_add_symbol_to_list (sym, &coff_global_symbols); break; case C_STAT: SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value; if (within_function) { /* Static symbol of local scope */ coff_add_symbol_to_list (sym, &coff_local_symbols); } else { /* Static symbol at top level of file */ coff_add_symbol_to_list (sym, &coff_file_symbols); } break;#ifdef C_GLBLREG /* AMD coff */ case C_GLBLREG:#endif case C_REG: SYMBOL_CLASS (sym) = LOC_REGISTER; SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM(cs->c_value); coff_add_symbol_to_list (sym, &coff_local_symbols); break; case C_LABEL: break; case C_ARG: SYMBOL_CLASS (sym) = LOC_ARG;#if 0 /* FIXME: This has not been tested. */ /* Add parameter to function. */ add_param_to_type(&in_function_type,sym);#endif coff_add_symbol_to_list (sym, &coff_local_symbols);#if !defined (BELIEVE_PCC_PROMOTION) /* If PCC says a parameter is a short or a char, it is really an int. */ temptype = lookup_fundamental_type (current_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 (current_objfile, FT_UNSIGNED_INTEGER) : temptype; }#endif break; case C_REGPARM: SYMBOL_CLASS (sym) = LOC_REGPARM; SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM(cs->c_value); coff_add_symbol_to_list (sym, &coff_local_symbols);#if !defined (BELIEVE_PCC_PROMOTION) /* If PCC says a parameter is a short or a char, it is really an int. */ temptype = lookup_fundamental_type (current_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 (current_objfile, FT_UNSIGNED_INTEGER) : temptype; }#endif break; case C_TPDEF: SYMBOL_CLASS (sym) = LOC_TYPEDEF; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; /* If type has no name, give it one */ if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) TYPE_NAME (SYMBOL_TYPE (sym)) = concat (SYMBOL_NAME (sym), NULL); /* Keep track of any type which points to empty structured type, so it can be filled from a definition from another file. A simple forward reference (TYPE_CODE_UNDEF) is not an empty structured type, though; the forward references work themselves out via the magic of coff_lookup_type. */ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 && TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) != TYPE_CODE_UNDEF) { register int i = hashname (SYMBOL_NAME (sym)); SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i]; opaque_type_chain[i] = sym; } coff_add_symbol_to_list (sym, &coff_file_symbols); break; case C_STRTAG: case C_UNTAG: case C_ENTAG: SYMBOL_CLASS (sym) = LOC_TYPEDEF; SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) TYPE_NAME (SYMBOL_TYPE (sym)) = concat ("", (cs->c_sclass == C_ENTAG ? "enum " : (cs->c_sclass == C_STRTAG ? "struct " : "union ")), SYMBOL_NAME (sym), NULL); coff_add_symbol_to_list (sym, &coff_file_symbols); break; default: break; } } return sym;}/* Decode a coff type specifier; return the type that is meant. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -