📄 ieee.c
字号:
else if (varindx < 32) { /* The MRI compiler reportedly sometimes emits variable lifetime information for a register. We just ignore it. */ if (atn_code == 9) return ieee_read_number (info, pp, &v); ieee_error (info, atn_start, _("illegal variable index")); return false; } else { varindx -= 32; if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL) { /* The MRI compiler or linker sometimes omits the NN record for a pmisc record. */ if (atn_code == 62) { if (varindx >= info->vars.alloc) { unsigned int alloc; alloc = info->vars.alloc; if (alloc == 0) alloc = 4; while (varindx >= alloc) alloc *= 2; info->vars.vars = ((struct ieee_var *) xrealloc (info->vars.vars, (alloc * sizeof *info->vars.vars))); memset (info->vars.vars + info->vars.alloc, 0, ((alloc - info->vars.alloc) * sizeof *info->vars.vars)); info->vars.alloc = alloc; } pvar = info->vars.vars + varindx; pvar->name = ""; pvar->namlen = 0; } else { ieee_error (info, atn_start, _("undefined variable in ATN")); return false; } } pvar = info->vars.vars + varindx; pvar->type = type; name = pvar->name; namlen = pvar->namlen; } dhandle = info->dhandle; /* If we are going to call debug_record_variable with a pointer type, change the type to an indirect type so that we can later change it to a reference type if we encounter a C++ pmisc 'R' record. */ if (pvar != NULL && type != DEBUG_TYPE_NULL && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER) { switch (atn_code) { case 1: case 2: case 3: case 5: case 8: case 10: pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot); *pvar->pslot = type; type = debug_make_indirect_type (dhandle, pvar->pslot, (const char *) NULL); pvar->type = type; break; } } switch (atn_code) { default: ieee_error (info, atn_code_start, _("unknown ATN type")); return false; case 1: /* Automatic variable. */ if (! ieee_read_number (info, pp, &v)) return false; namcopy = savestring (name, namlen); if (type == NULL) type = debug_make_void_type (dhandle); if (pvar != NULL) pvar->kind = IEEE_LOCAL; return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v); case 2: /* Register variable. */ if (! ieee_read_number (info, pp, &v)) return false; namcopy = savestring (name, namlen); if (type == NULL) type = debug_make_void_type (dhandle); if (pvar != NULL) pvar->kind = IEEE_LOCAL; return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, ieee_regno_to_genreg (info->abfd, v)); case 3: /* Static variable. */ if (! ieee_require_asn (info, pp, &v)) return false; namcopy = savestring (name, namlen); if (type == NULL) type = debug_make_void_type (dhandle); if (info->blockstack.bsp <= info->blockstack.stack) blocktype = 0; else blocktype = info->blockstack.bsp[-1].kind; if (pvar != NULL) { if (blocktype == 4 || blocktype == 6) pvar->kind = IEEE_LOCAL; else pvar->kind = IEEE_STATIC; } return debug_record_variable (dhandle, namcopy, type, (blocktype == 4 || blocktype == 6 ? DEBUG_LOCAL_STATIC : DEBUG_STATIC), v); case 4: /* External function. We don't currently record these. FIXME. */ if (pvar != NULL) pvar->kind = IEEE_EXTERNAL; return true; case 5: /* External variable. We don't currently record these. FIXME. */ if (pvar != NULL) pvar->kind = IEEE_EXTERNAL; return true; case 7: if (! ieee_read_number (info, pp, &v) || ! ieee_read_number (info, pp, &v2) || ! ieee_read_optional_number (info, pp, &v3, &present)) return false; if (present) { if (! ieee_read_optional_number (info, pp, &v4, &present)) return false; } /* We just ignore the two optional fields in v3 and v4, since they are not defined. */ if (! ieee_require_asn (info, pp, &v3)) return false; /* We have no way to record the column number. FIXME. */ return debug_record_line (dhandle, v, v3); case 8: /* Global variable. */ if (! ieee_require_asn (info, pp, &v)) return false; namcopy = savestring (name, namlen); if (type == NULL) type = debug_make_void_type (dhandle); if (pvar != NULL) pvar->kind = IEEE_GLOBAL; return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v); case 9: /* Variable lifetime information. */ if (! ieee_read_number (info, pp, &v)) return false; /* We have no way to record this information. FIXME. */ return true; case 10: /* Locked register. The spec says that there are two required fields, but at least on occasion the MRI compiler only emits one. */ if (! ieee_read_number (info, pp, &v) || ! ieee_read_optional_number (info, pp, &v2, &present)) return false; /* I think this means a variable that is both in a register and a frame slot. We ignore the frame slot. FIXME. */ namcopy = savestring (name, namlen); if (type == NULL) type = debug_make_void_type (dhandle); if (pvar != NULL) pvar->kind = IEEE_LOCAL; return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v); case 11: /* Reserved for FORTRAN common. */ ieee_error (info, atn_code_start, _("unsupported ATN11")); /* Return true to keep going. */ return true; case 12: /* Based variable. */ v3 = 0; v4 = 0x80; v5 = 0; if (! ieee_read_number (info, pp, &v) || ! ieee_read_number (info, pp, &v2) || ! ieee_read_optional_number (info, pp, &v3, &present)) return false; if (present) { if (! ieee_read_optional_number (info, pp, &v4, &present)) return false; if (present) { if (! ieee_read_optional_number (info, pp, &v5, &present)) return false; } } /* We have no way to record this information. FIXME. */ ieee_error (info, atn_code_start, _("unsupported ATN12")); /* Return true to keep going. */ return true; case 16: /* Constant. The description of this that I have is ambiguous, so I'm not going to try to implement it. */ if (! ieee_read_number (info, pp, &v) || ! ieee_read_optional_number (info, pp, &v2, &present)) return false; if (present) { if (! ieee_read_optional_number (info, pp, &v2, &present)) return false; if (present) { if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) return false; } } if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum) { if (! ieee_require_asn (info, pp, &v3)) return false; } return true; case 19: /* Static variable from assembler. */ v2 = 0; if (! ieee_read_number (info, pp, &v) || ! ieee_read_optional_number (info, pp, &v2, &present) || ! ieee_require_asn (info, pp, &v3)) return false; namcopy = savestring (name, namlen); /* We don't really handle this correctly. FIXME. */ return debug_record_variable (dhandle, namcopy, debug_make_void_type (dhandle), v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC, v3); case 62: /* Procedure miscellaneous information. */ case 63: /* Variable miscellaneous information. */ case 64: /* Module miscellaneous information. */ if (! ieee_read_number (info, pp, &v) || ! ieee_read_number (info, pp, &v2) || ! ieee_read_optional_id (info, pp, &name, &namlen, &present)) return false; if (atn_code == 62 && v == 80) { if (present) { ieee_error (info, atn_code_start, _("unexpected string in C++ misc")); return false; } return ieee_read_cxx_misc (info, pp, v2); } /* We just ignore all of this stuff. FIXME. */ for (; v2 > 0; --v2) { switch ((ieee_record_enum_type) **pp) { default: ieee_error (info, *pp, _("bad misc record")); return false; case ieee_at_record_enum: if (! ieee_require_atn65 (info, pp, &name, &namlen)) return false; break; case ieee_e2_first_byte_enum: if (! ieee_require_asn (info, pp, &v3)) return false; break; } } return true; } /*NOTREACHED*/}/* Handle C++ debugging miscellaneous records. This is called for procedure miscellaneous records of type 80. */static booleanieee_read_cxx_misc (info, pp, count) struct ieee_info *info; const bfd_byte **pp; unsigned long count;{ const bfd_byte *start; bfd_vma category; start = *pp; /* Get the category of C++ misc record. */ if (! ieee_require_asn (info, pp, &category)) return false; --count; switch (category) { default: ieee_error (info, start, _("unrecognized C++ misc record")); return false; case 'T': if (! ieee_read_cxx_class (info, pp, count)) return false; break; case 'M': { bfd_vma flags; const char *name; unsigned long namlen; /* The IEEE spec indicates that the 'M' record only has a flags field. The MRI compiler also emits the name of the function. */ if (! ieee_require_asn (info, pp, &flags)) return false; if (*pp < info->pend && (ieee_record_enum_type) **pp == ieee_at_record_enum) { if (! ieee_require_atn65 (info, pp, &name, &namlen)) return false; } /* This is emitted for method functions, but I don't think we care very much. It might help if it told us useful information like the class with which this function is associated, but it doesn't, so it isn't helpful. */ } break; case 'B': if (! ieee_read_cxx_defaults (info, pp, count)) return false; break; case 'z': { const char *name, *mangled, *class; unsigned long namlen, mangledlen, classlen; bfd_vma control; /* Pointer to member. */ if (! ieee_require_atn65 (info, pp, &name, &namlen) || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen) || ! ieee_require_atn65 (info, pp, &class, &classlen) || ! ieee_require_asn (info, pp, &control)) return false; /* FIXME: We should now track down name and change its type. */ } break; case 'R': if (! ieee_read_reference (info, pp)) return false; break; } return true;}/* Read a C++ class definition. This is a pmisc type 80 record of category 'T'. */static booleanieee_read_cxx_class (info, pp, count) struct ieee_info *info; const bfd_byte **pp; unsigned long count;{ const bfd_byte *start; bfd_vma class; const char *tag; unsigned long taglen; struct ieee_tag *it; PTR dhandle; debug_field *fields; unsigned int field_count, field_alloc; debug_baseclass *baseclasses; unsigned int baseclasses_count, baseclasses_alloc; const debug_field *structfields; struct ieee_method { const char *name; unsigned long namlen; debug_method_variant *variants; unsigned count; unsigned int alloc; } *methods; unsigned int methods_count, methods_alloc; debug_type vptrbase; boolean ownvptr; debug_method *dmethods; start = *pp; if (! ieee_require_asn (info, pp, &class)) return false; --count; if (! ieee_require_atn65 (info, pp, &tag, &taglen)) return false; --count; /* Find the C struct with this name. */ for (it = info->tags; it != NULL; it = it->next) if (it->name[0] == tag[0] && strncmp (it->name, tag, taglen) == 0 && strlen (it->name) == taglen) break; if (it == NULL) { ieee_error (info, start, _("undefined C++ object")); return false; } dhandle = info->dhandle; fields = NULL; field_count = 0; field_alloc = 0; baseclasses = NULL; baseclasses_count = 0; baseclasses_alloc = 0; methods = NULL; methods_count = 0; methods_alloc = 0; vptrbase = DEBUG_TYPE_NULL; ownvptr = false; structfields = debug_get_fields (dhandle, it->type); while (count > 0) { bfd_vma id; const bfd_byte *spec_start; spec_start = *pp; if (! ieee_require_asn (info, pp, &id)) return false; --count; switch (id) { default: ieee_error (info, spec_start, _("unrecognized C++ object spec")); return false; case 'b': { bfd_vma flags, cinline; const char *basename, *fieldname; unsigned long baselen, fieldlen; char *basecopy; debug_type basetype; bfd_vma bitpos; boolean virtualp; enum debug_visibility visibility; debug_baseclass baseclass; /* This represents a base or friend class. */ if (! ieee_require_asn (info, pp, &flags) || ! ieee_require_atn65 (info, pp, &basename, &baselen) || ! ieee_require_asn (info, pp, &cinline) || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)) return false; count -= 4; /* We have no way of recording friend information, so we just ignore it. */ if ((flags & BASEFLAGS_FRIEND) != 0) break; /* I assume that either all of the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -