-/* Return the fully scoped name associated with PDI, from compilation unit
- CU. The result will be allocated with malloc. */
-
-static gdb::unique_xmalloc_ptr<char>
-partial_die_full_name (struct partial_die_info *pdi,
- struct dwarf2_cu *cu)
-{
- const char *parent_scope;
-
- /* If this is a template instantiation, we can not work out the
- template arguments from partial DIEs. So, unfortunately, we have
- to go through the full DIEs. At least any work we do building
- types here will be reused if full symbols are loaded later. */
- if (pdi->has_template_arguments)
- {
- pdi->fixup (cu);
-
- if (pdi->name (cu) != NULL && strchr (pdi->name (cu), '<') == NULL)
- {
- struct die_info *die;
- struct attribute attr;
- struct dwarf2_cu *ref_cu = cu;
-
- /* DW_FORM_ref_addr is using section offset. */
- attr.name = (enum dwarf_attribute) 0;
- attr.form = DW_FORM_ref_addr;
- attr.u.unsnd = to_underlying (pdi->sect_off);
- die = follow_die_ref (NULL, &attr, &ref_cu);
-
- return make_unique_xstrdup (dwarf2_full_name (NULL, die, ref_cu));
- }
- }
-
- parent_scope = partial_die_parent_scope (pdi, cu);
- if (parent_scope == NULL)
- return NULL;
- else
- return gdb::unique_xmalloc_ptr<char> (typename_concat (NULL, parent_scope,
- pdi->name (cu),
- 0, cu));
-}
-
-static void
-add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
-{
- dwarf2_per_objfile *per_objfile = cu->per_objfile;
- struct objfile *objfile = per_objfile->objfile;
- struct gdbarch *gdbarch = objfile->arch ();
- CORE_ADDR addr = 0;
- const char *actual_name = NULL;
- CORE_ADDR baseaddr;
-
- baseaddr = objfile->text_section_offset ();
-
- gdb::unique_xmalloc_ptr<char> built_actual_name
- = partial_die_full_name (pdi, cu);
- if (built_actual_name != NULL)
- actual_name = built_actual_name.get ();
-
- if (actual_name == NULL)
- actual_name = pdi->name (cu);
-
- partial_symbol psymbol;
- memset (&psymbol, 0, sizeof (psymbol));
- psymbol.ginfo.set_language (cu->per_cu->lang,
- &objfile->objfile_obstack);
- psymbol.ginfo.set_section_index (-1);
-
- /* The code below indicates that the psymbol should be installed by
- setting this. */
- gdb::optional<psymbol_placement> where;
-
- switch (pdi->tag)
- {
- case DW_TAG_inlined_subroutine:
- case DW_TAG_subprogram:
- addr = (gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr)
- - baseaddr);
- if (pdi->is_external
- || cu->per_cu->lang == language_ada
- || (cu->per_cu->lang == language_fortran
- && pdi->die_parent != NULL
- && pdi->die_parent->tag == DW_TAG_subprogram))
- {
- /* Normally, only "external" DIEs are part of the global scope.
- 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. */
- where = psymbol_placement::GLOBAL;
- }
- else
- where = psymbol_placement::STATIC;
-
- psymbol.domain = VAR_DOMAIN;
- psymbol.aclass = LOC_BLOCK;
- psymbol.ginfo.set_section_index (SECT_OFF_TEXT (objfile));
- psymbol.ginfo.value.address = addr;
-
- if (pdi->main_subprogram && actual_name != NULL)
- set_objfile_main_name (objfile, actual_name, cu->per_cu->lang);
- break;
- case DW_TAG_constant:
- psymbol.domain = VAR_DOMAIN;
- psymbol.aclass = LOC_STATIC;
- where = (pdi->is_external
- ? psymbol_placement::GLOBAL
- : psymbol_placement::STATIC);
- break;
- case DW_TAG_variable:
- if (pdi->d.locdesc)
- addr = decode_locdesc (pdi->d.locdesc, cu);
-
- if (pdi->d.locdesc
- && addr == 0
- && !per_objfile->per_bfd->has_section_at_zero)
- {
- /* A global or static variable may also have been stripped
- out by the linker if unused, in which case its address
- will be nullified; do not add such variables into partial
- symbol table then. */
- }
- else if (pdi->is_external)
- {
- /* Global Variable.
- Don't enter into the minimal symbol tables as there is
- a minimal symbol table entry from the ELF symbols already.
- Enter into partial symbol table if it has a location
- descriptor or a type.
- If the location descriptor is missing, new_symbol will create
- a LOC_UNRESOLVED symbol, the address of the variable will then
- be determined from the minimal symbol table whenever the variable
- is referenced.
- The address for the partial symbol table entry is not
- used by GDB, but it comes in handy for debugging partial symbol
- table building. */
-
- if (pdi->d.locdesc || pdi->has_type)
- {
- psymbol.domain = VAR_DOMAIN;
- psymbol.aclass = LOC_STATIC;
- psymbol.ginfo.set_section_index (SECT_OFF_TEXT (objfile));
- psymbol.ginfo.value.address = addr;
- where = psymbol_placement::GLOBAL;
- }
- }
- else
- {
- int has_loc = pdi->d.locdesc != NULL;
-
- /* Static Variable. Skip symbols whose value we cannot know (those
- without location descriptors or constant values). */
- if (!has_loc && !pdi->has_const_value)
- return;
-
- psymbol.domain = VAR_DOMAIN;
- psymbol.aclass = LOC_STATIC;
- psymbol.ginfo.set_section_index (SECT_OFF_TEXT (objfile));
- if (has_loc)
- psymbol.ginfo.value.address = addr;
- where = psymbol_placement::STATIC;
- }
- break;
- case DW_TAG_array_type:
- case DW_TAG_typedef:
- case DW_TAG_base_type:
- case DW_TAG_subrange_type:
- psymbol.domain = VAR_DOMAIN;
- psymbol.aclass = LOC_TYPEDEF;
- where = psymbol_placement::STATIC;
- break;
- case DW_TAG_imported_declaration:
- case DW_TAG_namespace:
- psymbol.domain = VAR_DOMAIN;
- psymbol.aclass = LOC_TYPEDEF;
- where = psymbol_placement::GLOBAL;
- break;
- case DW_TAG_module:
- /* With Fortran 77 there might be a "BLOCK DATA" module
- available without any name. If so, we skip the module as it
- doesn't bring any value. */
- if (actual_name != nullptr)
- {
- psymbol.domain = MODULE_DOMAIN;
- psymbol.aclass = LOC_TYPEDEF;
- where = psymbol_placement::GLOBAL;
- }
- break;
- case DW_TAG_class_type:
- case DW_TAG_interface_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_enumeration_type:
- /* Skip external references. The DWARF standard says in the section
- about "Structure, Union, and Class Type Entries": "An incomplete
- structure, union or class type is represented by a structure,
- union or class entry that does not have a byte size attribute
- and that has a DW_AT_declaration attribute." */
- if (!pdi->has_byte_size && pdi->is_declaration)
- return;
-
- /* NOTE: carlton/2003-10-07: See comment in new_symbol about
- static vs. global. */
- psymbol.domain = STRUCT_DOMAIN;
- psymbol.aclass = LOC_TYPEDEF;
- where = (cu->per_cu->lang == language_cplus
- ? psymbol_placement::GLOBAL
- : psymbol_placement::STATIC);
- break;
- case DW_TAG_enumerator:
- psymbol.domain = VAR_DOMAIN;
- psymbol.aclass = LOC_CONST;
- where = (cu->per_cu->lang == language_cplus
- ? psymbol_placement::GLOBAL
- : psymbol_placement::STATIC);
- break;
- default:
- break;
- }
-
- if (where.has_value ())
- {
- if (built_actual_name != nullptr)
- actual_name = objfile->intern (actual_name);
- if (pdi->linkage_name == nullptr
- || cu->per_cu->lang == language_ada)
- psymbol.ginfo.set_linkage_name (actual_name);
- else
- {
- psymbol.ginfo.set_demangled_name (actual_name,
- &objfile->objfile_obstack);
- psymbol.ginfo.set_linkage_name (pdi->linkage_name);
- }
- cu->per_cu->v.psymtab->add_psymbol
- (psymbol, *where, per_objfile->per_bfd->partial_symtabs.get (),
- objfile);
- }
-}
-
-/* Read a partial die corresponding to a namespace; also, add a symbol
- corresponding to that namespace to the symbol table. NAMESPACE is
- the name of the enclosing namespace. */
-
-static void
-add_partial_namespace (struct partial_die_info *pdi,
- CORE_ADDR *lowpc, CORE_ADDR *highpc,
- int set_addrmap, struct dwarf2_cu *cu)
-{
- /* Add a symbol for the namespace. */
-
- add_partial_symbol (pdi, cu);
-
- /* Now scan partial symbols in that namespace. */
-
- if (pdi->has_children)
- scan_partial_symbols (pdi->die_child, lowpc, highpc, set_addrmap, cu);
-}
-
-/* Read a partial die corresponding to a Fortran module. */
-
-static void
-add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc,
- CORE_ADDR *highpc, int set_addrmap, struct dwarf2_cu *cu)
-{
- /* Add a symbol for the namespace. */
-
- add_partial_symbol (pdi, cu);
-
- /* Now scan partial symbols in that module. */
-
- if (pdi->has_children)
- scan_partial_symbols (pdi->die_child, lowpc, highpc, set_addrmap, cu);
-}
-
-static int
-dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *,
- dwarf2_psymtab *, dwarf_tag);
-
-/* Read a partial die corresponding to a subprogram or an inlined
- subprogram and create a partial symbol for that subprogram.
- When the CU language allows it, this routine also defines a partial
- symbol for each nested subprogram that this subprogram contains.
- If SET_ADDRMAP is true, record the covered ranges in the addrmap.
- Set *LOWPC and *HIGHPC to the lowest and highest PC values found in PDI.
-
- PDI may also be a lexical block, in which case we simply search
- recursively for subprograms defined inside that lexical block.
- Again, this is only performed when the CU language allows this
- type of definitions. */
-
-static void
-add_partial_subprogram (struct partial_die_info *pdi,
- CORE_ADDR *lowpc, CORE_ADDR *highpc,
- int set_addrmap, struct dwarf2_cu *cu)
-{
- if (pdi->tag == DW_TAG_subprogram || pdi->tag == DW_TAG_inlined_subroutine)
- {
- if (pdi->has_pc_info)
- {
- if (pdi->lowpc < *lowpc)
- *lowpc = pdi->lowpc;
- if (pdi->highpc > *highpc)
- *highpc = pdi->highpc;
- if (set_addrmap)
- {
- struct objfile *objfile = cu->per_objfile->objfile;
- dwarf2_per_bfd *per_bfd = cu->per_objfile->per_bfd;
- struct gdbarch *gdbarch = objfile->arch ();
- CORE_ADDR baseaddr;
- CORE_ADDR this_highpc;
- CORE_ADDR this_lowpc;
-
- baseaddr = objfile->text_section_offset ();
- this_lowpc
- = (gdbarch_adjust_dwarf2_addr (gdbarch,
- pdi->lowpc + baseaddr)
- - baseaddr);
- this_highpc
- = (gdbarch_adjust_dwarf2_addr (gdbarch,
- pdi->highpc + baseaddr)
- - baseaddr);
- addrmap_set_empty (per_bfd->partial_symtabs->psymtabs_addrmap,
- this_lowpc, this_highpc - 1,
- cu->per_cu->v.psymtab);
- }
- }
-
- if (pdi->has_range_info
- && dwarf2_ranges_read (pdi->ranges_offset, &pdi->lowpc, &pdi->highpc,
- cu,
- set_addrmap ? cu->per_cu->v.psymtab : nullptr,
- pdi->tag))
- {
- if (pdi->lowpc < *lowpc)
- *lowpc = pdi->lowpc;
- if (pdi->highpc > *highpc)
- *highpc = pdi->highpc;
- }
-
- if (pdi->has_pc_info || pdi->has_range_info
- || (!pdi->is_external && pdi->may_be_inlined))
- {
- if (!pdi->is_declaration)
- /* Ignore subprogram DIEs that do not have a name, they are
- illegal. Do not emit a complaint at this point, we will
- do so when we convert this psymtab into a symtab. */
- if (pdi->name (cu))
- add_partial_symbol (pdi, cu);
- }
- }
-
- if (! pdi->has_children)
- return;
-
- if (cu->per_cu->lang == language_ada
- || cu->per_cu->lang == language_fortran)
- {
- pdi = pdi->die_child;
- while (pdi != NULL)
- {
- pdi->fixup (cu);
- if (pdi->tag == DW_TAG_subprogram
- || pdi->tag == DW_TAG_inlined_subroutine
- || pdi->tag == DW_TAG_lexical_block)
- add_partial_subprogram (pdi, lowpc, highpc, set_addrmap, cu);
- pdi = pdi->die_sibling;
- }
- }
-}
-
-/* Read a partial die corresponding to an enumeration type. */
-
-static void
-add_partial_enumeration (struct partial_die_info *enum_pdi,
- struct dwarf2_cu *cu)
-{
- struct partial_die_info *pdi;
-
- if (enum_pdi->name (cu) != NULL)
- add_partial_symbol (enum_pdi, cu);
-
- pdi = enum_pdi->die_child;
- while (pdi)
- {
- if (pdi->tag != DW_TAG_enumerator || pdi->raw_name == NULL)
- complaint (_("malformed enumerator DIE ignored"));
- else
- add_partial_symbol (pdi, cu);
- pdi = pdi->die_sibling;
- }
-}
-
-/* Return the initial uleb128 in the die at INFO_PTR. */
-
-static unsigned int
-peek_abbrev_code (bfd *abfd, const gdb_byte *info_ptr)
-{
- unsigned int bytes_read;
-
- return read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
-}
-
-/* Read the initial uleb128 in the die at INFO_PTR in compilation unit
- READER::CU. Use READER::ABBREV_TABLE to lookup any abbreviation.
-
- Return the corresponding abbrev, or NULL if the number is zero (indicating
- an empty DIE). In either case *BYTES_READ will be set to the length of
- the initial number. */
-
-static const struct abbrev_info *
-peek_die_abbrev (const die_reader_specs &reader,
- const gdb_byte *info_ptr, unsigned int *bytes_read)
-{
- dwarf2_cu *cu = reader.cu;
- bfd *abfd = reader.abfd;
- unsigned int abbrev_number
- = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
-
- if (abbrev_number == 0)
- return NULL;
-
- const abbrev_info *abbrev
- = reader.abbrev_table->lookup_abbrev (abbrev_number);
- if (!abbrev)
- {
- error (_("Dwarf Error: Could not find abbrev number %d in %s"
- " at offset %s [in module %s]"),
- abbrev_number, cu->per_cu->is_debug_types ? "TU" : "CU",
- sect_offset_str (cu->header.sect_off), bfd_get_filename (abfd));
- }
-
- return abbrev;
-}
-
-/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER.
- Returns a pointer to the end of a series of DIEs, terminated by an empty
- DIE. Any children of the skipped DIEs will also be skipped. */