rdcoff.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 908 行 · 第 1/2 页
C
908 行
bitpos = bfd_asymbol_value (sym); bitsize = auxent.x_sym.x_misc.x_lnsz.x_size; break; case C_EOS: done = true; break; } if (! done) { debug_type ftype; debug_field f; ftype = parse_coff_type (abfd, symbols, types, this_coff_symno, syment.n_type, psubaux, true, dhandle); f = debug_make_field (dhandle, bfd_asymbol_name (sym), ftype, bitpos, bitsize, DEBUG_VISIBILITY_PUBLIC); if (f == DEBUG_FIELD_NULL) return DEBUG_TYPE_NULL; if (count + 1 >= alloc) { alloc += 10; fields = ((debug_field *) xrealloc (fields, alloc * sizeof *fields)); } fields[count] = f; ++count; } } fields[count] = DEBUG_FIELD_NULL; return debug_make_struct_type (dhandle, ntype == T_STRUCT, pauxent->x_sym.x_misc.x_lnsz.x_size, fields);}/* Parse an enum type. */static debug_typeparse_coff_enum_type (abfd, symbols, types, pauxent, dhandle) bfd *abfd; struct coff_symbols *symbols; struct coff_types *types ATTRIBUTE_UNUSED; union internal_auxent *pauxent; PTR dhandle;{ long symend; int alloc; const char **names; bfd_signed_vma *vals; int count; boolean done; symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l; alloc = 10; names = (const char **) xmalloc (alloc * sizeof *names); vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *vals); count = 0; done = false; while (! done && symbols->coff_symno < symend && symbols->symno < symbols->symcount) { asymbol *sym; struct internal_syment syment; sym = symbols->syms[symbols->symno]; if (! bfd_coff_get_syment (abfd, sym, &syment)) { non_fatal (_("bfd_coff_get_syment failed: %s"), bfd_errmsg (bfd_get_error ())); return DEBUG_TYPE_NULL; } ++symbols->symno; symbols->coff_symno += 1 + syment.n_numaux; switch (syment.n_sclass) { case C_MOE: if (count + 1 >= alloc) { alloc += 10; names = ((const char **) xrealloc (names, alloc * sizeof *names)); vals = ((bfd_signed_vma *) xrealloc (vals, alloc * sizeof *vals)); } names[count] = bfd_asymbol_name (sym); vals[count] = bfd_asymbol_value (sym); ++count; break; case C_EOS: done = true; break; } } names[count] = NULL; return debug_make_enum_type (dhandle, names, vals);}/* Handle a single COFF symbol. */static booleanparse_coff_symbol (abfd, types, sym, coff_symno, psyment, dhandle, type, within_function) bfd *abfd ATTRIBUTE_UNUSED; struct coff_types *types; asymbol *sym; long coff_symno; struct internal_syment *psyment; PTR dhandle; debug_type type; boolean within_function;{ switch (psyment->n_sclass) { case C_NULL: break; case C_AUTO: if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, DEBUG_LOCAL, bfd_asymbol_value (sym))) return false; break; case C_WEAKEXT: case C_EXT: if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, DEBUG_GLOBAL, bfd_asymbol_value (sym))) return false; break; case C_STAT: if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, (within_function ? DEBUG_LOCAL_STATIC : DEBUG_STATIC), bfd_asymbol_value (sym))) return false; break; case C_REG: /* FIXME: We may need to convert the register number. */ if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, DEBUG_REGISTER, bfd_asymbol_value (sym))) return false; break; case C_LABEL: break; case C_ARG: if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type, DEBUG_PARM_STACK, bfd_asymbol_value (sym))) return false; break; case C_REGPARM: /* FIXME: We may need to convert the register number. */ if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type, DEBUG_PARM_REG, bfd_asymbol_value (sym))) return false; break; case C_TPDEF: type = debug_name_type (dhandle, bfd_asymbol_name (sym), type); if (type == DEBUG_TYPE_NULL) return false; break; case C_STRTAG: case C_UNTAG: case C_ENTAG: { debug_type *slot; type = debug_tag_type (dhandle, bfd_asymbol_name (sym), type); if (type == DEBUG_TYPE_NULL) return false; /* Store the named type into the slot, so that references get the name. */ slot = coff_get_slot (types, coff_symno); *slot = type; } break; default: break; } return true; }/* Determine if a symbol has external visibility. */static booleanexternal_coff_symbol_p (sym_class) int sym_class;{ switch (sym_class) { case C_EXT: case C_WEAKEXT: return true; default: break; } return false; }/* This is the main routine. It looks through all the symbols and handles them. */booleanparse_coff (abfd, syms, symcount, dhandle) bfd *abfd; asymbol **syms; long symcount; PTR dhandle;{ struct coff_symbols symbols; struct coff_types types; int i; long next_c_file; const char *fnname; int fnclass; int fntype; bfd_vma fnend; alent *linenos; boolean within_function; long this_coff_symno; symbols.syms = syms; symbols.symcount = symcount; symbols.symno = 0; symbols.coff_symno = 0; types.slots = NULL; for (i = 0; i <= T_MAX; i++) types.basic[i] = DEBUG_TYPE_NULL; next_c_file = -1; fnname = NULL; fnclass = 0; fntype = 0; fnend = 0; linenos = NULL; within_function = false; while (symbols.symno < symcount) { asymbol *sym; const char *name; struct internal_syment syment; union internal_auxent auxent; union internal_auxent *paux; debug_type type; sym = syms[symbols.symno]; if (! bfd_coff_get_syment (abfd, sym, &syment)) { non_fatal (_("bfd_coff_get_syment failed: %s"), bfd_errmsg (bfd_get_error ())); return false; } name = bfd_asymbol_name (sym); this_coff_symno = symbols.coff_symno; ++symbols.symno; symbols.coff_symno += 1 + syment.n_numaux; /* We only worry about the first auxent, because that is the only one which is relevant for debugging information. */ if (syment.n_numaux == 0) paux = NULL; else { if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent)) { non_fatal (_("bfd_coff_get_auxent failed: %s"), bfd_errmsg (bfd_get_error ())); return false; } paux = &auxent; } if (this_coff_symno == next_c_file && syment.n_sclass != C_FILE) { /* The last C_FILE symbol points to the first external symbol. */ if (! debug_set_filename (dhandle, "*globals*")) return false; } switch (syment.n_sclass) { case C_EFCN: case C_EXTDEF: case C_ULABEL: case C_USTATIC: case C_LINE: case C_ALIAS: case C_HIDDEN: /* Just ignore these classes. */ break; case C_FILE: next_c_file = syment.n_value; if (! debug_set_filename (dhandle, name)) return false; break; case C_STAT: /* Ignore static symbols with a type of T_NULL. These represent section entries. */ if (syment.n_type == T_NULL) break; /* Fall through. */ case C_WEAKEXT: case C_EXT: if (ISFCN (syment.n_type)) { fnname = name; fnclass = syment.n_sclass; fntype = syment.n_type; if (syment.n_numaux > 0) fnend = bfd_asymbol_value (sym) + auxent.x_sym.x_misc.x_fsize; else fnend = 0; linenos = BFD_SEND (abfd, _get_lineno, (abfd, sym)); break; } type = parse_coff_type (abfd, &symbols, &types, this_coff_symno, syment.n_type, paux, true, dhandle); if (type == DEBUG_TYPE_NULL) return false; if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment, dhandle, type, within_function)) return false; break; case C_FCN: if (strcmp (name, ".bf") == 0) { if (fnname == NULL) { non_fatal (_("%ld: .bf without preceding function"), this_coff_symno); return false; } type = parse_coff_type (abfd, &symbols, &types, this_coff_symno, DECREF (fntype), paux, false, dhandle); if (type == DEBUG_TYPE_NULL) return false; if (! debug_record_function (dhandle, fnname, type, external_coff_symbol_p (fnclass), bfd_asymbol_value (sym))) return false; if (linenos != NULL) { int base; bfd_vma addr; if (syment.n_numaux == 0) base = 0; else base = auxent.x_sym.x_misc.x_lnsz.x_lnno - 1; addr = bfd_get_section_vma (abfd, bfd_get_section (sym)); ++linenos; while (linenos->line_number != 0) { if (! debug_record_line (dhandle, linenos->line_number + base, linenos->u.offset + addr)) return false; ++linenos; } } fnname = NULL; linenos = NULL; fnclass = 0; fntype = 0; within_function = true; } else if (strcmp (name, ".ef") == 0) { if (! within_function) { non_fatal (_("%ld: unexpected .ef\n"), this_coff_symno); return false; } if (bfd_asymbol_value (sym) > fnend) fnend = bfd_asymbol_value (sym); if (! debug_end_function (dhandle, fnend)) return false; fnend = 0; within_function = false; } break; case C_BLOCK: if (strcmp (name, ".bb") == 0) { if (! debug_start_block (dhandle, bfd_asymbol_value (sym))) return false; } else if (strcmp (name, ".eb") == 0) { if (! debug_end_block (dhandle, bfd_asymbol_value (sym))) return false; } break; default: type = parse_coff_type (abfd, &symbols, &types, this_coff_symno, syment.n_type, paux, true, dhandle); if (type == DEBUG_TYPE_NULL) return false; if (! parse_coff_symbol (abfd, &types, sym, this_coff_symno, &syment, dhandle, type, within_function)) return false; break; } } return true;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?