extern struct cmd_list_element *set_dwarf_cmdlist;
extern struct cmd_list_element *show_dwarf_cmdlist;
-extern bool dwarf_always_disassemble;
-
struct tu_stats
{
int nr_uniq_abbrev_tables;
enum language pretend_language;
};
-/* Collection of data recorded per objfile.
- This hangs off of dwarf2_objfile_data_key. */
+/* Some DWARF data can be shared across objfiles who share the same BFD,
+ this data is stored in this object.
-struct dwarf2_per_objfile
+ Two dwarf2_per_objfile objects representing objfiles sharing the same BFD
+ will point to the same instance of dwarf2_per_bfd, unless the BFD requires
+ relocation. */
+
+struct dwarf2_per_bfd
{
- /* Construct a dwarf2_per_objfile for OBJFILE. NAMES points to the
+ /* Construct a dwarf2_per_bfd for OBFD. NAMES points to the
dwarf2 section names, or is NULL if the standard ELF names are
used. CAN_COPY is true for formats where symbol
interposition is possible and so symbol values must follow copy
relocation rules. */
- dwarf2_per_objfile (struct objfile *objfile,
- const dwarf2_debug_sections *names,
- bool can_copy);
+ dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names, bool can_copy);
- ~dwarf2_per_objfile ();
+ ~dwarf2_per_bfd ();
- DISABLE_COPY_AND_ASSIGN (dwarf2_per_objfile);
+ DISABLE_COPY_AND_ASSIGN (dwarf2_per_bfd);
/* Return the CU/TU given its index.
This is intended for loops like:
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_units); ++i)
+ for (i = 0; i < (dwarf2_per_bfd->n_comp_units
+ + dwarf2_per_bfd->n_type_units); ++i)
{
- dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
+ dwarf2_per_cu_data *per_cu = dwarf2_per_bfd->get_cutu (i);
...;
}
/* Free all cached compilation units. */
void free_cached_comp_units ();
+
+ /* A convenience function to allocate a dwarf2_per_cu_data. The
+ returned object has its "index" field set properly. The object
+ is allocated on the dwarf2_per_bfd obstack. */
+ dwarf2_per_cu_data *allocate_per_cu ();
+
+ /* A convenience function to allocate a signatured_type. The
+ returned object has its "index" field set properly. The object
+ is allocated on the dwarf2_per_bfd obstack. */
+ signatured_type *allocate_signatured_type ();
+
+ /* Return the number of partial symtabs allocated with allocate_per_cu
+ and allocate_signatured_type so far. */
+ int num_psymtabs () const
+ { return m_num_psymtabs; }
+
private:
/* This function is mapped across the sections and remembers the
offset and size of each of the debugging sections we are
const dwarf2_debug_sections &names);
public:
+ /* Objects that can be shared across objfiles are stored in this
+ obstack or on the psymtab obstack, while objects that are
+ objfile-specific are stored on the objfile obstack. */
+ auto_obstack obstack;
+
dwarf2_section_info info {};
dwarf2_section_info abbrev {};
dwarf2_section_info line {};
std::vector<dwarf2_section_info> types;
- /* Back link. */
- struct objfile *objfile = NULL;
-
/* Table of all the compilation units. This is used to locate
the target compilation unit of a particular reference. */
std::vector<dwarf2_per_cu_data *> all_comp_units;
/* Table of struct type_unit_group objects.
The hash key is the DW_AT_stmt_list value. */
- htab_t type_unit_groups {};
+ htab_up type_unit_groups;
/* A table mapping .debug_types signatures to its signatured_type entry.
This is NULL if the .debug_types section hasn't been read in yet. */
- htab_t signatured_types {};
+ htab_up signatured_types;
/* Type unit statistics, to see how well the scaling improvements
are doing. */
sorted all the TUs into "type unit groups", grouped by their
DW_AT_stmt_list value. Therefore the only sharing done here is with a
CU and its associated TU group if there is one. */
- htab_t quick_file_names_table {};
+ htab_up quick_file_names_table;
/* Set during partial symbol reading, to prevent queueing of full
symbols. */
bool reading_partial_symbols = false;
- /* Table mapping type DIEs to their struct type *.
- This is NULL if not allocated yet.
- The mapping is done via (CU/TU + DIE offset) -> type. */
- htab_t die_type_hash {};
-
/* The CUs we recently read. */
std::vector<dwarf2_per_cu_data *> just_read_cus;
/* Table containing line_header indexed by offset and offset_in_dwz. */
- htab_t line_header_hash {};
+ htab_up line_header_hash;
/* Table containing all filenames. This is an optional because the
table is lazily constructed on first access. */
/* CUs that are queued to be read. */
std::queue<dwarf2_queue_item> queue;
+
+private:
+
+ /* The total number of per_cu and signatured_type objects that have
+ been created so far for this reader. */
+ size_t m_num_psymtabs = 0;
};
-/* Get the dwarf2_per_objfile associated to OBJFILE. */
+/* Collection of data recorded per objfile.
+ This hangs off of dwarf2_objfile_data_key.
-dwarf2_per_objfile *get_dwarf2_per_objfile (struct objfile *objfile);
+ Some DWARF data cannot (currently) be shared across objfiles. Such
+ data is stored in this object. */
-/* A partial symtab specialized for DWARF. */
-struct dwarf2_psymtab : public standard_psymtab
+struct dwarf2_per_objfile
{
- dwarf2_psymtab (const char *filename, struct objfile *objfile)
- : standard_psymtab (filename, objfile)
+ dwarf2_per_objfile (struct objfile *objfile, dwarf2_per_bfd *per_bfd)
+ : objfile (objfile), per_bfd (per_bfd)
+ {}
+
+ /* Return pointer to string at .debug_line_str offset as read from BUF.
+ BUF is assumed to be in a compilation unit described by CU_HEADER.
+ Return *BYTES_READ_PTR count of bytes read from BUF. */
+ const char *read_line_string (const gdb_byte *buf,
+ const struct comp_unit_head *cu_header,
+ unsigned int *bytes_read_ptr);
+
+ /* Resize the M_SYMTABS vector to the needed size (the number of partial
+ symtabs allocated by the per-bfd). */
+ void resize_symtabs ()
{
+ /* The symtabs vector should only grow, not shrink. */
+ gdb_assert (per_bfd->num_psymtabs () >= m_symtabs.size ());
+
+ m_symtabs.resize (per_bfd->num_psymtabs ());
}
+ /* Return true if the symtab corresponding to PER_CU has been set,
+ false otherwise. */
+ bool symtab_set_p (const dwarf2_per_cu_data *per_cu) const;
+
+ /* Return the compunit_symtab associated to PER_CU, if it has been created. */
+ compunit_symtab *get_symtab (const dwarf2_per_cu_data *per_cu) const;
+
+ /* Set the compunit_symtab associated to PER_CU. */
+ void set_symtab (const dwarf2_per_cu_data *per_cu, compunit_symtab *symtab);
+
+ /* Back link. */
+ struct objfile *objfile;
+
+ /* Pointer to the data that is (possibly) shared between this objfile and
+ other objfiles backed by the same BFD. */
+ struct dwarf2_per_bfd *per_bfd;
+
+ /* Table mapping type DIEs to their struct type *.
+ This is nullptr if not allocated yet.
+ The mapping is done via (CU/TU + DIE offset) -> type. */
+ htab_up die_type_hash;
+
+private:
+ /* Hold the corresponding compunit_symtab for each CU or TU. This
+ is indexed by dwarf2_per_cu_data::index. A NULL value means
+ that the CU/TU has not been expanded yet. */
+ std::vector<compunit_symtab *> m_symtabs;
+};
+
+/* Get the dwarf2_per_objfile associated to OBJFILE. */
+
+dwarf2_per_objfile *get_dwarf2_per_objfile (struct objfile *objfile);
+
+/* A partial symtab specialized for DWARF. */
+struct dwarf2_psymtab : public partial_symtab
+{
dwarf2_psymtab (const char *filename, struct objfile *objfile,
- CORE_ADDR addr)
- : standard_psymtab (filename, objfile, addr)
+ dwarf2_per_cu_data *per_cu)
+ : partial_symtab (filename, objfile, 0),
+ per_cu_data (per_cu)
{
}
void read_symtab (struct objfile *) override;
void expand_psymtab (struct objfile *) override;
+ bool readin_p (struct objfile *) const override;
+ compunit_symtab *get_compunit_symtab (struct objfile *) const override;
struct dwarf2_per_cu_data *per_cu_data;
};
This flag is only valid if is_debug_types is true. */
unsigned int tu_read : 1;
+ /* Our index in the unshared "symtabs" vector. */
+ unsigned index;
+
/* The section this CU/TU lives in.
If the DIE refers to a DWO file, this is always the original die,
not the DWO file. */
dummy CUs (a CU header, but nothing else). */
struct dwarf2_cu *cu;
+ /* The unit type of this CU. */
+ enum dwarf_unit_type unit_type;
+
+ /* The language of this CU. */
+ enum language lang;
+
/* The corresponding dwarf2_per_objfile. */
struct dwarf2_per_objfile *dwarf2_per_objfile;
- /* When dwarf2_per_objfile->using_index is true, the 'quick' field
+ /* Backlink to the owner of this. */
+ dwarf2_per_bfd *per_bfd;
+
+ /* When dwarf2_per_bfd::using_index is true, the 'quick' field
is active. Otherwise, the 'psymtab' field is active. */
union
{
struct dwarf2_per_cu_quick_data *quick;
} v;
+ /* The CUs we import using DW_TAG_imported_unit. This is filled in
+ while reading psymtabs, used to compute the psymtab dependencies,
+ and then cleared. Then it is filled in again while reading full
+ symbols, and only deleted when the objfile is destroyed.
+
+ This is also used to work around a difference between the way gold
+ generates .gdb_index version <=7 and the way gdb does. Arguably this
+ is a gold bug. For symbols coming from TUs, gold records in the index
+ the CU that includes the TU instead of the TU itself. This breaks
+ dw2_lookup_symbol: It assumes that if the index says symbol X lives
+ in CU/TU Y, then one need only expand Y and a subsequent lookup in Y
+ will find X. Alas TUs live in their own symtab, so after expanding CU Y
+ we need to look in TU Z to find X. Fortunately, this is akin to
+ DW_TAG_imported_unit, so we just use the same mechanism: For
+ .gdb_index version <=7 this also records the TUs that the CU referred
+ to. Concurrently with this change gdb was modified to emit version 8
+ indices so we only pay a price for gold generated indices.
+ http://sourceware.org/bugzilla/show_bug.cgi?id=15021.
+
+ This currently needs to be a public member due to how
+ dwarf2_per_cu_data is allocated and used. Ideally in future things
+ could be refactored to make this private. Until then please try to
+ avoid direct access to this member, and instead use the helper
+ functions above. */
+ std::vector <dwarf2_per_cu_data *> *imported_symtabs;
+
/* Return true of IMPORTED_SYMTABS is empty or not yet allocated. */
bool imported_symtabs_empty () const
{
imported_symtabs = nullptr;
}
- /* The CUs we import using DW_TAG_imported_unit. This is filled in
- while reading psymtabs, used to compute the psymtab dependencies,
- and then cleared. Then it is filled in again while reading full
- symbols, and only deleted when the objfile is destroyed.
-
- This is also used to work around a difference between the way gold
- generates .gdb_index version <=7 and the way gdb does. Arguably this
- is a gold bug. For symbols coming from TUs, gold records in the index
- the CU that includes the TU instead of the TU itself. This breaks
- dw2_lookup_symbol: It assumes that if the index says symbol X lives
- in CU/TU Y, then one need only expand Y and a subsequent lookup in Y
- will find X. Alas TUs live in their own symtab, so after expanding CU Y
- we need to look in TU Z to find X. Fortunately, this is akin to
- DW_TAG_imported_unit, so we just use the same mechanism: For
- .gdb_index version <=7 this also records the TUs that the CU referred
- to. Concurrently with this change gdb was modified to emit version 8
- indices so we only pay a price for gold generated indices.
- http://sourceware.org/bugzilla/show_bug.cgi?id=15021.
+ /* Return the OBJFILE associated with this compilation unit. If
+ this compilation unit came from a separate debuginfo file, then
+ the master objfile is returned. */
+ struct objfile *objfile () const;
+
+ /* Return the address size given in the compilation unit header for
+ this CU. */
+ int addr_size () const;
+
+ /* Return the offset size given in the compilation unit header for
+ this CU. */
+ int offset_size () const;
+
+ /* Return the DW_FORM_ref_addr size given in the compilation unit
+ header for this CU. */
+ int ref_addr_size () const;
+
+ /* Return the text offset of the CU. The returned offset comes from
+ this CU's objfile. If this objfile came from a separate
+ debuginfo file, then the offset may be different from the
+ corresponding offset in the parent objfile. */
+ CORE_ADDR text_offset () const;
+
+ /* 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 SIZE_IN_BYTES bytes in size and return it.
+ UNSIGNED_P controls if the integer is unsigned or not. */
+ struct type *int_type (int size_in_bytes, bool unsigned_p) 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;
+
+ /* Return DWARF version number of this CU. */
+ short version () const
+ {
+ return dwarf_version;
+ }
- This currently needs to be a public member due to how
- dwarf2_per_cu_data is allocated and used. Ideally in future things
- could be refactored to make this private. Until then please try to
- avoid direct access to this member, and instead use the helper
- functions above. */
- std::vector <dwarf2_per_cu_data *> *imported_symtabs;
+ /* A type unit group has a per_cu object that is recognized by
+ having no section. */
+ bool type_unit_group_p () const
+ {
+ return section == nullptr;
+ }
};
/* Entry in the signatured_types hash table. */
struct dwo_unit *dwo_unit;
};
-/* This represents a '.dwz' file. */
+/* Open the separate '.dwz' debug file, if needed. Return NULL if
+ there is no .gnu_debugaltlink section in the file. Error if there
+ is such a section but the file cannot be found. */
-struct dwz_file
-{
- dwz_file (gdb_bfd_ref_ptr &&bfd)
- : dwz_bfd (std::move (bfd))
- {
- }
+extern struct dwz_file *dwarf2_get_dwz_file
+ (struct dwarf2_per_objfile *dwarf2_per_objfile);
- const char *filename () const
- {
- return bfd_get_filename (this->dwz_bfd.get ());
- }
+/* Return the type of the DIE at DIE_OFFSET in the CU named by
+ PER_CU. */
- /* A dwz file can only contain a few sections. */
- struct dwarf2_section_info abbrev {};
- struct dwarf2_section_info info {};
- struct dwarf2_section_info str {};
- struct dwarf2_section_info line {};
- struct dwarf2_section_info macro {};
- struct dwarf2_section_info gdb_index {};
- struct dwarf2_section_info debug_names {};
+struct type *dwarf2_get_die_type (cu_offset die_offset,
+ struct dwarf2_per_cu_data *per_cu);
- /* The dwz's BFD. */
- gdb_bfd_ref_ptr dwz_bfd;
+/* Given an index in .debug_addr, fetch the value.
+ NOTE: This can be called during dwarf expression evaluation,
+ long after the debug information has been read, and thus per_cu->cu
+ may no longer exist. */
- /* If we loaded the index from an external file, this contains the
- resources associated to the open file, memory mapping, etc. */
- std::unique_ptr<index_cache_resource> index_cache_res;
-};
+CORE_ADDR dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
+ unsigned int addr_index);
-/* Open the separate '.dwz' debug file, if needed. Return NULL if
- there is no .gnu_debugaltlink section in the file. Error if there
- is such a section but the file cannot be found. */
+/* Return DWARF block referenced by DW_AT_location of DIE at SECT_OFF at PER_CU.
+ Returned value is intended for DW_OP_call*. Returned
+ dwarf2_locexpr_baton->data has lifetime of
+ PER_CU->DWARF2_PER_OBJFILE->OBJFILE. */
-extern struct dwz_file *dwarf2_get_dwz_file
- (struct dwarf2_per_objfile *dwarf2_per_objfile);
+struct dwarf2_locexpr_baton dwarf2_fetch_die_loc_sect_off
+ (sect_offset sect_off, dwarf2_per_cu_data *per_cu,
+ CORE_ADDR (*get_frame_pc) (void *baton),
+ void *baton, bool resolve_abstract_p = false);
+
+/* Like dwarf2_fetch_die_loc_sect_off, but take a CU
+ offset. */
+
+struct dwarf2_locexpr_baton dwarf2_fetch_die_loc_cu_off
+ (cu_offset offset_in_cu, dwarf2_per_cu_data *per_cu,
+ CORE_ADDR (*get_frame_pc) (void *baton),
+ void *baton);
+
+/* If the DIE at SECT_OFF in PER_CU has a DW_AT_const_value, return a
+ pointer to the constant bytes and set LEN to the length of the
+ data. If memory is needed, allocate it on OBSTACK. If the DIE
+ does not have a DW_AT_const_value, return NULL. */
+
+extern const gdb_byte *dwarf2_fetch_constant_bytes
+ (sect_offset sect_off, dwarf2_per_cu_data *per_cu, obstack *obstack,
+ LONGEST *len);
+
+/* Return the type of the die at SECT_OFF in PER_CU. Return NULL if no
+ valid type for this die is found. */
+
+struct type *dwarf2_fetch_die_type_sect_off
+ (sect_offset sect_off, dwarf2_per_cu_data *per_cu);
+
+/* When non-zero, dump line number entries as they are read in. */
+extern unsigned int dwarf_line_debug;
#endif /* DWARF2READ_H */