aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/cu.h
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2/cu.h')
-rw-r--r--gdb/dwarf2/cu.h270
1 files changed, 270 insertions, 0 deletions
diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h
new file mode 100644
index 0000000..9fb2d61
--- /dev/null
+++ b/gdb/dwarf2/cu.h
@@ -0,0 +1,270 @@
+/* DWARF CU data structure
+
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_DWARF2_CU_H
+#define GDB_DWARF2_CU_H
+
+#include "buildsym.h"
+#include "dwarf2/comp-unit.h"
+#include "gdbsupport/gdb_optional.h"
+
+/* Type used for delaying computation of method physnames.
+ See comments for compute_delayed_physnames. */
+struct delayed_method_info
+{
+ /* The type to which the method is attached, i.e., its parent class. */
+ struct type *type;
+
+ /* The index of the method in the type's function fieldlists. */
+ int fnfield_index;
+
+ /* The index of the method in the fieldlist. */
+ int index;
+
+ /* The name of the DIE. */
+ const char *name;
+
+ /* The DIE associated with this method. */
+ struct die_info *die;
+};
+
+/* Internal state when decoding a particular compilation unit. */
+struct dwarf2_cu
+{
+ explicit dwarf2_cu (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile);
+
+ DISABLE_COPY_AND_ASSIGN (dwarf2_cu);
+
+ /* TU version of handle_DW_AT_stmt_list for read_type_unit_scope.
+ Create the set of symtabs used by this TU, or if this TU is sharing
+ symtabs with another TU and the symtabs have already been created
+ then restore those symtabs in the line header.
+ We don't need the pc/line-number mapping for type units. */
+ void setup_type_unit_groups (struct die_info *die);
+
+ /* Start a symtab for DWARF. NAME, COMP_DIR, LOW_PC are passed to the
+ buildsym_compunit constructor. */
+ struct compunit_symtab *start_symtab (const char *name,
+ const char *comp_dir,
+ CORE_ADDR low_pc);
+
+ /* Reset the builder. */
+ void reset_builder () { m_builder.reset (); }
+
+ /* Return a type that is a generic pointer type, the size of which
+ matches the address size given in the compilation unit header for
+ this CU. */
+ struct type *addr_type () const;
+
+ /* Find an integer type the same size as the address size given in
+ the compilation unit header for this CU. UNSIGNED_P controls if
+ the integer is unsigned or not. */
+ struct type *addr_sized_int_type (bool unsigned_p) const;
+
+ /* The header of the compilation unit. */
+ struct comp_unit_head header {};
+
+ /* Base address of this compilation unit. */
+ gdb::optional<CORE_ADDR> base_address;
+
+ /* The language we are debugging. */
+ enum language language = language_unknown;
+ const struct language_defn *language_defn = nullptr;
+
+ const char *producer = nullptr;
+
+private:
+ /* The symtab builder for this CU. This is only non-NULL when full
+ symbols are being read. */
+ std::unique_ptr<buildsym_compunit> m_builder;
+
+public:
+ /* The generic symbol table building routines have separate lists for
+ file scope symbols and all all other scopes (local scopes). So
+ we need to select the right one to pass to add_symbol_to_list().
+ We do it by keeping a pointer to the correct list in list_in_scope.
+
+ FIXME: The original dwarf code just treated the file scope as the
+ first local scope, and all other local scopes as nested local
+ scopes, and worked fine. Check to see if we really need to
+ distinguish these in buildsym.c. */
+ struct pending **list_in_scope = nullptr;
+
+ /* Hash table holding all the loaded partial DIEs
+ with partial_die->offset.SECT_OFF as hash. */
+ htab_t partial_dies = nullptr;
+
+ /* Storage for things with the same lifetime as this read-in compilation
+ unit, including partial DIEs. */
+ auto_obstack comp_unit_obstack;
+
+ /* Backlink to our per_cu entry. */
+ struct dwarf2_per_cu_data *per_cu;
+
+ /* The dwarf2_per_objfile that owns this. */
+ dwarf2_per_objfile *per_objfile;
+
+ /* How many compilation units ago was this CU last referenced? */
+ int last_used = 0;
+
+ /* A hash table of DIE cu_offset for following references with
+ die_info->offset.sect_off as hash. */
+ htab_t die_hash = nullptr;
+
+ /* Full DIEs if read in. */
+ struct die_info *dies = nullptr;
+
+ /* A set of pointers to dwarf2_per_cu_data objects for compilation
+ units referenced by this one. Only set during full symbol processing;
+ partial symbol tables do not have dependencies. */
+ htab_t dependencies = nullptr;
+
+ /* Header data from the line table, during full symbol processing. */
+ struct line_header *line_header = nullptr;
+ /* Non-NULL if LINE_HEADER is owned by this DWARF_CU. Otherwise,
+ it's owned by dwarf2_per_bfd::line_header_hash. If non-NULL,
+ this is the DW_TAG_compile_unit die for this CU. We'll hold on
+ to the line header as long as this DIE is being processed. See
+ process_die_scope. */
+ die_info *line_header_die_owner = nullptr;
+
+ /* A list of methods which need to have physnames computed
+ after all type information has been read. */
+ std::vector<delayed_method_info> method_list;
+
+ /* To be copied to symtab->call_site_htab. */
+ htab_t call_site_htab = nullptr;
+
+ /* Non-NULL if this CU came from a DWO file.
+ There is an invariant here that is important to remember:
+ Except for attributes copied from the top level DIE in the "main"
+ (or "stub") file in preparation for reading the DWO file
+ (e.g., DW_AT_addr_base), we KISS: there is only *one* CU.
+ Either there isn't a DWO file (in which case this is NULL and the point
+ is moot), or there is and either we're not going to read it (in which
+ case this is NULL) or there is and we are reading it (in which case this
+ is non-NULL). */
+ struct dwo_unit *dwo_unit = nullptr;
+
+ /* The DW_AT_addr_base (DW_AT_GNU_addr_base) attribute if present.
+ Note this value comes from the Fission stub CU/TU's DIE. */
+ gdb::optional<ULONGEST> addr_base;
+
+ /* The DW_AT_GNU_ranges_base attribute, if present.
+
+ This is only relevant in the context of pre-DWARF 5 split units. In this
+ context, there is a .debug_ranges section in the linked executable,
+ containing all the ranges data for all the compilation units. Each
+ skeleton/stub unit has (if needed) a DW_AT_GNU_ranges_base attribute that
+ indicates the base of its contribution to that section. The DW_AT_ranges
+ attributes in the split-unit are of the form DW_FORM_sec_offset and point
+ into the .debug_ranges section of the linked file. However, they are not
+ "true" DW_FORM_sec_offset, because they are relative to the base of their
+ compilation unit's contribution, rather than relative to the beginning of
+ the section. The DW_AT_GNU_ranges_base value must be added to it to make
+ it relative to the beginning of the section.
+
+ Note that the value is zero when we are not in a pre-DWARF 5 split-unit
+ case, so this value can be added without needing to know whether we are in
+ this case or not.
+
+ N.B. If a DW_AT_ranges attribute is found on the DW_TAG_compile_unit in the
+ skeleton/stub, it must not have the base added, as it already points to the
+ right place. And since the DW_TAG_compile_unit DIE in the split-unit can't
+ have a DW_AT_ranges attribute, we can use the
+
+ die->tag != DW_AT_compile_unit
+
+ to determine whether the base should be added or not. */
+ ULONGEST gnu_ranges_base = 0;
+
+ /* The DW_AT_rnglists_base attribute, if present.
+
+ This is used when processing attributes of form DW_FORM_rnglistx in
+ non-split units. Attributes of this form found in a split unit don't
+ use it, as split-unit files have their own non-shared .debug_rnglists.dwo
+ section. */
+ ULONGEST rnglists_base = 0;
+
+ /* The DW_AT_loclists_base attribute if present. */
+ ULONGEST loclist_base = 0;
+
+ /* When reading debug info generated by older versions of rustc, we
+ have to rewrite some union types to be struct types with a
+ variant part. This rewriting must be done after the CU is fully
+ read in, because otherwise at the point of rewriting some struct
+ type might not have been fully processed. So, we keep a list of
+ all such types here and process them after expansion. */
+ std::vector<struct type *> rust_unions;
+
+ /* The DW_AT_str_offsets_base attribute if present. For DWARF 4 version DWO
+ files, the value is implicitly zero. For DWARF 5 version DWO files, the
+ value is often implicit and is the size of the header of
+ .debug_str_offsets section (8 or 4, depending on the address size). */
+ gdb::optional<ULONGEST> str_offsets_base;
+
+ /* Mark used when releasing cached dies. */
+ bool mark : 1;
+
+ /* This CU references .debug_loc. See the symtab->locations_valid field.
+ This test is imperfect as there may exist optimized debug code not using
+ any location list and still facing inlining issues if handled as
+ unoptimized code. For a future better test see GCC PR other/32998. */
+ bool has_loclist : 1;
+
+ /* These cache the results for producer_is_* fields. CHECKED_PRODUCER is true
+ if all the producer_is_* fields are valid. This information is cached
+ because profiling CU expansion showed excessive time spent in
+ producer_is_gxx_lt_4_6. */
+ bool checked_producer : 1;
+ bool producer_is_gxx_lt_4_6 : 1;
+ bool producer_is_gcc_lt_4_3 : 1;
+ bool producer_is_icc : 1;
+ bool producer_is_icc_lt_14 : 1;
+ bool producer_is_codewarrior : 1;
+
+ /* When true, the file that we're processing is known to have
+ debugging info for C++ namespaces. GCC 3.3.x did not produce
+ this information, but later versions do. */
+
+ bool processing_has_namespace_info : 1;
+
+ struct partial_die_info *find_partial_die (sect_offset sect_off);
+
+ /* If this CU was inherited by another CU (via specification,
+ abstract_origin, etc), this is the ancestor CU. */
+ dwarf2_cu *ancestor;
+
+ /* Get the buildsym_compunit for this CU. */
+ buildsym_compunit *get_builder ()
+ {
+ /* If this CU has a builder associated with it, use that. */
+ if (m_builder != nullptr)
+ return m_builder.get ();
+
+ /* Otherwise, search ancestors for a valid builder. */
+ if (ancestor != nullptr)
+ return ancestor->get_builder ();
+
+ return nullptr;
+ }
+};
+
+#endif /* GDB_DWARF2_CU_H */