X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=0a7a0334202429c70328763b83ef9323f4c45ea9;hb=59c35742fb785b1e454f45c2ace663000bf34f4c;hp=a78f818e0e8734c2ae99ed734b7bf3fa178493ea;hpb=950b74950f6020eda38647f22e9077ac7f68ca49;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index a78f818e0e..0a7a033420 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -909,13 +909,13 @@ typedef void (die_reader_func_ftype) (const struct die_reader_specs *reader, int has_children, void *data); -/* A 1-based directory index. This is a strong typedef to prevent - accidentally using a directory index as a 0-based index into an - array/vector. */ -enum class dir_index : unsigned int {}; +/* dir_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5 and + later. */ +typedef int dir_index; -/* Likewise, a 1-based file name index. */ -enum class file_name_index : unsigned int {}; +/* file_name_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5 + and later. */ +typedef int file_name_index; struct file_entry { @@ -967,32 +967,47 @@ struct line_header void add_file_name (const char *name, dir_index d_index, unsigned int mod_time, unsigned int length); - /* Return the include dir at INDEX (1-based). Returns NULL if INDEX - is out of bounds. */ + /* Return the include dir at INDEX (0-based in DWARF 5 and 1-based before). + Returns NULL if INDEX is out of bounds. */ const char *include_dir_at (dir_index index) const { - /* Convert directory index number (1-based) to vector index - (0-based). */ - size_t vec_index = to_underlying (index) - 1; - - if (vec_index >= include_dirs.size ()) + int vec_index; + if (version >= 5) + vec_index = index; + else + vec_index = index - 1; + if (vec_index < 0 || vec_index >= m_include_dirs.size ()) return NULL; - return include_dirs[vec_index]; + return m_include_dirs[vec_index]; } - /* Return the file name at INDEX (1-based). Returns NULL if INDEX - is out of bounds. */ - file_entry *file_name_at (file_name_index index) + bool is_valid_file_index (int file_index) { - /* Convert file name index number (1-based) to vector index - (0-based). */ - size_t vec_index = to_underlying (index) - 1; + if (version >= 5) + return 0 <= file_index && file_index < file_names_size (); + return 1 <= file_index && file_index <= file_names_size (); + } - if (vec_index >= file_names.size ()) + /* Return the file name at INDEX (0-based in DWARF 5 and 1-based before). + Returns NULL if INDEX is out of bounds. */ + file_entry *file_name_at (file_name_index index) + { + int vec_index; + if (version >= 5) + vec_index = index; + else + vec_index = index - 1; + if (vec_index < 0 || vec_index >= m_file_names.size ()) return NULL; - return &file_names[vec_index]; + return &m_file_names[vec_index]; } + /* The indexes are 0-based in DWARF 5 and 1-based in DWARF 4. Therefore, + this method should only be used to iterate through all file entries in an + index-agnostic manner. */ + std::vector &file_names () + { return m_file_names; } + /* Offset of line number information in .debug_line section. */ sect_offset sect_off {}; @@ -1015,16 +1030,23 @@ struct line_header element is standard_opcode_lengths[opcode_base - 1]. */ std::unique_ptr standard_opcode_lengths; - /* The include_directories table. Note these are observing - pointers. The memory is owned by debug_line_buffer. */ - std::vector include_dirs; - - /* The file_names table. */ - std::vector file_names; + int file_names_size () + { return m_file_names.size(); } /* The start and end of the statement program following this header. These point into dwarf2_per_objfile->line_buffer. */ const gdb_byte *statement_program_start {}, *statement_program_end {}; + + private: + /* The include_directories table. Note these are observing + pointers. The memory is owned by debug_line_buffer. */ + std::vector m_include_dirs; + + /* The file_names table. This is private because the meaning of indexes + differs among DWARF versions (The first valid index is 1 in DWARF 4 and + before, and is 0 in DWARF 5 and later). So the client should use + file_name_at method for access. */ + std::vector m_file_names; }; typedef std::unique_ptr line_header_up; @@ -1375,7 +1397,7 @@ struct field_info /* Number of fields (including baseclasses). */ int nfields = 0; - /* Set if the accesibility of one of the fields is not public. */ + /* Set if the accessibility of one of the fields is not public. */ int non_public_fields = 0; /* Member function fieldlist array, contains name of possibly overloaded @@ -1486,7 +1508,7 @@ struct cu_partial_die_info cu_partial_die_info (struct dwarf2_cu *cu, struct partial_die_info *pdi) : cu (cu), pdi (pdi) - { /* Nothhing. */ } + { /* Nothing. */ } private: cu_partial_die_info () = delete; @@ -3640,7 +3662,6 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader, struct objfile *objfile = dwarf2_per_objfile->objfile; struct dwarf2_per_cu_data *lh_cu; struct attribute *attr; - int i; void **slot; struct quick_file_names *qfn; @@ -3699,12 +3720,12 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader, if (strcmp (fnd.name, "") != 0) ++offset; - qfn->num_file_names = offset + lh->file_names.size (); + qfn->num_file_names = offset + lh->file_names_size (); qfn->file_names = XOBNEWVEC (&objfile->objfile_obstack, const char *, qfn->num_file_names); if (offset != 0) qfn->file_names[0] = xstrdup (fnd.name); - for (i = 0; i < lh->file_names.size (); ++i) + for (int i = 0; i < lh->file_names_size (); ++i) qfn->file_names[i + offset] = file_full_name (i + 1, lh.get (), fnd.comp_dir); qfn->real_names = NULL; @@ -4021,6 +4042,10 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter) if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER) continue; break; + case MODULE_DOMAIN: + if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER) + continue; + break; default: break; } @@ -5043,6 +5068,10 @@ dw2_expand_marked_cus if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE) continue; break; + case MODULES_DOMAIN: + if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER) + continue; + break; default: break; } @@ -5949,6 +5978,15 @@ dw2_debug_names_iterator::next () goto again; } break; + case MODULE_DOMAIN: + switch (indexval.dwarf_tag) + { + case DW_TAG_module: + break; + default: + goto again; + } + break; default: break; } @@ -5985,6 +6023,14 @@ dw2_debug_names_iterator::next () goto again; } break; + case MODULES_DOMAIN: + switch (indexval.dwarf_tag) + { + case DW_TAG_module: + break; + default: + goto again; + } default: break; } @@ -8712,7 +8758,8 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc, add_partial_namespace (pdi, lowpc, highpc, set_addrmap, cu); break; case DW_TAG_module: - add_partial_module (pdi, lowpc, highpc, set_addrmap, cu); + if (!pdi->is_declaration) + add_partial_module (pdi, lowpc, highpc, set_addrmap, cu); break; case DW_TAG_imported_unit: { @@ -8931,7 +8978,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) But in Ada and Fortran, we want to be able to access nested procedures globally. So all Ada and Fortran subprograms are stored in the global scope. */ - add_psymbol_to_list (actual_name, strlen (actual_name), + add_psymbol_to_list (actual_name, built_actual_name != NULL, VAR_DOMAIN, LOC_BLOCK, SECT_OFF_TEXT (objfile), @@ -8941,7 +8988,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) } else { - add_psymbol_to_list (actual_name, strlen (actual_name), + add_psymbol_to_list (actual_name, built_actual_name != NULL, VAR_DOMAIN, LOC_BLOCK, SECT_OFF_TEXT (objfile), @@ -8953,7 +9000,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) set_objfile_main_name (objfile, actual_name, cu->language); break; case DW_TAG_constant: - add_psymbol_to_list (actual_name, strlen (actual_name), + add_psymbol_to_list (actual_name, built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC, -1, (pdi->is_external ? psymbol_placement::GLOBAL @@ -8989,7 +9036,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) table building. */ if (pdi->d.locdesc || pdi->has_type) - add_psymbol_to_list (actual_name, strlen (actual_name), + add_psymbol_to_list (actual_name, built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC, SECT_OFF_TEXT (objfile), @@ -9008,7 +9055,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) return; } - add_psymbol_to_list (actual_name, strlen (actual_name), + add_psymbol_to_list (actual_name, built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC, SECT_OFF_TEXT (objfile), @@ -9020,7 +9067,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) case DW_TAG_typedef: case DW_TAG_base_type: case DW_TAG_subrange_type: - add_psymbol_to_list (actual_name, strlen (actual_name), + add_psymbol_to_list (actual_name, built_actual_name != NULL, VAR_DOMAIN, LOC_TYPEDEF, -1, psymbol_placement::STATIC, @@ -9028,7 +9075,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) break; case DW_TAG_imported_declaration: case DW_TAG_namespace: - add_psymbol_to_list (actual_name, strlen (actual_name), + add_psymbol_to_list (actual_name, built_actual_name != NULL, VAR_DOMAIN, LOC_TYPEDEF, -1, psymbol_placement::GLOBAL, @@ -9039,7 +9086,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) available without any name. If so, we skip the module as it doesn't bring any value. */ if (actual_name != nullptr) - add_psymbol_to_list (actual_name, strlen (actual_name), + add_psymbol_to_list (actual_name, built_actual_name != NULL, MODULE_DOMAIN, LOC_TYPEDEF, -1, psymbol_placement::GLOBAL, @@ -9063,7 +9110,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) /* NOTE: carlton/2003-10-07: See comment in new_symbol about static vs. global. */ - add_psymbol_to_list (actual_name, strlen (actual_name), + add_psymbol_to_list (actual_name, built_actual_name != NULL, STRUCT_DOMAIN, LOC_TYPEDEF, -1, cu->language == language_cplus @@ -9073,7 +9120,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) break; case DW_TAG_enumerator: - add_psymbol_to_list (actual_name, strlen (actual_name), + add_psymbol_to_list (actual_name, built_actual_name != NULL, VAR_DOMAIN, LOC_CONST, -1, cu->language == language_cplus @@ -9903,8 +9950,7 @@ fixup_go_packaging (struct dwarf2_cu *cu) sym = allocate_symbol (objfile); SYMBOL_SET_LANGUAGE (sym, language_go, &objfile->objfile_obstack); - SYMBOL_SET_NAMES (sym, saved_package_name, - strlen (saved_package_name), 0, objfile); + SYMBOL_SET_NAMES (sym, saved_package_name, false, objfile); /* This is not VAR_DOMAIN because we want a way to ensure a lookup of, e.g., "main" finds the "main" module and not C's main(). */ SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; @@ -11702,14 +11748,14 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die) process_full_type_unit still needs to know if this is the first time. */ - tu_group->num_symtabs = line_header->file_names.size (); + tu_group->num_symtabs = line_header->file_names_size (); tu_group->symtabs = XNEWVEC (struct symtab *, - line_header->file_names.size ()); + line_header->file_names_size ()); - for (i = 0; i < line_header->file_names.size (); ++i) + auto &file_names = line_header->file_names (); + for (i = 0; i < file_names.size (); ++i) { - file_entry &fe = line_header->file_names[i]; - + file_entry &fe = file_names[i]; dwarf2_start_subfile (this, fe.name, fe.include_dir (line_header)); buildsym_compunit *b = get_builder (); @@ -11738,10 +11784,10 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die) compunit_language (cust), 0, cust)); - for (i = 0; i < line_header->file_names.size (); ++i) + auto &file_names = line_header->file_names (); + for (i = 0; i < file_names.size (); ++i) { - file_entry &fe = line_header->file_names[i]; - + file_entry &fe = file_names[i]; fe.symtab = tu_group->symtabs[i]; } } @@ -14942,7 +14988,7 @@ producer_is_codewarrior (struct dwarf2_cu *cu) return cu->producer_is_codewarrior; } -/* Return the default accessibility type if it is not overriden by +/* Return the default accessibility type if it is not overridden by DW_AT_accessibility. */ static enum dwarf_access_attribute @@ -16215,7 +16261,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) { /* Any related symtab will do. */ symtab - = cu->line_header->file_name_at (file_name_index (1))->symtab; + = cu->line_header->file_names ()[0].symtab; } else { @@ -16751,7 +16797,7 @@ mark_common_block_symbol_computed (struct symbol *sym, /* Create appropriate locally-scoped variables for all the DW_TAG_common_block entries. Also create a struct common_block listing all such variables for `info common'. COMMON_BLOCK_DOMAIN - is used to sepate the common blocks name namespace from regular + is used to separate the common blocks name namespace from regular variable names. */ static void @@ -17309,7 +17355,7 @@ prototyped_function_p (struct die_info *die, struct dwarf2_cu *cu) return 1; /* The DWARF standard implies that the DW_AT_prototyped attribute - is only meaninful for C, but the concept also extends to other + is only meaningful for C, but the concept also extends to other languages that allow unprototyped functions (Eg: Objective C). For all other languages, assume that functions are always prototyped. */ @@ -18039,7 +18085,7 @@ read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu) TYPE_NAME (type) = dwarf2_name (die, cu); /* In Ada, an unspecified type is typically used when the description - of the type is defered to a different unit. When encountering + of the type is deferred to a different unit. When encountering such a type, we treat it as a stub, and try to resolve it later on, when needed. */ if (cu->language == language_ada) @@ -18545,7 +18591,7 @@ load_partial_dies (const struct die_reader_specs *reader, || pdi.tag == DW_TAG_subrange_type)) { if (building_psymtab && pdi.name != NULL) - add_psymbol_to_list (pdi.name, strlen (pdi.name), false, + add_psymbol_to_list (pdi.name, false, VAR_DOMAIN, LOC_TYPEDEF, -1, psymbol_placement::STATIC, 0, cu->language, objfile); @@ -18579,7 +18625,7 @@ load_partial_dies (const struct die_reader_specs *reader, if (pdi.name == NULL) complaint (_("malformed enumerator DIE ignored")); else if (building_psymtab) - add_psymbol_to_list (pdi.name, strlen (pdi.name), false, + add_psymbol_to_list (pdi.name, false, VAR_DOMAIN, LOC_CONST, -1, cu->language == language_cplus ? psymbol_placement::GLOBAL @@ -20199,7 +20245,7 @@ dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *c } /* Return the dwo name or NULL if not present. If present, it is in either - DW_AT_GNU_dwo_name or DW_AT_dwo_name atrribute. */ + DW_AT_GNU_dwo_name or DW_AT_dwo_name attribute. */ static const char * dwarf2_dwo_name (struct die_info *die, struct dwarf2_cu *cu) { @@ -20270,10 +20316,16 @@ void line_header::add_include_dir (const char *include_dir) { if (dwarf_line_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "Adding dir %zu: %s\n", - include_dirs.size () + 1, include_dir); - - include_dirs.push_back (include_dir); + { + size_t new_size; + if (version >= 5) + new_size = m_include_dirs.size (); + else + new_size = m_include_dirs.size () + 1; + fprintf_unfiltered (gdb_stdlog, "Adding dir %zu: %s\n", + new_size, include_dir); + } + m_include_dirs.push_back (include_dir); } void @@ -20283,10 +20335,16 @@ line_header::add_file_name (const char *name, unsigned int length) { if (dwarf_line_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "Adding file %u: %s\n", - (unsigned) file_names.size () + 1, name); - - file_names.emplace_back (name, d_index, mod_time, length); + { + size_t new_size; + if (version >= 5) + new_size = file_names_size (); + else + new_size = file_names_size () + 1; + fprintf_unfiltered (gdb_stdlog, "Adding file %zu: %s\n", + new_size, name); + } + m_file_names.emplace_back (name, d_index, mod_time, length); } /* A convenience function to find the proper .debug_line section for a CU. */ @@ -20400,6 +20458,11 @@ read_formatted_entries (struct dwarf2_per_objfile *dwarf2_per_objfile, buf += 8; break; + case DW_FORM_data16: + /* This is used for MD5, but file_entry does not record MD5s. */ + buf += 16; + break; + case DW_FORM_udata: uint.emplace (read_unsigned_leb128 (abfd, buf, &bytes_read)); buf += bytes_read; @@ -20500,12 +20563,15 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) read_checked_initial_length_and_offset (abfd, line_ptr, &cu->header, &bytes_read, &offset_size); line_ptr += bytes_read; + + const gdb_byte *start_here = line_ptr; + if (line_ptr + lh->total_length > (section->buffer + section->size)) { dwarf2_statement_list_fits_in_line_number_section_complaint (); return 0; } - lh->statement_program_end = line_ptr + lh->total_length; + lh->statement_program_end = start_here + lh->total_length; lh->version = read_2_bytes (abfd, line_ptr); line_ptr += 2; if (lh->version > 5) @@ -20535,6 +20601,7 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) } lh->header_length = read_offset_1 (abfd, line_ptr, offset_size); line_ptr += offset_size; + lh->statement_program_start = line_ptr + lh->header_length; lh->minimum_instruction_length = read_1_byte (abfd, line_ptr); line_ptr += 1; if (lh->version >= 4) @@ -20619,7 +20686,6 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) } line_ptr += bytes_read; } - lh->statement_program_start = line_ptr; if (line_ptr > (section->buffer + section->size)) complaint (_("line number info header doesn't " @@ -20629,19 +20695,17 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu) } /* Subroutine of dwarf_decode_lines to simplify it. - Return the file name of the psymtab for included file FILE_INDEX - in line header LH of PST. + Return the file name of the psymtab for the given file_entry. COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown. If space for the result is malloc'd, *NAME_HOLDER will be set. Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename. */ static const char * -psymtab_include_file_name (const struct line_header *lh, int file_index, +psymtab_include_file_name (const struct line_header *lh, const file_entry &fe, const struct partial_symtab *pst, const char *comp_dir, gdb::unique_xmalloc_ptr *name_holder) { - const file_entry &fe = lh->file_names[file_index]; const char *include_name = fe.name; const char *include_name_to_compare = include_name; const char *pst_filename; @@ -20816,8 +20880,8 @@ private: and initialized according to the DWARF spec. */ unsigned char m_op_index = 0; - /* The line table index (1-based) of the current file. */ - file_name_index m_file = (file_name_index) 1; + /* The line table index of the current file. */ + file_name_index m_file = 1; unsigned int m_line = 1; /* These are initialized in the constructor. */ @@ -21009,7 +21073,7 @@ lnp_state_machine::record_line (bool end_sequence) fprintf_unfiltered (gdb_stdlog, "Processing actual line %u: file %u," " address %s, is_stmt %u, discrim %u\n", - m_line, to_underlying (m_file), + m_line, m_file, paddress (m_gdbarch, m_address), m_is_stmt, m_discriminator); } @@ -21348,17 +21412,15 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, if (decode_for_pst_p) { - int file_index; - /* Now that we're done scanning the Line Header Program, we can create the psymtab of each included file. */ - for (file_index = 0; file_index < lh->file_names.size (); file_index++) - if (lh->file_names[file_index].included_p == 1) + for (auto &file_entry : lh->file_names ()) + if (file_entry.included_p == 1) { gdb::unique_xmalloc_ptr name_holder; const char *include_name = - psymtab_include_file_name (lh, file_index, pst, comp_dir, - &name_holder); + psymtab_include_file_name (lh, file_entry, pst, + comp_dir, &name_holder); if (include_name != NULL) dwarf2_create_include_psymtab (include_name, pst, objfile); } @@ -21370,14 +21432,10 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, line numbers). */ buildsym_compunit *builder = cu->get_builder (); struct compunit_symtab *cust = builder->get_compunit_symtab (); - int i; - for (i = 0; i < lh->file_names.size (); i++) + for (auto &fe : lh->file_names ()) { - file_entry &fe = lh->file_names[i]; - dwarf2_start_subfile (cu, fe.name, fe.include_dir (lh)); - if (builder->get_current_subfile ()->symtab == NULL) { builder->get_current_subfile ()->symtab @@ -21573,7 +21631,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu, /* Cache this symbol's name and the name's demangled form (if any). */ SYMBOL_SET_LANGUAGE (sym, cu->language, &objfile->objfile_obstack); linkagename = dwarf2_physname (name, die, cu); - SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), 0, objfile); + SYMBOL_SET_NAMES (sym, linkagename, false, objfile); /* Fortran does not have mangling standard and the mangling does differ between gfortran, iFort etc. */ @@ -24182,17 +24240,17 @@ file_file_name (int file, struct line_header *lh) { /* Is the file number a valid index into the line header's file name table? Remember that file numbers start with one, not zero. */ - if (1 <= file && file <= lh->file_names.size ()) + if (lh->is_valid_file_index (file)) { - const file_entry &fe = lh->file_names[file - 1]; + const file_entry *fe = lh->file_name_at (file); - if (!IS_ABSOLUTE_PATH (fe.name)) + if (!IS_ABSOLUTE_PATH (fe->name)) { - const char *dir = fe.include_dir (lh); + const char *dir = fe->include_dir (lh); if (dir != NULL) - return concat (dir, SLASH_STRING, fe.name, (char *) NULL); + return concat (dir, SLASH_STRING, fe->name, (char *) NULL); } - return xstrdup (fe.name); + return xstrdup (fe->name); } else { @@ -24220,7 +24278,7 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir) { /* Is the file number a valid index into the line header's file name table? Remember that file numbers start with one, not zero. */ - if (1 <= file && file <= lh->file_names.size ()) + if (lh->is_valid_file_index (file)) { char *relative = file_file_name (file, lh); @@ -25622,7 +25680,7 @@ per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs) table if necessary. For convenience, return TYPE. The DIEs reading must have careful ordering to: - * Not cause infite loops trying to read in DIEs as a prerequisite for + * Not cause infinite loops trying to read in DIEs as a prerequisite for reading current DIE. * Not trying to dereference contents of still incompletely read in types while reading in other DIEs.