📄 dwarfread.c
字号:
Decode the language attribute for a compilation unit DIE and remember what the language was. We use this at various times when processing DIE's for a given compilation unit.RETURNS No return value. */static voidset_cu_language (dip) struct dieinfo *dip;{ switch (dip -> at_language) { case LANG_C89: case LANG_C: cu_language = language_c; break; case LANG_C_PLUS_PLUS: cu_language = language_cplus; break; case LANG_ADA83: case LANG_COBOL74: case LANG_COBOL85: case LANG_FORTRAN77: case LANG_FORTRAN90: case LANG_PASCAL83: case LANG_MODULA2: default: cu_language = language_unknown; break; }}/*GLOBAL FUNCTION dwarf_build_psymtabs -- build partial symtabs from DWARF debug infoSYNOPSIS void dwarf_build_psymtabs (struct objfile *objfile, struct section_offsets *section_offsets, int mainline, file_ptr dbfoff, unsigned int dbfsize, file_ptr lnoffset, unsigned int lnsize)DESCRIPTION This function is called upon to build partial symtabs from files containing DIE's (Dwarf Information Entries) and DWARF line numbers. It is passed a bfd* containing the DIES and line number information, the corresponding filename for that file, a base address for relocating the symbols, a flag indicating whether or not this debugging information is from a "main symbol table" rather than a shared library or dynamically linked file, and file offset/size pairs for the DIE information and line number information.RETURNS No return value. */voiddwarf_build_psymtabs (objfile, section_offsets, mainline, dbfoff, dbfsize, lnoffset, lnsize) struct objfile *objfile; struct section_offsets *section_offsets; int mainline; file_ptr dbfoff; unsigned int dbfsize; file_ptr lnoffset; unsigned int lnsize;{ bfd *abfd = objfile->obfd; struct cleanup *back_to; current_objfile = objfile; dbsize = dbfsize; dbbase = xmalloc (dbsize); dbroff = 0; if ((bfd_seek (abfd, dbfoff, L_SET) != 0) || (bfd_read (dbbase, dbsize, 1, abfd) != dbsize)) { free (dbbase); error ("can't read DWARF data from '%s'", bfd_get_filename (abfd)); } back_to = make_cleanup (free, dbbase); /* If we are reinitializing, or if we have never loaded syms yet, init. Since we have no idea how many DIES we are looking at, we just guess some arbitrary value. */ if (mainline || objfile -> global_psymbols.size == 0 || objfile -> static_psymbols.size == 0) { init_psymbol_list (objfile, 1024); } /* Save the relocation factor where everybody can see it. */ base_section_offsets = section_offsets; baseaddr = ANOFFSET (section_offsets, 0); /* Follow the compilation unit sibling chain, building a partial symbol table entry for each one. Save enough information about each compilation unit to locate the full DWARF information later. */ scan_compilation_units (dbbase, dbbase + dbsize, dbfoff, lnoffset, objfile); do_cleanups (back_to); current_objfile = NULL;}/*LOCAL FUNCTION record_minimal_symbol -- add entry to gdb's minimal symbol tableSYNOPSIS static void record_minimal_symbol (char *name, CORE_ADDR address, enum minimal_symbol_type ms_type, struct objfile *objfile)DESCRIPTION Given a pointer to the name of a symbol that should be added to the minimal symbol table, and the address associated with that symbol, records this information for later use in building the minimal symbol table. */static voidrecord_minimal_symbol (name, address, ms_type, objfile) char *name; CORE_ADDR address; enum minimal_symbol_type ms_type; struct objfile *objfile;{ name = obsavestring (name, strlen (name), &objfile -> symbol_obstack); prim_record_minimal_symbol (name, address, ms_type);}/*LOCAL FUNCTION dwarfwarn -- issue a DWARF related warningDESCRIPTION Issue warnings about DWARF related things that aren't serious enough to warrant aborting with an error, but should not be ignored either. This includes things like detectable corruption in DIE's, missing DIE's, unimplemented features, etc. In general, running across tags or attributes that we don't recognize is not considered to be a problem and we should not issue warnings about such.NOTES We mostly follow the example of the error() routine, but without returning to command level. It is arguable about whether warnings should be issued at all, and if so, where they should go (stdout or stderr). We assume that curdie is valid and contains at least the basic information for the DIE where the problem was noticed.*/static voiddwarfwarn (va_alist) va_dcl{ va_list ap; char *fmt; va_start (ap); fmt = va_arg (ap, char *); warning_setup (); fprintf (stderr, "warning: DWARF ref 0x%x: ", curdie -> die_ref); if (curdie -> at_name) { fprintf (stderr, "'%s': ", curdie -> at_name); } vfprintf (stderr, fmt, ap); fprintf (stderr, "\n"); fflush (stderr); va_end (ap);}/*LOCAL FUNCTION read_lexical_block_scope -- process all dies in a lexical blockSYNOPSIS static void read_lexical_block_scope (struct dieinfo *dip, char *thisdie, char *enddie)DESCRIPTION Process all the DIES contained within a lexical block scope. Start a new scope, process the dies, and then close the scope. */static voidread_lexical_block_scope (dip, thisdie, enddie, objfile) struct dieinfo *dip; char *thisdie; char *enddie; struct objfile *objfile;{ register struct context_stack *new; push_context (0, dip -> at_low_pc); process_dies (thisdie + dip -> die_length, enddie, objfile); new = pop_context (); if (local_symbols != NULL) { finish_block (0, &local_symbols, new -> old_blocks, new -> start_addr, dip -> at_high_pc, objfile); } local_symbols = new -> locals;}/*LOCAL FUNCTION lookup_utype -- look up a user defined type from die referenceSYNOPSIS static type *lookup_utype (DIE_REF die_ref)DESCRIPTION Given a DIE reference, lookup the user defined type associated with that DIE, if it has been registered already. If not registered, then return NULL. Alloc_utype() can be called to register an empty type for this reference, which will be filled in later when the actual referenced DIE is processed. */static struct type *lookup_utype (die_ref) DIE_REF die_ref;{ struct type *type = NULL; int utypeidx; utypeidx = (die_ref - dbroff) / 4; if ((utypeidx < 0) || (utypeidx >= numutypes)) { dwarfwarn ("reference to DIE (0x%x) outside compilation unit", die_ref); } else { type = *(utypes + utypeidx); } return (type);}/*LOCAL FUNCTION alloc_utype -- add a user defined type for die referenceSYNOPSIS static type *alloc_utype (DIE_REF die_ref, struct type *utypep)DESCRIPTION Given a die reference DIE_REF, and a possible pointer to a user defined type UTYPEP, register that this reference has a user defined type and either use the specified type in UTYPEP or make a new empty type that will be filled in later. We should only be called after calling lookup_utype() to verify that there is not currently a type registered for DIE_REF. */static struct type *alloc_utype (die_ref, utypep) DIE_REF die_ref; struct type *utypep;{ struct type **typep; int utypeidx; utypeidx = (die_ref - dbroff) / 4; typep = utypes + utypeidx; if ((utypeidx < 0) || (utypeidx >= numutypes)) { utypep = lookup_fundamental_type (current_objfile, FT_INTEGER); dwarfwarn ("reference to DIE (0x%x) outside compilation unit", die_ref); } else if (*typep != NULL) { utypep = *typep; SQUAWK (("internal error: dup user type allocation")); } else { if (utypep == NULL) { utypep = alloc_type (current_objfile); } *typep = utypep; } return (utypep);}/*LOCAL FUNCTION decode_die_type -- return a type for a specified dieSYNOPSIS static struct type *decode_die_type (struct dieinfo *dip)DESCRIPTION Given a pointer to a die information structure DIP, decode the type of the die and return a pointer to the decoded type. All dies without specific types default to type int. */static struct type *decode_die_type (dip) struct dieinfo *dip;{ struct type *type = NULL; if (dip -> at_fund_type != 0) { type = decode_fund_type (dip -> at_fund_type); } else if (dip -> at_mod_fund_type != NULL) { type = decode_mod_fund_type (dip -> at_mod_fund_type); } else if (dip -> at_user_def_type) { if ((type = lookup_utype (dip -> at_user_def_type)) == NULL) { type = alloc_utype (dip -> at_user_def_type, NULL); } } else if (dip -> at_mod_u_d_type) { type = decode_mod_u_d_type (dip -> at_mod_u_d_type); } else { type = lookup_fundamental_type (current_objfile, FT_INTEGER); } return (type);}/*LOCAL FUNCTION struct_type -- compute and return the type for a struct or unionSYNOPSIS static struct type *struct_type (struct dieinfo *dip, char *thisdie, char *enddie, struct objfile *objfile)DESCRIPTION Given pointer to a die information structure for a die which defines a union or structure (and MUST define one or the other), and pointers to the raw die data that define the range of dies which define the members, compute and return the user defined type for the structure or union. */static struct type *struct_type (dip, thisdie, enddie, objfile) struct dieinfo *dip; char *thisdie; char *enddie; struct objfile *objfile;{ struct type *type; struct nextfield { struct nextfield *next; struct field field; }; struct nextfield *list = NULL; struct nextfield *new; int nfields = 0; int n; char *tpart1; struct dieinfo mbr; char *nextdie; int anonymous_size; if ((type = lookup_utype (dip -> die_ref)) == NULL) { /* No forward references created an empty type, so install one now */ type = alloc_utype (dip -> die_ref, NULL); } INIT_CPLUS_SPECIFIC(type); switch (dip -> die_tag) { case TAG_class_type: TYPE_CODE (type) = TYPE_CODE_CLASS; tpart1 = "class"; break; case TAG_structure_type: TYPE_CODE (type) = TYPE_CODE_STRUCT; tpart1 = "struct"; break; case TAG_union_type: TYPE_CODE (type) = TYPE_CODE_UNION; tpart1 = "union"; break; default: /* Should never happen */ TYPE_CODE (type) = TYPE_CODE_UNDEF; tpart1 = "???"; SQUAWK (("missing class, structure, or union tag")); break; } /* Some compilers try to be helpful by inventing "fake" names for anonymous enums, structures, and unions, like "~0fake" or ".0fake". Thanks, but no thanks... */ if (dip -> at_name != NULL && *dip -> at_name != '~' && *dip -> at_name != '.') { TYPE_NAME (type) = obconcat (&objfile -> type_obstack, tpart1, " ", dip -> at_name); } /* Use whatever size is known. Zero is a valid size. We might however wish to check has_at_byte_size to make sure that some byte size was given explicitly, but DWARF doesn't specify that explicit sizes of zero have to present, so complaining about missing sizes should probably not be the default. */ TYPE_LENGTH (type) = dip -> at_byte_size; thisdie += dip -> die_length; while (thisdie < enddie)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -