blob: 769ca91faccf3d4efcf08eaf0a213e0436935760 [file] [log] [blame]
/* DWARF 2 debugging format support for GDB.
Copyright (C) 1994-2024 Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
with the Ada Joint Program Office), and Silicon Graphics, Inc.
Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
based on Fred Fish's (Cygnus Support) implementation of DWARF 1
support.
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/>. */
/* FIXME: Various die-reading functions need to be more careful with
reading off the end of the section. */
#include "dwarf2/read.h"
#include "dwarf2/abbrev.h"
#include "dwarf2/aranges.h"
#include "dwarf2/attribute.h"
#include "dwarf2/comp-unit-head.h"
#include "dwarf2/cu.h"
#include "dwarf2/index-cache.h"
#include "dwarf2/index-common.h"
#include "dwarf2/leb.h"
#include "dwarf2/line-header.h"
#include "dwarf2/dwz.h"
#include "dwarf2/macro.h"
#include "dwarf2/die.h"
#include "dwarf2/read-debug-names.h"
#include "dwarf2/read-gdb-index.h"
#include "dwarf2/sect-names.h"
#include "dwarf2/stringify.h"
#include "dwarf2/public.h"
#include "bfd.h"
#include "elf-bfd.h"
#include "event-top.h"
#include "gdbsupport/task-group.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "objfiles.h"
#include "dwarf2.h"
#include "demangle.h"
#include "gdb-demangle.h"
#include "filenames.h"
#include "language.h"
#include "complaints.h"
#include "dwarf2/expr.h"
#include "dwarf2/loc.h"
#include "cp-support.h"
#include "hashtab.h"
#include "command.h"
#include "cli/cli-cmds.h"
#include "block.h"
#include "addrmap.h"
#include "typeprint.h"
#include "c-lang.h"
#include "go-lang.h"
#include "valprint.h"
#include "gdbcore.h"
#include "gdb_bfd.h"
#include "f-lang.h"
#include "source.h"
#include "build-id.h"
#include "namespace.h"
#include "gdbsupport/function-view.h"
#include <optional>
#include "gdbsupport/underlying.h"
#include "gdbsupport/hash_enum.h"
#include "filename-seen-cache.h"
#include "producer.h"
#include <fcntl.h>
#include <algorithm>
#include <unordered_map>
#include "gdbsupport/selftest.h"
#include "rust-lang.h"
#include "gdbsupport/pathstuff.h"
#include "count-one-bits.h"
#include <unordered_set>
#include "dwarf2/abbrev-cache.h"
#include "cooked-index.h"
#include "gdbsupport/thread-pool.h"
#include "run-on-main-thread.h"
#include "dwarf2/parent-map.h"
#include "dwarf2/error.h"
/* When == 1, print basic high level tracing messages.
When > 1, be more verbose.
This is in contrast to the low level DIE reading of dwarf_die_debug. */
static unsigned int dwarf_read_debug = 0;
/* Print a "dwarf-read" debug statement if dwarf_read_debug is >= 1. */
#define dwarf_read_debug_printf(fmt, ...) \
debug_prefixed_printf_cond (dwarf_read_debug >= 1, "dwarf-read", fmt, \
##__VA_ARGS__)
/* Print a "dwarf-read" debug statement if dwarf_read_debug is >= 2. */
#define dwarf_read_debug_printf_v(fmt, ...) \
debug_prefixed_printf_cond (dwarf_read_debug >= 2, "dwarf-read", fmt, \
##__VA_ARGS__)
/* When non-zero, dump DIEs after they are read in. */
static unsigned int dwarf_die_debug = 0;
/* When non-zero, dump line number entries as they are read in. */
unsigned int dwarf_line_debug = 0;
/* When true, cross-check physname against demangler. */
static bool check_physname = false;
/* This is used to store the data that is always per objfile. */
static const registry<objfile>::key<dwarf2_per_objfile>
dwarf2_objfile_data_key;
/* These are used to store the dwarf2_per_bfd objects.
objfiles having the same BFD, which doesn't require relocations, are going to
share a dwarf2_per_bfd object, which is held in the _bfd_data_key version.
Other objfiles are not going to share a dwarf2_per_bfd with any other
objfiles, so they'll have their own version kept in the _objfile_data_key
version. */
static const registry<bfd>::key<dwarf2_per_bfd> dwarf2_per_bfd_bfd_data_key;
static const registry<objfile>::key<dwarf2_per_bfd>
dwarf2_per_bfd_objfile_data_key;
/* The "aclass" indices for various kinds of computed DWARF symbols. */
static int dwarf2_locexpr_index;
static int dwarf2_loclist_index;
static int ada_imported_index;
static int dwarf2_locexpr_block_index;
static int dwarf2_loclist_block_index;
static int ada_block_index;
static bool producer_is_gas_lt_2_38 (struct dwarf2_cu *cu);
static bool producer_is_gas_ge_2_39 (struct dwarf2_cu *cu);
/* Size of .debug_loclists section header for 32-bit DWARF format. */
#define LOCLIST_HEADER_SIZE32 12
/* Size of .debug_loclists section header for 64-bit DWARF format. */
#define LOCLIST_HEADER_SIZE64 20
/* Size of .debug_rnglists section header for 32-bit DWARF format. */
#define RNGLIST_HEADER_SIZE32 12
/* Size of .debug_rnglists section header for 64-bit DWARF format. */
#define RNGLIST_HEADER_SIZE64 20
/* See dwarf2/read.h. */
dwarf2_per_objfile *
get_dwarf2_per_objfile (struct objfile *objfile)
{
return dwarf2_objfile_data_key.get (objfile);
}
/* Default names of the debugging sections. */
/* Note that if the debugging section has been compressed, it might
have a name like .zdebug_info. */
const struct dwarf2_debug_sections dwarf2_elf_names =
{
{ ".debug_info", ".zdebug_info" },
{ ".debug_abbrev", ".zdebug_abbrev" },
{ ".debug_line", ".zdebug_line" },
{ ".debug_loc", ".zdebug_loc" },
{ ".debug_loclists", ".zdebug_loclists" },
{ ".debug_macinfo", ".zdebug_macinfo" },
{ ".debug_macro", ".zdebug_macro" },
{ ".debug_str", ".zdebug_str" },
{ ".debug_str_offsets", ".zdebug_str_offsets" },
{ ".debug_line_str", ".zdebug_line_str" },
{ ".debug_ranges", ".zdebug_ranges" },
{ ".debug_rnglists", ".zdebug_rnglists" },
{ ".debug_types", ".zdebug_types" },
{ ".debug_addr", ".zdebug_addr" },
{ ".debug_frame", ".zdebug_frame" },
{ ".eh_frame", NULL },
{ ".gdb_index", ".zgdb_index" },
{ ".debug_names", ".zdebug_names" },
{ ".debug_aranges", ".zdebug_aranges" },
23
};
/* List of DWO/DWP sections. */
static const struct dwop_section_names
{
struct dwarf2_section_names abbrev_dwo;
struct dwarf2_section_names info_dwo;
struct dwarf2_section_names line_dwo;
struct dwarf2_section_names loc_dwo;
struct dwarf2_section_names loclists_dwo;
struct dwarf2_section_names macinfo_dwo;
struct dwarf2_section_names macro_dwo;
struct dwarf2_section_names rnglists_dwo;
struct dwarf2_section_names str_dwo;
struct dwarf2_section_names str_offsets_dwo;
struct dwarf2_section_names types_dwo;
struct dwarf2_section_names cu_index;
struct dwarf2_section_names tu_index;
}
dwop_section_names =
{
{ ".debug_abbrev.dwo", ".zdebug_abbrev.dwo" },
{ ".debug_info.dwo", ".zdebug_info.dwo" },
{ ".debug_line.dwo", ".zdebug_line.dwo" },
{ ".debug_loc.dwo", ".zdebug_loc.dwo" },
{ ".debug_loclists.dwo", ".zdebug_loclists.dwo" },
{ ".debug_macinfo.dwo", ".zdebug_macinfo.dwo" },
{ ".debug_macro.dwo", ".zdebug_macro.dwo" },
{ ".debug_rnglists.dwo", ".zdebug_rnglists.dwo" },
{ ".debug_str.dwo", ".zdebug_str.dwo" },
{ ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo" },
{ ".debug_types.dwo", ".zdebug_types.dwo" },
{ ".debug_cu_index", ".zdebug_cu_index" },
{ ".debug_tu_index", ".zdebug_tu_index" },
};
/* local data types */
/* The location list and range list sections (.debug_loclists & .debug_rnglists)
begin with a header, which contains the following information. */
struct loclists_rnglists_header
{
/* A 4-byte or 12-byte length containing the length of the
set of entries for this compilation unit, not including the
length field itself. */
unsigned int length;
/* A 2-byte version identifier. */
short version;
/* A 1-byte unsigned integer containing the size in bytes of an address on
the target system. */
unsigned char addr_size;
/* A 1-byte unsigned integer containing the size in bytes of a segment selector
on the target system. */
unsigned char segment_collector_size;
/* A 4-byte count of the number of offsets that follow the header. */
unsigned int offset_entry_count;
};
/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list.
This includes type_unit_group and quick_file_names. */
struct stmt_list_hash
{
/* The DWO unit this table is from or NULL if there is none. */
struct dwo_unit *dwo_unit;
/* Offset in .debug_line or .debug_line.dwo. */
sect_offset line_sect_off;
};
/* Each element of dwarf2_per_bfd->type_unit_groups is a pointer to
an object of this type. This contains elements of type unit groups
that can be shared across objfiles. The non-shareable parts are in
type_unit_group_unshareable. */
struct type_unit_group
{
/* The data used to construct the hash key. */
struct stmt_list_hash hash {};
};
/* These sections are what may appear in a (real or virtual) DWO file. */
struct dwo_sections
{
struct dwarf2_section_info abbrev;
struct dwarf2_section_info line;
struct dwarf2_section_info loc;
struct dwarf2_section_info loclists;
struct dwarf2_section_info macinfo;
struct dwarf2_section_info macro;
struct dwarf2_section_info rnglists;
struct dwarf2_section_info str;
struct dwarf2_section_info str_offsets;
/* In the case of a virtual DWO file, these two are unused. */
struct dwarf2_section_info info;
std::vector<dwarf2_section_info> types;
};
/* CUs/TUs in DWP/DWO files. */
struct dwo_unit
{
/* Backlink to the containing struct dwo_file. */
struct dwo_file *dwo_file;
/* The "id" that distinguishes this CU/TU.
.debug_info calls this "dwo_id", .debug_types calls this "signature".
Since signatures came first, we stick with it for consistency. */
ULONGEST signature;
/* The section this CU/TU lives in, in the DWO file. */
struct dwarf2_section_info *section;
/* Same as dwarf2_per_cu_data:{sect_off,length} but in the DWO section. */
sect_offset sect_off;
unsigned int length;
/* For types, offset in the type's DIE of the type defined by this TU. */
cu_offset type_offset_in_tu;
};
/* include/dwarf2.h defines the DWP section codes.
It defines a max value but it doesn't define a min value, which we
use for error checking, so provide one. */
enum dwp_v2_section_ids
{
DW_SECT_MIN = 1
};
/* Data for one DWO file.
This includes virtual DWO files (a virtual DWO file is a DWO file as it
appears in a DWP file). DWP files don't really have DWO files per se -
comdat folding of types "loses" the DWO file they came from, and from
a high level view DWP files appear to contain a mass of random types.
However, to maintain consistency with the non-DWP case we pretend DWP
files contain virtual DWO files, and we assign each TU with one virtual
DWO file (generally based on the line and abbrev section offsets -
a heuristic that seems to work in practice). */
struct dwo_file
{
dwo_file () = default;
DISABLE_COPY_AND_ASSIGN (dwo_file);
/* The DW_AT_GNU_dwo_name or DW_AT_dwo_name attribute.
For virtual DWO files the name is constructed from the section offsets
of abbrev,line,loc,str_offsets so that we combine virtual DWO files
from related CU+TUs. */
std::string dwo_name;
/* The DW_AT_comp_dir attribute. */
const char *comp_dir = nullptr;
/* The bfd, when the file is open. Otherwise this is NULL.
This is unused(NULL) for virtual DWO files where we use dwp_file.dbfd. */
gdb_bfd_ref_ptr dbfd;
/* The sections that make up this DWO file.
Remember that for virtual DWO files in DWP V2 or DWP V5, these are virtual
sections (for lack of a better name). */
struct dwo_sections sections {};
/* The CUs in the file.
Each element is a struct dwo_unit. Multiple CUs per DWO are supported as
an extension to handle LLVM's Link Time Optimization output (where
multiple source files may be compiled into a single object/dwo pair). */
htab_up cus;
/* Table of TUs in the file.
Each element is a struct dwo_unit. */
htab_up tus;
};
/* These sections are what may appear in a DWP file. */
struct dwp_sections
{
/* These are used by all DWP versions (1, 2 and 5). */
struct dwarf2_section_info str;
struct dwarf2_section_info cu_index;
struct dwarf2_section_info tu_index;
/* These are only used by DWP version 2 and version 5 files.
In DWP version 1 the .debug_info.dwo, .debug_types.dwo, and other
sections are referenced by section number, and are not recorded here.
In DWP version 2 or 5 there is at most one copy of all these sections,
each section being (effectively) comprised of the concatenation of all of
the individual sections that exist in the version 1 format.
To keep the code simple we treat each of these concatenated pieces as a
section itself (a virtual section?). */
struct dwarf2_section_info abbrev;
struct dwarf2_section_info info;
struct dwarf2_section_info line;
struct dwarf2_section_info loc;
struct dwarf2_section_info loclists;
struct dwarf2_section_info macinfo;
struct dwarf2_section_info macro;
struct dwarf2_section_info rnglists;
struct dwarf2_section_info str_offsets;
struct dwarf2_section_info types;
};
/* These sections are what may appear in a virtual DWO file in DWP version 1.
A virtual DWO file is a DWO file as it appears in a DWP file. */
struct virtual_v1_dwo_sections
{
struct dwarf2_section_info abbrev;
struct dwarf2_section_info line;
struct dwarf2_section_info loc;
struct dwarf2_section_info macinfo;
struct dwarf2_section_info macro;
struct dwarf2_section_info str_offsets;
/* Each DWP hash table entry records one CU or one TU.
That is recorded here, and copied to dwo_unit.section. */
struct dwarf2_section_info info_or_types;
};
/* Similar to virtual_v1_dwo_sections, but for DWP version 2 or 5.
In version 2, the sections of the DWO files are concatenated together
and stored in one section of that name. Thus each ELF section contains
several "virtual" sections. */
struct virtual_v2_or_v5_dwo_sections
{
bfd_size_type abbrev_offset;
bfd_size_type abbrev_size;
bfd_size_type line_offset;
bfd_size_type line_size;
bfd_size_type loc_offset;
bfd_size_type loc_size;
bfd_size_type loclists_offset;
bfd_size_type loclists_size;
bfd_size_type macinfo_offset;
bfd_size_type macinfo_size;
bfd_size_type macro_offset;
bfd_size_type macro_size;
bfd_size_type rnglists_offset;
bfd_size_type rnglists_size;
bfd_size_type str_offsets_offset;
bfd_size_type str_offsets_size;
/* Each DWP hash table entry records one CU or one TU.
That is recorded here, and copied to dwo_unit.section. */
bfd_size_type info_or_types_offset;
bfd_size_type info_or_types_size;
};
/* Contents of DWP hash tables. */
struct dwp_hash_table
{
uint32_t version, nr_columns;
uint32_t nr_units, nr_slots;
const gdb_byte *hash_table, *unit_table;
union
{
struct
{
const gdb_byte *indices;
} v1;
struct
{
/* This is indexed by column number and gives the id of the section
in that column. */
#define MAX_NR_V2_DWO_SECTIONS \
(1 /* .debug_info or .debug_types */ \
+ 1 /* .debug_abbrev */ \
+ 1 /* .debug_line */ \
+ 1 /* .debug_loc */ \
+ 1 /* .debug_str_offsets */ \
+ 1 /* .debug_macro or .debug_macinfo */)
int section_ids[MAX_NR_V2_DWO_SECTIONS];
const gdb_byte *offsets;
const gdb_byte *sizes;
} v2;
struct
{
/* This is indexed by column number and gives the id of the section
in that column. */
#define MAX_NR_V5_DWO_SECTIONS \
(1 /* .debug_info */ \
+ 1 /* .debug_abbrev */ \
+ 1 /* .debug_line */ \
+ 1 /* .debug_loclists */ \
+ 1 /* .debug_str_offsets */ \
+ 1 /* .debug_macro */ \
+ 1 /* .debug_rnglists */)
int section_ids[MAX_NR_V5_DWO_SECTIONS];
const gdb_byte *offsets;
const gdb_byte *sizes;
} v5;
} section_pool;
};
/* Data for one DWP file. */
struct dwp_file
{
dwp_file (const char *name_, gdb_bfd_ref_ptr &&abfd)
: name (name_),
dbfd (std::move (abfd))
{
}
/* Name of the file. */
const char *name;
/* File format version. */
int version = 0;
/* The bfd. */
gdb_bfd_ref_ptr dbfd;
/* Section info for this file. */
struct dwp_sections sections {};
/* Table of CUs in the file. */
const struct dwp_hash_table *cus = nullptr;
/* Table of TUs in the file. */
const struct dwp_hash_table *tus = nullptr;
/* Tables of loaded CUs/TUs. Each entry is a struct dwo_unit *. */
htab_up loaded_cus;
htab_up loaded_tus;
/* Table to map ELF section numbers to their sections.
This is only needed for the DWP V1 file format. */
unsigned int num_sections = 0;
asection **elf_sections = nullptr;
};
/* Struct used to pass misc. parameters to read_die_and_children, et
al. which are used for both .debug_info and .debug_types dies.
All parameters here are unchanging for the life of the call. This
struct exists to abstract away the constant parameters of die reading. */
struct die_reader_specs
{
/* The bfd of die_section. */
bfd *abfd;
/* The CU of the DIE we are parsing. */
struct dwarf2_cu *cu;
/* Non-NULL if reading a DWO file (including one packaged into a DWP). */
struct dwo_file *dwo_file;
/* The section the die comes from.
This is either .debug_info or .debug_types, or the .dwo variants. */
struct dwarf2_section_info *die_section;
/* die_section->buffer. */
const gdb_byte *buffer;
/* The end of the buffer. */
const gdb_byte *buffer_end;
/* The abbreviation table to use when reading the DIEs. */
struct abbrev_table *abbrev_table;
};
/* A subclass of die_reader_specs that holds storage and has complex
constructor and destructor behavior. */
class cutu_reader : public die_reader_specs
{
public:
cutu_reader (dwarf2_per_cu_data *this_cu,
dwarf2_per_objfile *per_objfile,
struct abbrev_table *abbrev_table,
dwarf2_cu *existing_cu,
bool skip_partial,
abbrev_cache *cache = nullptr);
explicit cutu_reader (struct dwarf2_per_cu_data *this_cu,
dwarf2_per_objfile *per_objfile,
struct dwarf2_cu *parent_cu = nullptr,
struct dwo_file *dwo_file = nullptr);
DISABLE_COPY_AND_ASSIGN (cutu_reader);
cutu_reader (cutu_reader &&) = default;
const gdb_byte *info_ptr = nullptr;
struct die_info *comp_unit_die = nullptr;
bool dummy_p = false;
/* Release the new CU, putting it on the chain. This cannot be done
for dummy CUs. */
void keep ();
/* Release the abbrev table, transferring ownership to the
caller. */
abbrev_table_up release_abbrev_table ()
{
return std::move (m_abbrev_table_holder);
}
private:
void init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
dwarf2_per_objfile *per_objfile,
dwarf2_cu *existing_cu);
struct dwarf2_per_cu_data *m_this_cu;
std::unique_ptr<dwarf2_cu> m_new_cu;
/* The ordinary abbreviation table. */
abbrev_table_up m_abbrev_table_holder;
/* The DWO abbreviation table. */
abbrev_table_up m_dwo_abbrev_table;
};
/* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
but this would require a corresponding change in unpack_field_as_long
and friends. */
static int bits_per_byte = 8;
struct variant_part_builder;
/* When reading a variant, we track a bit more information about the
field, and store it in an object of this type. */
struct variant_field
{
int first_field = -1;
int last_field = -1;
/* A variant can contain other variant parts. */
std::vector<variant_part_builder> variant_parts;
/* If we see a DW_TAG_variant, then this will be set if this is the
default branch. */
bool default_branch = false;
/* If we see a DW_AT_discr_value, then this will be the discriminant
value. */
ULONGEST discriminant_value = 0;
/* If we see a DW_AT_discr_list, then this is a pointer to the list
data. */
struct dwarf_block *discr_list_data = nullptr;
};
/* This represents a DW_TAG_variant_part. */
struct variant_part_builder
{
/* The offset of the discriminant field. */
sect_offset discriminant_offset {};
/* Variants that are direct children of this variant part. */
std::vector<variant_field> variants;
/* True if we're currently reading a variant. */
bool processing_variant = false;
};
struct nextfield
{
/* Variant parts need to find the discriminant, which is a DIE
reference. We track the section offset of each field to make
this link. */
sect_offset offset;
struct field field {};
};
struct fnfieldlist
{
const char *name = nullptr;
std::vector<struct fn_field> fnfields;
};
/* The routines that read and process dies for a C struct or C++ class
pass lists of data member fields and lists of member function fields
in an instance of a field_info structure, as defined below. */
struct field_info
{
/* List of data member and baseclasses fields. */
std::vector<struct nextfield> fields;
std::vector<struct nextfield> baseclasses;
/* Member function fieldlist array, contains name of possibly overloaded
member function, number of overloaded member functions and a pointer
to the head of the member function field chain. */
std::vector<struct fnfieldlist> fnfieldlists;
/* typedefs defined inside this class. TYPEDEF_FIELD_LIST contains head of
a NULL terminated list of TYPEDEF_FIELD_LIST_COUNT elements. */
std::vector<struct decl_field> typedef_field_list;
/* Nested types defined by this class and the number of elements in this
list. */
std::vector<struct decl_field> nested_types_list;
/* If non-null, this is the variant part we are currently
reading. */
variant_part_builder *current_variant_part = nullptr;
/* This holds all the top-level variant parts attached to the type
we're reading. */
std::vector<variant_part_builder> variant_parts;
/* Return the total number of fields (including baseclasses). */
int nfields () const
{
return fields.size () + baseclasses.size ();
}
};
/* Loaded secondary compilation units are kept in memory until they
have not been referenced for the processing of this many
compilation units. Set this to zero to disable caching. Cache
sizes of up to at least twenty will improve startup time for
typical inter-CU-reference binaries, at an obvious memory cost. */
static int dwarf_max_cache_age = 5;
static void
show_dwarf_max_cache_age (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
gdb_printf (file, _("The upper bound on the age of cached "
"DWARF compilation units is %s.\n"),
value);
}
/* When true, wait for DWARF reading to be complete. */
static bool dwarf_synchronous = true;
/* "Show" callback for "maint set dwarf synchronous". */
static void
show_dwarf_synchronous (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
gdb_printf (file, _("Whether DWARF reading is synchronous is %s.\n"),
value);
}
/* local function prototypes */
static void dwarf2_find_base_address (struct die_info *die,
struct dwarf2_cu *cu);
static void build_type_psymtabs_reader (cutu_reader *reader,
cooked_index_storage *storage);
static void var_decode_location (struct attribute *attr,
struct symbol *sym,
struct dwarf2_cu *cu);
static unsigned int peek_abbrev_code (bfd *, const gdb_byte *);
static const gdb_byte *read_attribute (const struct die_reader_specs *,
struct attribute *,
const struct attr_abbrev *,
const gdb_byte *,
bool allow_reprocess = true);
/* Note that the default for TAG is chosen because it only matters
when reading the top-level DIE, and that function is careful to
pass the correct tag. */
static void read_attribute_reprocess (const struct die_reader_specs *reader,
struct attribute *attr,
dwarf_tag tag = DW_TAG_padding);
static unrelocated_addr read_addr_index (struct dwarf2_cu *cu,
unsigned int addr_index);
static sect_offset read_abbrev_offset (dwarf2_per_objfile *per_objfile,
dwarf2_section_info *, sect_offset);
static const char *read_indirect_string
(dwarf2_per_objfile *per_objfile, bfd *, const gdb_byte *,
const struct comp_unit_head *, unsigned int *);
static unrelocated_addr read_addr_index_from_leb128 (struct dwarf2_cu *,
const gdb_byte *,
unsigned int *);
static const char *read_dwo_str_index (const struct die_reader_specs *reader,
ULONGEST str_index);
static const char *read_stub_str_index (struct dwarf2_cu *cu,
ULONGEST str_index);
static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
struct dwarf2_cu *);
static const char *dwarf2_string_attr (struct die_info *die, unsigned int name,
struct dwarf2_cu *cu);
static const char *dwarf2_dwo_name (struct die_info *die, struct dwarf2_cu *cu);
static int dwarf2_flag_true_p (struct die_info *die, unsigned name,
struct dwarf2_cu *cu);
static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu);
static struct die_info *die_specification (struct die_info *die,
struct dwarf2_cu **);
static line_header_up dwarf_decode_line_header (sect_offset sect_off,
struct dwarf2_cu *cu,
const char *comp_dir);
static void dwarf_decode_lines (struct line_header *,
struct dwarf2_cu *,
unrelocated_addr, int decode_mapping);
static void dwarf2_start_subfile (dwarf2_cu *cu, const file_entry &fe,
const line_header &lh);
static struct symbol *new_symbol (struct die_info *, struct type *,
struct dwarf2_cu *, struct symbol * = NULL);
static void dwarf2_const_value (const struct attribute *, struct symbol *,
struct dwarf2_cu *);
static void dwarf2_const_value_attr (const struct attribute *attr,
struct type *type,
const char *name,
struct obstack *obstack,
struct dwarf2_cu *cu, LONGEST *value,
const gdb_byte **bytes,
struct dwarf2_locexpr_baton **baton);
static struct type *read_subrange_index_type (struct die_info *die,
struct dwarf2_cu *cu);
static struct type *die_type (struct die_info *, struct dwarf2_cu *);
static int need_gnat_info (struct dwarf2_cu *);
static struct type *die_descriptive_type (struct die_info *,
struct dwarf2_cu *);
static void set_descriptive_type (struct type *, struct die_info *,
struct dwarf2_cu *);
static struct type *die_containing_type (struct die_info *,
struct dwarf2_cu *);
static struct type *lookup_die_type (struct die_info *, const struct attribute *,
struct dwarf2_cu *);
static struct type *read_type_die (struct die_info *, struct dwarf2_cu *);
static struct type *read_type_die_1 (struct die_info *, struct dwarf2_cu *);
static const char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
static gdb::unique_xmalloc_ptr<char> typename_concat (const char *prefix,
const char *suffix,
int physname,
struct dwarf2_cu *cu);
static void read_file_scope (struct die_info *, struct dwarf2_cu *);
static void read_type_unit_scope (struct die_info *, struct dwarf2_cu *);
static void read_func_scope (struct die_info *, struct dwarf2_cu *);
static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *);
static void read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu);
static void read_variable (struct die_info *die, struct dwarf2_cu *cu);
/* Return the .debug_loclists section to use for cu. */
static struct dwarf2_section_info *cu_debug_loc_section (struct dwarf2_cu *cu);
/* Return the .debug_rnglists section to use for cu. */
static struct dwarf2_section_info *cu_debug_rnglists_section
(struct dwarf2_cu *cu, dwarf_tag tag);
/* How dwarf2_get_pc_bounds constructed its *LOWPC and *HIGHPC return
values. Keep the items ordered with increasing constraints compliance. */
enum pc_bounds_kind
{
/* No attribute DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges was found. */
PC_BOUNDS_NOT_PRESENT,
/* Some of the attributes DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges
were present but they do not form a valid range of PC addresses. */
PC_BOUNDS_INVALID,
/* Discontiguous range was found - that is DW_AT_ranges was found. */
PC_BOUNDS_RANGES,
/* Contiguous range was found - DW_AT_low_pc and DW_AT_high_pc were found. */
PC_BOUNDS_HIGH_LOW,
};
static enum pc_bounds_kind dwarf2_get_pc_bounds (struct die_info *,
unrelocated_addr *,
unrelocated_addr *,
struct dwarf2_cu *,
addrmap_mutable *,
void *);
static void get_scope_pc_bounds (struct die_info *,
unrelocated_addr *, unrelocated_addr *,
struct dwarf2_cu *);
static void dwarf2_record_block_ranges (struct die_info *, struct block *,
struct dwarf2_cu *);
static void dwarf2_add_field (struct field_info *, struct die_info *,
struct dwarf2_cu *);
static void dwarf2_attach_fields_to_type (struct field_info *,
struct type *, struct dwarf2_cu *);
static void dwarf2_add_member_fn (struct field_info *,
struct die_info *, struct type *,
struct dwarf2_cu *);
static void dwarf2_attach_fn_fields_to_type (struct field_info *,
struct type *,
struct dwarf2_cu *);
static void process_structure_scope (struct die_info *, struct dwarf2_cu *);
static void read_common_block (struct die_info *, struct dwarf2_cu *);
static void read_namespace (struct die_info *die, struct dwarf2_cu *);
static void read_module (struct die_info *die, struct dwarf2_cu *cu);
static struct using_direct **using_directives (struct dwarf2_cu *cu);
static void read_import_statement (struct die_info *die, struct dwarf2_cu *);
static bool read_alias (struct die_info *die, struct dwarf2_cu *cu);
static struct type *read_module_type (struct die_info *die,
struct dwarf2_cu *cu);
static const char *namespace_name (struct die_info *die,
int *is_anonymous, struct dwarf2_cu *);
static void process_enumeration_scope (struct die_info *, struct dwarf2_cu *);
static bool decode_locdesc (struct dwarf_block *, struct dwarf2_cu *,
CORE_ADDR *addr);
static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
struct dwarf2_cu *);
static struct die_info *read_die_and_siblings_1
(const struct die_reader_specs *, const gdb_byte *, const gdb_byte **,
struct die_info *);
static struct die_info *read_die_and_siblings (const struct die_reader_specs *,
const gdb_byte *info_ptr,
const gdb_byte **new_info_ptr,
struct die_info *parent);
static const gdb_byte *read_full_die_1 (const struct die_reader_specs *,
struct die_info **, const gdb_byte *,
int, bool);
static const gdb_byte *read_toplevel_die (const struct die_reader_specs *,
struct die_info **,
const gdb_byte *,
gdb::array_view<attribute *> = {});
static void process_die (struct die_info *, struct dwarf2_cu *);
static const char *dwarf2_canonicalize_name (const char *, struct dwarf2_cu *,
struct objfile *);
static const char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
static const char *dwarf2_full_name (const char *name,
struct die_info *die,
struct dwarf2_cu *cu);
static const char *dwarf2_physname (const char *name, struct die_info *die,
struct dwarf2_cu *cu);
static struct die_info *dwarf2_extension (struct die_info *die,
struct dwarf2_cu **);
static struct die_info *follow_die_ref_or_sig (struct die_info *,
const struct attribute *,
struct dwarf2_cu **);
static struct die_info *follow_die_ref (struct die_info *,
const struct attribute *,
struct dwarf2_cu **);
static struct die_info *follow_die_sig (struct die_info *,
const struct attribute *,
struct dwarf2_cu **);
static struct type *get_signatured_type (struct die_info *, ULONGEST,
struct dwarf2_cu *);
static struct type *get_DW_AT_signature_type (struct die_info *,
const struct attribute *,
struct dwarf2_cu *);
static void load_full_type_unit (dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile);
static void read_signatured_type (signatured_type *sig_type,
dwarf2_per_objfile *per_objfile);
static int attr_to_dynamic_prop (const struct attribute *attr,
struct die_info *die, struct dwarf2_cu *cu,
struct dynamic_prop *prop, struct type *type);
/* memory allocation interface */
static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *);
static void dwarf_decode_macros (struct dwarf2_cu *, unsigned int, int);
static void fill_in_loclist_baton (struct dwarf2_cu *cu,
struct dwarf2_loclist_baton *baton,
const struct attribute *attr);
static void dwarf2_symbol_mark_computed (const struct attribute *attr,
struct symbol *sym,
struct dwarf2_cu *cu,
int is_block);
static const gdb_byte *skip_one_die (const struct die_reader_specs *reader,
const gdb_byte *info_ptr,
const struct abbrev_info *abbrev,
bool do_skip_children = true);
static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
(sect_offset sect_off, unsigned int offset_in_dwz,
dwarf2_per_bfd *per_bfd);
static void prepare_one_comp_unit (struct dwarf2_cu *cu,
struct die_info *comp_unit_die,
enum language pretend_language);
static struct type *set_die_type (struct die_info *, struct type *,
struct dwarf2_cu *, bool = false);
static void load_full_comp_unit (dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile,
dwarf2_cu *existing_cu,
bool skip_partial,
enum language pretend_language);
static void process_full_comp_unit (dwarf2_cu *cu,
enum language pretend_language);
static void process_full_type_unit (dwarf2_cu *cu,
enum language pretend_language);
static struct type *get_die_type_at_offset (sect_offset,
dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile);
static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
static void queue_comp_unit (dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile,
enum language pretend_language);
static void process_queue (dwarf2_per_objfile *per_objfile);
static bool is_ada_import_or_export (dwarf2_cu *cu, const char *name,
const char *linkagename);
/* Class, the destructor of which frees all allocated queue entries. This
will only have work to do if an error was thrown while processing the
dwarf. If no error was thrown then the queue entries should have all
been processed, and freed, as we went along. */
class dwarf2_queue_guard
{
public:
explicit dwarf2_queue_guard (dwarf2_per_objfile *per_objfile)
: m_per_objfile (per_objfile)
{
gdb_assert (!m_per_objfile->queue.has_value ());
m_per_objfile->queue.emplace ();
}
/* Free any entries remaining on the queue. There should only be
entries left if we hit an error while processing the dwarf. */
~dwarf2_queue_guard ()
{
gdb_assert (m_per_objfile->queue.has_value ());
m_per_objfile->queue.reset ();
}
DISABLE_COPY_AND_ASSIGN (dwarf2_queue_guard);
private:
dwarf2_per_objfile *m_per_objfile;
};
dwarf2_queue_item::~dwarf2_queue_item ()
{
/* Anything still marked queued is likely to be in an
inconsistent state, so discard it. */
if (per_cu->queued)
{
per_objfile->remove_cu (per_cu);
per_cu->queued = 0;
}
}
/* See dwarf2/read.h. */
void
dwarf2_per_cu_data_deleter::operator() (dwarf2_per_cu_data *data)
{
if (data->is_debug_types)
delete static_cast<signatured_type *> (data);
else
delete data;
}
static file_and_directory &find_file_and_directory
(struct die_info *die, struct dwarf2_cu *cu);
static const char *compute_include_file_name
(const struct line_header *lh,
const file_entry &fe,
const file_and_directory &cu_info,
std::string &name_holder);
static htab_up allocate_dwo_unit_table ();
static struct dwo_unit *lookup_dwo_unit_in_dwp
(dwarf2_per_objfile *per_objfile, struct dwp_file *dwp_file,
const char *comp_dir, ULONGEST signature, int is_debug_types);
static struct dwp_file *get_dwp_file (dwarf2_per_objfile *per_objfile);
static struct dwo_unit *lookup_dwo_comp_unit
(dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
ULONGEST signature);
static struct dwo_unit *lookup_dwo_type_unit
(dwarf2_cu *cu, const char *dwo_name, const char *comp_dir);
static void queue_and_load_all_dwo_tus (dwarf2_cu *cu);
/* A unique pointer to a dwo_file. */
typedef std::unique_ptr<struct dwo_file> dwo_file_up;
static void process_cu_includes (dwarf2_per_objfile *per_objfile);
static void check_producer (struct dwarf2_cu *cu);
/* Various complaints about symbol reading that don't abort the process. */
static void
dwarf2_debug_line_missing_file_complaint (void)
{
complaint (_(".debug_line section has line data without a file"));
}
static void
dwarf2_debug_line_missing_end_sequence_complaint (void)
{
complaint (_(".debug_line section has line "
"program sequence without an end"));
}
static void
dwarf2_complex_location_expr_complaint (void)
{
complaint (_("location expression too complex"));
}
static void
dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
int arg3)
{
complaint (_("const value length mismatch for '%s', got %d, expected %d"),
arg1, arg2, arg3);
}
static void
dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2)
{
complaint (_("invalid attribute class or form for '%s' in '%s'"),
arg1, arg2);
}
/* See read.h. */
CORE_ADDR
dwarf2_per_objfile::relocate (unrelocated_addr addr)
{
CORE_ADDR baseaddr = objfile->text_section_offset ();
CORE_ADDR tem = (CORE_ADDR) addr + baseaddr;
return gdbarch_adjust_dwarf2_addr (objfile->arch (), tem);
}
/* Hash function for line_header_hash. */
static hashval_t
line_header_hash (const struct line_header *ofs)
{
return to_underlying (ofs->sect_off) ^ ofs->offset_in_dwz;
}
/* Hash function for htab_create_alloc_ex for line_header_hash. */
static hashval_t
line_header_hash_voidp (const void *item)
{
const struct line_header *ofs = (const struct line_header *) item;
return line_header_hash (ofs);
}
/* Equality function for line_header_hash. */
static int
line_header_eq_voidp (const void *item_lhs, const void *item_rhs)
{
const struct line_header *ofs_lhs = (const struct line_header *) item_lhs;
const struct line_header *ofs_rhs = (const struct line_header *) item_rhs;
return (ofs_lhs->sect_off == ofs_rhs->sect_off
&& ofs_lhs->offset_in_dwz == ofs_rhs->offset_in_dwz);
}
/* See declaration. */
dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
bool can_copy_)
: obfd (obfd),
can_copy (can_copy_)
{
if (names == NULL)
names = &dwarf2_elf_names;
for (asection *sec = obfd->sections; sec != NULL; sec = sec->next)
locate_sections (obfd, sec, *names);
}
dwarf2_per_bfd::~dwarf2_per_bfd ()
{
/* Data from the per-BFD may be needed when finalizing the cooked
index table, so wait here while this happens. */
if (index_table != nullptr)
index_table->wait_completely ();
for (auto &per_cu : all_units)
per_cu->free_cached_file_names ();
/* Everything else should be on this->obstack. */
}
/* See read.h. */
void
dwarf2_per_objfile::remove_all_cus ()
{
gdb_assert (!queue.has_value ());
m_dwarf2_cus.clear ();
}
/* A helper class that calls free_cached_comp_units on
destruction. */
class free_cached_comp_units
{
public:
explicit free_cached_comp_units (dwarf2_per_objfile *per_objfile)
: m_per_objfile (per_objfile)
{
}
~free_cached_comp_units ()
{
m_per_objfile->remove_all_cus ();
}
DISABLE_COPY_AND_ASSIGN (free_cached_comp_units);
private:
dwarf2_per_objfile *m_per_objfile;
};
/* See read.h. */
bool
dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu_data *per_cu) const
{
if (per_cu->index < this->m_symtabs.size ())
return this->m_symtabs[per_cu->index] != nullptr;
return false;
}
/* See read.h. */
compunit_symtab *
dwarf2_per_objfile::get_symtab (const dwarf2_per_cu_data *per_cu) const
{
if (per_cu->index < this->m_symtabs.size ())
return this->m_symtabs[per_cu->index];
return nullptr;
}
/* See read.h. */
void
dwarf2_per_objfile::set_symtab (const dwarf2_per_cu_data *per_cu,
compunit_symtab *symtab)
{
if (per_cu->index >= this->m_symtabs.size ())
this->m_symtabs.resize (per_cu->index + 1);
gdb_assert (this->m_symtabs[per_cu->index] == nullptr);
this->m_symtabs[per_cu->index] = symtab;
}
/* Helper function for dwarf2_initialize_objfile that creates the
per-BFD object. */
static bool
dwarf2_has_info (struct objfile *objfile,
const struct dwarf2_debug_sections *names,
bool can_copy)
{
if (objfile->flags & OBJF_READNEVER)
return false;
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
bool just_created = false;
if (per_objfile == NULL)
{
dwarf2_per_bfd *per_bfd;
/* We can share a "dwarf2_per_bfd" with other objfiles if the
BFD doesn't require relocations.
We don't share with objfiles for which -readnow was requested,
because it would complicate things when loading the same BFD with
-readnow and then without -readnow. */
if (!gdb_bfd_requires_relocations (objfile->obfd.get ())
&& (objfile->flags & OBJF_READNOW) == 0)
{
/* See if one has been created for this BFD yet. */
per_bfd = dwarf2_per_bfd_bfd_data_key.get (objfile->obfd.get ());
if (per_bfd == nullptr)
{
/* No, create it now. */
per_bfd = new dwarf2_per_bfd (objfile->obfd.get (), names,
can_copy);
dwarf2_per_bfd_bfd_data_key.set (objfile->obfd.get (), per_bfd);
just_created = true;
}
}
else
{
/* No sharing possible, create one specifically for this objfile. */
per_bfd = new dwarf2_per_bfd (objfile->obfd.get (), names, can_copy);
dwarf2_per_bfd_objfile_data_key.set (objfile, per_bfd);
just_created = true;
}
per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile, per_bfd);
}
const bool has_info = (!per_objfile->per_bfd->info.is_virtual
&& per_objfile->per_bfd->info.s.section != nullptr
&& !per_objfile->per_bfd->abbrev.is_virtual
&& per_objfile->per_bfd->abbrev.s.section != nullptr);
if (just_created && has_info)
{
/* Try to fetch any potential dwz file early, while still on
the main thread. Also, be sure to do it just once per
BFD, to avoid races. */
try
{
dwarf2_read_dwz_file (per_objfile);
}
catch (const gdb_exception_error &err)
{
warning (_("%s"), err.what ());
}
}
return has_info;
}
/* See declaration. */
void
dwarf2_per_bfd::locate_sections (bfd *abfd, asection *sectp,
const dwarf2_debug_sections &names)
{
flagword aflag = bfd_section_flags (sectp);
if ((aflag & SEC_HAS_CONTENTS) == 0)
{
}
else if (bfd_section_size_insane (abfd, sectp))
{
bfd_size_type size = sectp->size;
warning (_("Discarding section %s which has an invalid size (%s) "
"[in module %s]"),
bfd_section_name (sectp), phex_nz (size, sizeof (size)),
bfd_get_filename (abfd));
}
else if (names.info.matches (sectp->name))
{
this->info.s.section = sectp;
this->info.size = bfd_section_size (sectp);
}
else if (names.abbrev.matches (sectp->name))
{
this->abbrev.s.section = sectp;
this->abbrev.size = bfd_section_size (sectp);
}
else if (names.line.matches (sectp->name))
{
this->line.s.section = sectp;
this->line.size = bfd_section_size (sectp);
}
else if (names.loc.matches (sectp->name))
{
this->loc.s.section = sectp;
this->loc.size = bfd_section_size (sectp);
}
else if (names.loclists.matches (sectp->name))
{
this->loclists.s.section = sectp;
this->loclists.size = bfd_section_size (sectp);
}
else if (names.macinfo.matches (sectp->name))
{
this->macinfo.s.section = sectp;
this->macinfo.size = bfd_section_size (sectp);
}
else if (names.macro.matches (sectp->name))
{
this->macro.s.section = sectp;
this->macro.size = bfd_section_size (sectp);
}
else if (names.str.matches (sectp->name))
{
this->str.s.section = sectp;
this->str.size = bfd_section_size (sectp);
}
else if (names.str_offsets.matches (sectp->name))
{
this->str_offsets.s.section = sectp;
this->str_offsets.size = bfd_section_size (sectp);
}
else if (names.line_str.matches (sectp->name))
{
this->line_str.s.section = sectp;
this->line_str.size = bfd_section_size (sectp);
}
else if (names.addr.matches (sectp->name))
{
this->addr.s.section = sectp;
this->addr.size = bfd_section_size (sectp);
}
else if (names.frame.matches (sectp->name))
{
this->frame.s.section = sectp;
this->frame.size = bfd_section_size (sectp);
}
else if (names.eh_frame.matches (sectp->name))
{
this->eh_frame.s.section = sectp;
this->eh_frame.size = bfd_section_size (sectp);
}
else if (names.ranges.matches (sectp->name))
{
this->ranges.s.section = sectp;
this->ranges.size = bfd_section_size (sectp);
}
else if (names.rnglists.matches (sectp->name))
{
this->rnglists.s.section = sectp;
this->rnglists.size = bfd_section_size (sectp);
}
else if (names.types.matches (sectp->name))
{
struct dwarf2_section_info type_section;
memset (&type_section, 0, sizeof (type_section));
type_section.s.section = sectp;
type_section.size = bfd_section_size (sectp);
this->types.push_back (type_section);
}
else if (names.gdb_index.matches (sectp->name))
{
this->gdb_index.s.section = sectp;
this->gdb_index.size = bfd_section_size (sectp);
}
else if (names.debug_names.matches (sectp->name))
{
this->debug_names.s.section = sectp;
this->debug_names.size = bfd_section_size (sectp);
}
else if (names.debug_aranges.matches (sectp->name))
{
this->debug_aranges.s.section = sectp;
this->debug_aranges.size = bfd_section_size (sectp);
}
if ((bfd_section_flags (sectp) & (SEC_LOAD | SEC_ALLOC))
&& bfd_section_vma (sectp) == 0)
this->has_section_at_zero = true;
}
/* Fill in SECTP, BUFP and SIZEP with section info, given OBJFILE and
SECTION_NAME. */
void
dwarf2_get_section_info (struct objfile *objfile,
enum dwarf2_section_enum sect,
asection **sectp, const gdb_byte **bufp,
bfd_size_type *sizep)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
struct dwarf2_section_info *info;
/* We may see an objfile without any DWARF, in which case we just
return nothing. */
if (per_objfile == NULL)
{
*sectp = NULL;
*bufp = NULL;
*sizep = 0;
return;
}
switch (sect)
{
case DWARF2_DEBUG_FRAME:
info = &per_objfile->per_bfd->frame;
break;
case DWARF2_EH_FRAME:
info = &per_objfile->per_bfd->eh_frame;
break;
default:
gdb_assert_not_reached ("unexpected section");
}
info->read (objfile);
*sectp = info->get_bfd_section ();
*bufp = info->buffer;
*sizep = info->size;
}
/* See dwarf2/read.h. */
void
dwarf2_per_bfd::map_info_sections (struct objfile *objfile)
{
info.read (objfile);
abbrev.read (objfile);
line.read (objfile);
str.read (objfile);
str_offsets.read (objfile);
line_str.read (objfile);
ranges.read (objfile);
rnglists.read (objfile);
addr.read (objfile);
debug_aranges.read (objfile);
for (auto &section : types)
section.read (objfile);
}
/* DWARF quick_symbol_functions support. */
/* TUs can share .debug_line entries, and there can be a lot more TUs than
unique line tables, so we maintain a separate table of all .debug_line
derived entries to support the sharing.
All the quick functions need is the list of file names. We discard the
line_header when we're done and don't need to record it here. */
struct quick_file_names
{
/* The data used to construct the hash key. */
struct stmt_list_hash hash;
/* The number of entries in file_names, real_names. */
unsigned int num_file_names;
/* The CU directory, as given by DW_AT_comp_dir. May be
nullptr. */
const char *comp_dir;
/* The file names from the line table, after being run through
file_full_name. */
const char **file_names;
/* The file names from the line table after being run through
gdb_realpath. These are computed lazily. */
const char **real_names;
};
/* With OBJF_READNOW, the DWARF reader expands all CUs immediately.
It's handy in this case to have an empty implementation of the
quick symbol functions, to avoid special cases in the rest of the
code. */
struct readnow_functions : public dwarf2_base_index_functions
{
void dump (struct objfile *objfile) override
{
}
bool expand_symtabs_matching
(struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
const lookup_name_info *lookup_name,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
block_search_flags search_flags,
domain_search_flags domain) override
{
return true;
}
};
/* Utility hash function for a stmt_list_hash. */
static hashval_t
hash_stmt_list_entry (const struct stmt_list_hash *stmt_list_hash)
{
hashval_t v = 0;
if (stmt_list_hash->dwo_unit != NULL)
v += (uintptr_t) stmt_list_hash->dwo_unit->dwo_file;
v += to_underlying (stmt_list_hash->line_sect_off);
return v;
}
/* Utility equality function for a stmt_list_hash. */
static int
eq_stmt_list_entry (const struct stmt_list_hash *lhs,
const struct stmt_list_hash *rhs)
{
if ((lhs->dwo_unit != NULL) != (rhs->dwo_unit != NULL))
return 0;
if (lhs->dwo_unit != NULL
&& lhs->dwo_unit->dwo_file != rhs->dwo_unit->dwo_file)
return 0;
return lhs->line_sect_off == rhs->line_sect_off;
}
/* Hash function for a quick_file_names. */
static hashval_t
hash_file_name_entry (const void *e)
{
const struct quick_file_names *file_data
= (const struct quick_file_names *) e;
return hash_stmt_list_entry (&file_data->hash);
}
/* Equality function for a quick_file_names. */
static int
eq_file_name_entry (const void *a, const void *b)
{
const struct quick_file_names *ea = (const struct quick_file_names *) a;
const struct quick_file_names *eb = (const struct quick_file_names *) b;
return eq_stmt_list_entry (&ea->hash, &eb->hash);
}
/* See read.h. */
htab_up
create_quick_file_names_table (unsigned int nr_initial_entries)
{
return htab_up (htab_create_alloc (nr_initial_entries,
hash_file_name_entry, eq_file_name_entry,
nullptr, xcalloc, xfree));
}
/* Read in CU (dwarf2_cu object) for PER_CU in the context of PER_OBJFILE. This
function is unrelated to symtabs, symtab would have to be created afterwards.
You should call age_cached_comp_units after processing the CU. */
static dwarf2_cu *
load_cu (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
bool skip_partial)
{
if (per_cu->is_debug_types)
load_full_type_unit (per_cu, per_objfile);
else
load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
skip_partial, language_minimal);
dwarf2_cu *cu = per_objfile->get_cu (per_cu);
if (cu == nullptr)
return nullptr; /* Dummy CU. */
dwarf2_find_base_address (cu->dies, cu);
return cu;
}
/* Read in the symbols for PER_CU in the context of PER_OBJFILE. */
static void
dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile, bool skip_partial)
{
{
/* The destructor of dwarf2_queue_guard frees any entries left on
the queue. After this point we're guaranteed to leave this function
with the dwarf queue empty. */
dwarf2_queue_guard q_guard (per_objfile);
if (!per_objfile->symtab_set_p (per_cu))
{
queue_comp_unit (per_cu, per_objfile, language_minimal);
dwarf2_cu *cu = load_cu (per_cu, per_objfile, skip_partial);
/* If we just loaded a CU from a DWO, and we're working with an index
that may badly handle TUs, load all the TUs in that DWO as well.
http://sourceware.org/bugzilla/show_bug.cgi?id=15021 */
if (!per_cu->is_debug_types
&& cu != NULL
&& cu->dwo_unit != NULL
&& per_objfile->per_bfd->index_table != NULL
&& !per_objfile->per_bfd->index_table->version_check ()
/* DWP files aren't supported yet. */
&& get_dwp_file (per_objfile) == NULL)
queue_and_load_all_dwo_tus (cu);
}
process_queue (per_objfile);
}
/* Age the cache, releasing compilation units that have not
been used recently. */
per_objfile->age_comp_units ();
}
/* Ensure that the symbols for PER_CU have been read in. DWARF2_PER_OBJFILE is
the per-objfile for which this symtab is instantiated.
Returns the resulting symbol table. */
static struct compunit_symtab *
dw2_instantiate_symtab (dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile,
bool skip_partial)
{
if (!per_objfile->symtab_set_p (per_cu))
{
free_cached_comp_units freer (per_objfile);
scoped_restore decrementer = increment_reading_symtab ();
dw2_do_instantiate_symtab (per_cu, per_objfile, skip_partial);
process_cu_includes (per_objfile);
}
return per_objfile->get_symtab (per_cu);
}
/* See read.h. */
dwarf2_per_cu_data_up
dwarf2_per_bfd::allocate_per_cu ()
{
dwarf2_per_cu_data_up result (new dwarf2_per_cu_data);
result->per_bfd = this;
result->index = all_units.size ();
return result;
}
/* See read.h. */
signatured_type_up
dwarf2_per_bfd::allocate_signatured_type (ULONGEST signature)
{
signatured_type_up result (new signatured_type (signature));
result->per_bfd = this;
result->index = all_units.size ();
result->is_debug_types = true;
tu_stats.nr_tus++;
return result;
}
/* See read.h. */
dwarf2_per_cu_data_up
create_cu_from_index_list (dwarf2_per_bfd *per_bfd,
struct dwarf2_section_info *section,
int is_dwz,
sect_offset sect_off, ULONGEST length)
{
dwarf2_per_cu_data_up the_cu = per_bfd->allocate_per_cu ();
the_cu->sect_off = sect_off;
the_cu->set_length (length);
the_cu->section = section;
the_cu->is_dwz = is_dwz;
return the_cu;
}
/* die_reader_func for dw2_get_file_names. */
static void
dw2_get_file_names_reader (const struct die_reader_specs *reader,
struct die_info *comp_unit_die)
{
struct dwarf2_cu *cu = reader->cu;
struct dwarf2_per_cu_data *this_cu = cu->per_cu;
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct dwarf2_per_cu_data *lh_cu;
struct attribute *attr;
void **slot;
struct quick_file_names *qfn;
gdb_assert (! this_cu->is_debug_types);
this_cu->files_read = true;
/* Our callers never want to match partial units -- instead they
will match the enclosing full CU. */
if (comp_unit_die->tag == DW_TAG_partial_unit)
return;
lh_cu = this_cu;
slot = NULL;
line_header_up lh;
sect_offset line_offset {};
file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu);
attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu);
if (attr != nullptr && attr->form_is_unsigned ())
{
struct quick_file_names find_entry;
line_offset = (sect_offset) attr->as_unsigned ();
/* We may have already read in this line header (TU line header sharing).
If we have we're done. */
find_entry.hash.dwo_unit = cu->dwo_unit;
find_entry.hash.line_sect_off = line_offset;
slot = htab_find_slot (per_objfile->per_bfd->quick_file_names_table.get (),
&find_entry, INSERT);
if (*slot != NULL)
{
lh_cu->file_names = (struct quick_file_names *) *slot;
return;
}
lh = dwarf_decode_line_header (line_offset, cu, fnd.get_comp_dir ());
}
int offset = 0;
if (!fnd.is_unknown ())
++offset;
else if (lh == nullptr)
return;
qfn = XOBNEW (&per_objfile->per_bfd->obstack, struct quick_file_names);
qfn->hash.dwo_unit = cu->dwo_unit;
qfn->hash.line_sect_off = line_offset;
/* There may not be a DW_AT_stmt_list. */
if (slot != nullptr)
*slot = qfn;
std::vector<const char *> include_names;
if (lh != nullptr)
{
for (const auto &entry : lh->file_names ())
{
std::string name_holder;
const char *include_name =
compute_include_file_name (lh.get (), entry, fnd, name_holder);
if (include_name != nullptr)
{
include_name = per_objfile->objfile->intern (include_name);
include_names.push_back (include_name);
}
}
}
qfn->num_file_names = offset + include_names.size ();
qfn->comp_dir = fnd.intern_comp_dir (per_objfile->objfile);
qfn->file_names =
XOBNEWVEC (&per_objfile->per_bfd->obstack, const char *,
qfn->num_file_names);
if (offset != 0)
qfn->file_names[0] = per_objfile->objfile->intern (fnd.get_name ());
if (!include_names.empty ())
memcpy (&qfn->file_names[offset], include_names.data (),
include_names.size () * sizeof (const char *));
qfn->real_names = NULL;
lh_cu->file_names = qfn;
}
/* A helper for the "quick" functions which attempts to read the line
table for THIS_CU. */
static struct quick_file_names *
dw2_get_file_names (dwarf2_per_cu_data *this_cu,
dwarf2_per_objfile *per_objfile)
{
/* This should never be called for TUs. */
gdb_assert (! this_cu->is_debug_types);
if (this_cu->files_read)
return this_cu->file_names;
cutu_reader reader (this_cu, per_objfile);
if (!reader.dummy_p)
dw2_get_file_names_reader (&reader, reader.comp_unit_die);
return this_cu->file_names;
}
/* A helper for the "quick" functions which computes and caches the
real path for a given file name from the line table. */
static const char *
dw2_get_real_path (dwarf2_per_objfile *per_objfile,
struct quick_file_names *qfn, int index)
{
if (qfn->real_names == NULL)
qfn->real_names = OBSTACK_CALLOC (&per_objfile->per_bfd->obstack,
qfn->num_file_names, const char *);
if (qfn->real_names[index] == NULL)
{
const char *dirname = nullptr;
if (!IS_ABSOLUTE_PATH (qfn->file_names[index]))
dirname = qfn->comp_dir;
gdb::unique_xmalloc_ptr<char> fullname;
fullname = find_source_or_rewrite (qfn->file_names[index], dirname);
qfn->real_names[index] = fullname.release ();
}
return qfn->real_names[index];
}
struct symtab *
dwarf2_base_index_functions::find_last_source_symtab (struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
dwarf2_per_cu_data *dwarf_cu
= per_objfile->per_bfd->all_units.back ().get ();
compunit_symtab *cust = dw2_instantiate_symtab (dwarf_cu, per_objfile, false);
if (cust == NULL)
return NULL;
return cust->primary_filetab ();
}
/* See read.h. */
void
dwarf2_per_cu_data::free_cached_file_names ()
{
if (fnd != nullptr)
fnd->forget_fullname ();
if (per_bfd == nullptr)
return;
struct quick_file_names *file_data = file_names;
if (file_data != nullptr && file_data->real_names != nullptr)
{
for (int i = 0; i < file_data->num_file_names; ++i)
{
xfree ((void *) file_data->real_names[i]);
file_data->real_names[i] = nullptr;
}
}
}
void
dwarf2_base_index_functions::forget_cached_source_info
(struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
for (auto &per_cu : per_objfile->per_bfd->all_units)
per_cu->free_cached_file_names ();
}
void
dwarf2_base_index_functions::print_stats (struct objfile *objfile,
bool print_bcache)
{
if (print_bcache)
return;
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
int total = per_objfile->per_bfd->all_units.size ();
int count = 0;
for (int i = 0; i < total; ++i)
{
dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cu (i);
if (!per_objfile->symtab_set_p (per_cu))
++count;
}
gdb_printf (_(" Number of read CUs: %d\n"), total - count);
gdb_printf (_(" Number of unread CUs: %d\n"), count);
}
void
dwarf2_base_index_functions::expand_all_symtabs (struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
int total_units = per_objfile->per_bfd->all_units.size ();
for (int i = 0; i < total_units; ++i)
{
dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cu (i);
/* We don't want to directly expand a partial CU, because if we
read it with the wrong language, then assertion failures can
be triggered later on. See PR symtab/23010. So, tell
dw2_instantiate_symtab to skip partial CUs -- any important
partial CU will be read via DW_TAG_imported_unit anyway. */
dw2_instantiate_symtab (per_cu, per_objfile, true);
}
}
/* Starting from a search name, return the string that finds the upper
bound of all strings that start with SEARCH_NAME in a sorted name
list. Returns the empty string to indicate that the upper bound is
the end of the list. */
static std::string
make_sort_after_prefix_name (const char *search_name)
{
/* When looking to complete "func", we find the upper bound of all
symbols that start with "func" by looking for where we'd insert
the closest string that would follow "func" in lexicographical
order. Usually, that's "func"-with-last-character-incremented,
i.e. "fund". Mind non-ASCII characters, though. Usually those
will be UTF-8 multi-byte sequences, but we can't be certain.
Especially mind the 0xff character, which is a valid character in
non-UTF-8 source character sets (e.g. Latin1 'ÿ'), and we can't
rule out compilers allowing it in identifiers. Note that
conveniently, strcmp/strcasecmp are specified to compare
characters interpreted as unsigned char. So what we do is treat
the whole string as a base 256 number composed of a sequence of
base 256 "digits" and add 1 to it. I.e., adding 1 to 0xff wraps
to 0, and carries 1 to the following more-significant position.
If the very first character in SEARCH_NAME ends up incremented
and carries/overflows, then the upper bound is the end of the
list. The string after the empty string is also the empty
string.
Some examples of this operation:
SEARCH_NAME => "+1" RESULT
"abc" => "abd"
"ab\xff" => "ac"
"\xff" "a" "\xff" => "\xff" "b"
"\xff" => ""
"\xff\xff" => ""
"" => ""
Then, with these symbols for example:
func
func1
fund
completing "func" looks for symbols between "func" and
"func"-with-last-character-incremented, i.e. "fund" (exclusive),
which finds "func" and "func1", but not "fund".
And with:
funcÿ (Latin1 'ÿ' [0xff])
funcÿ1
fund
completing "funcÿ" looks for symbols between "funcÿ" and "fund"
(exclusive), which finds "funcÿ" and "funcÿ1", but not "fund".
And with:
ÿÿ (Latin1 'ÿ' [0xff])
ÿÿ1
completing "ÿ" or "ÿÿ" looks for symbols between between "ÿÿ" and
the end of the list.
*/
std::string after = search_name;
while (!after.empty () && (unsigned char) after.back () == 0xff)
after.pop_back ();
if (!after.empty ())
after.back () = (unsigned char) after.back () + 1;
return after;
}
/* See declaration. */
std::pair<std::vector<name_component>::const_iterator,
std::vector<name_component>::const_iterator>
mapped_index_base::find_name_components_bounds
(const lookup_name_info &lookup_name_without_params, language lang,
dwarf2_per_objfile *per_objfile) const
{
auto *name_cmp
= this->name_components_casing == case_sensitive_on ? strcmp : strcasecmp;
const char *lang_name
= lookup_name_without_params.language_lookup_name (lang);
/* Comparison function object for lower_bound that matches against a
given symbol name. */
auto lookup_compare_lower = [&] (const name_component &elem,
const char *name)
{
const char *elem_qualified = this->symbol_name_at (elem.idx, per_objfile);
const char *elem_name = elem_qualified + elem.name_offset;
return name_cmp (elem_name, name) < 0;
};
/* Comparison function object for upper_bound that matches against a
given symbol name. */
auto lookup_compare_upper = [&] (const char *name,
const name_component &elem)
{
const char *elem_qualified = this->symbol_name_at (elem.idx, per_objfile);
const char *elem_name = elem_qualified + elem.name_offset;
return name_cmp (name, elem_name) < 0;
};
auto begin = this->name_components.begin ();
auto end = this->name_components.end ();
/* Find the lower bound. */
auto lower = [&] ()
{
if (lookup_name_without_params.completion_mode () && lang_name[0] == '\0')
return begin;
else
return std::lower_bound (begin, end, lang_name, lookup_compare_lower);
} ();
/* Find the upper bound. */
auto upper = [&] ()
{
if (lookup_name_without_params.completion_mode ())
{
/* In completion mode, we want UPPER to point past all
symbols names that have the same prefix. I.e., with
these symbols, and completing "func":
function << lower bound
function1
other_function << upper bound
We find the upper bound by looking for the insertion
point of "func"-with-last-character-incremented,
i.e. "fund". */
std::string after = make_sort_after_prefix_name (lang_name);
if (after.empty ())
return end;
return std::lower_bound (lower, end, after.c_str (),
lookup_compare_lower);
}
else
return std::upper_bound (lower, end, lang_name, lookup_compare_upper);
} ();
return {lower, upper};
}
/* See declaration. */
void
mapped_index_base::build_name_components (dwarf2_per_objfile *per_objfile)
{
if (!this->name_components.empty ())
return;
this->name_components_casing = case_sensitivity;
auto *name_cmp
= this->name_components_casing == case_sensitive_on ? strcmp : strcasecmp;
/* The code below only knows how to break apart components of C++
symbol names (and other languages that use '::' as
namespace/module separator) and Ada symbol names. */
auto count = this->symbol_name_count ();
for (offset_type idx = 0; idx < count; idx++)
{
if (this->symbol_name_slot_invalid (idx))
continue;
const char *name = this->symbol_name_at (idx, per_objfile);
/* Add each name component to the name component table. */
unsigned int previous_len = 0;
if (strstr (name, "::") != nullptr)
{
for (unsigned int current_len = cp_find_first_component (name);
name[current_len] != '\0';
current_len += cp_find_first_component (name + current_len))
{
gdb_assert (name[current_len] == ':');
this->name_components.push_back ({previous_len, idx});
/* Skip the '::'. */
current_len += 2;
previous_len = current_len;
}
}
else
{
/* Handle the Ada encoded (aka mangled) form here. */
for (const char *iter = strstr (name, "__");
iter != nullptr;
iter = strstr (iter, "__"))
{
this->name_components.push_back ({previous_len, idx});
iter += 2;
previous_len = iter - name;
}
}
this->name_components.push_back ({previous_len, idx});
}
/* Sort name_components elements by name. */
auto name_comp_compare = [&] (const name_component &left,
const name_component &right)
{
const char *left_qualified
= this->symbol_name_at (left.idx, per_objfile);
const char *right_qualified
= this->symbol_name_at (right.idx, per_objfile);
const char *left_name = left_qualified + left.name_offset;
const char *right_name = right_qualified + right.name_offset;
return name_cmp (left_name, right_name) < 0;
};
std::sort (this->name_components.begin (),
this->name_components.end (),
name_comp_compare);
}
/* See read.h. */
bool
dw2_expand_symtabs_matching_symbol
(mapped_index_base &index,
const lookup_name_info &lookup_name_in,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<bool (offset_type)> match_callback,
dwarf2_per_objfile *per_objfile)
{
lookup_name_info lookup_name_without_params
= lookup_name_in.make_ignore_params ();
/* Build the symbol name component sorted vector, if we haven't
yet. */
index.build_name_components (per_objfile);
/* The same symbol may appear more than once in the range though.
E.g., if we're looking for symbols that complete "w", and we have
a symbol named "w1::w2", we'll find the two name components for
that same symbol in the range. To be sure we only call the
callback once per symbol, we first collect the symbol name
indexes that matched in a temporary vector and ignore
duplicates. */
std::vector<offset_type> matches;
struct name_and_matcher
{
symbol_name_matcher_ftype *matcher;
const char *name;
bool operator== (const name_and_matcher &other) const
{
return matcher == other.matcher && strcmp (name, other.name) == 0;
}
};
/* A vector holding all the different symbol name matchers, for all
languages. */
std::vector<name_and_matcher> matchers;
for (int i = 0; i < nr_languages; i++)
{
enum language lang_e = (enum language) i;
const language_defn *lang = language_def (lang_e);
symbol_name_matcher_ftype *name_matcher
= lang->get_symbol_name_matcher (lookup_name_without_params);
name_and_matcher key {
name_matcher,
lookup_name_without_params.language_lookup_name (lang_e)
};
/* Don't insert the same comparison routine more than once.
Note that we do this linear walk. This is not a problem in
practice because the number of supported languages is
low. */
if (std::find (matchers.begin (), matchers.end (), key)
!= matchers.end ())
continue;
matchers.push_back (std::move (key));
auto bounds
= index.find_name_components_bounds (lookup_name_without_params,
lang_e, per_objfile);
/* Now for each symbol name in range, check to see if we have a name
match, and if so, call the MATCH_CALLBACK callback. */
for (; bounds.first != bounds.second; ++bounds.first)
{
const char *qualified
= index.symbol_name_at (bounds.first->idx, per_objfile);
if (!name_matcher (qualified, lookup_name_without_params, NULL)
|| (symbol_matcher != NULL && !symbol_matcher (qualified)))
continue;
matches.push_back (bounds.first->idx);
}
}
std::sort (matches.begin (), matches.end ());
/* Finally call the callback, once per match. */
ULONGEST prev = -1;
bool result = true;
for (offset_type idx : matches)
{
if (prev != idx)
{
if (!match_callback (idx))
{
result = false;
break;
}
prev = idx;
}
}
/* Above we use a type wider than idx's for 'prev', since 0 and
(offset_type)-1 are both possible values. */
static_assert (sizeof (prev) > sizeof (offset_type), "");
return result;
}
#if GDB_SELF_TEST
namespace selftests { namespace dw2_expand_symtabs_matching {
/* A mock .gdb_index/.debug_names-like name index table, enough to
exercise dw2_expand_symtabs_matching_symbol, which works with the
mapped_index_base interface. Builds an index from the symbol list
passed as parameter to the constructor. */
class mock_mapped_index : public mapped_index_base
{
public:
mock_mapped_index (gdb::array_view<const char *> symbols)
: m_symbol_table (symbols)
{}
DISABLE_COPY_AND_ASSIGN (mock_mapped_index);
/* Return the number of names in the symbol table. */
size_t symbol_name_count () const override
{
return m_symbol_table.size ();
}
/* Get the name of the symbol at IDX in the symbol table. */
const char *symbol_name_at
(offset_type idx, dwarf2_per_objfile *per_objfile) const override
{
return m_symbol_table[idx];
}
quick_symbol_functions_up make_quick_functions () const override
{
return nullptr;
}
private:
gdb::array_view<const char *> m_symbol_table;
};
/* Convenience function that converts a NULL pointer to a "<null>"
string, to pass to print routines. */
static const char *
string_or_null (const char *str)
{
return str != NULL ? str : "<null>";
}
/* Check if a lookup_name_info built from
NAME/MATCH_TYPE/COMPLETION_MODE matches the symbols in the mock
index. EXPECTED_LIST is the list of expected matches, in expected
matching order. If no match expected, then an empty list is
specified. Returns true on success. On failure prints a warning
indicating the file:line that failed, and returns false. */
static bool
check_match (const char *file, int line,
mock_mapped_index &mock_index,
const char *name, symbol_name_match_type match_type,
bool completion_mode,
std::initializer_list<const char *> expected_list,
dwarf2_per_objfile *per_objfile)
{
lookup_name_info lookup_name (name, match_type, completion_mode);
bool matched = true;
auto mismatch = [&] (const char *expected_str,
const char *got)
{
warning (_("%s:%d: match_type=%s, looking-for=\"%s\", "
"expected=\"%s\", got=\"%s\"\n"),
file, line,
(match_type == symbol_name_match_type::FULL
? "FULL" : "WILD"),
name, string_or_null (expected_str), string_or_null (got));
matched = false;
};
auto expected_it = expected_list.begin ();
auto expected_end = expected_list.end ();
dw2_expand_symtabs_matching_symbol (mock_index, lookup_name,
nullptr,
[&] (offset_type idx)
{
const char *matched_name = mock_index.symbol_name_at (idx, per_objfile);
const char *expected_str
= expected_it == expected_end ? NULL : *expected_it++;
if (expected_str == NULL || strcmp (expected_str, matched_name) != 0)
mismatch (expected_str, matched_name);
return true;
}, per_objfile);
const char *expected_str
= expected_it == expected_end ? NULL : *expected_it++;
if (expected_str != NULL)
mismatch (expected_str, NULL);
return matched;
}
/* The symbols added to the mock mapped_index for testing (in
canonical form). */
static const char *test_symbols[] = {
"function",
"std::bar",
"std::zfunction",
"std::zfunction2",
"w1::w2",
"ns::foo<char*>",
"ns::foo<int>",
"ns::foo<long>",
"ns2::tmpl<int>::foo2",
"(anonymous namespace)::A::B::C",
/* These are used to check that the increment-last-char in the
matching algorithm for completion doesn't match "t1_fund" when
completing "t1_func". */
"t1_func",
"t1_func1",
"t1_fund",
"t1_fund1",
/* A UTF-8 name with multi-byte sequences to make sure that
cp-name-parser understands this as a single identifier ("função"
is "function" in PT). */
(const char *)u8"u8função",
/* Test a symbol name that ends with a 0xff character, which is a
valid character in non-UTF-8 source character sets (e.g. Latin1
'ÿ'), and we can't rule out compilers allowing it in identifiers.
We test this because the completion algorithm finds the upper
bound of symbols by looking for the insertion point of
"func"-with-last-character-incremented, i.e. "fund", and adding 1
to 0xff should wraparound and carry to the previous character.
See comments in make_sort_after_prefix_name. */
"yfunc\377",
/* Some more symbols with \377 (0xff). See above. */
"\377",
"\377\377123",
/* A name with all sorts of complications. Starts with "z" to make
it easier for the completion tests below. */
#define Z_SYM_NAME \
"z::std::tuple<(anonymous namespace)::ui*, std::bar<(anonymous namespace)::ui> >" \
"::tuple<(anonymous namespace)::ui*, " \
"std::default_delete<(anonymous namespace)::ui>, void>"
Z_SYM_NAME
};
/* Returns true if the mapped_index_base::find_name_component_bounds
method finds EXPECTED_SYMS in INDEX when looking for SEARCH_NAME,
in completion mode. */
static bool
check_find_bounds_finds (mapped_index_base &index,
const char *search_name,
gdb::array_view<const char *> expected_syms,
dwarf2_per_objfile *per_objfile)
{
lookup_name_info lookup_name (search_name,
symbol_name_match_type::FULL, true);
auto bounds = index.find_name_components_bounds (lookup_name,
language_cplus,
per_objfile);
size_t distance = std::distance (bounds.first, bounds.second);
if (distance != expected_syms.size ())
return false;
for (size_t exp_elem = 0; exp_elem < distance; exp_elem++)
{
auto nc_elem = bounds.first + exp_elem;
const char *qualified = index.symbol_name_at (nc_elem->idx, per_objfile);
if (strcmp (qualified, expected_syms[exp_elem]) != 0)
return false;
}
return true;
}
/* Test the lower-level mapped_index::find_name_component_bounds
method. */
static void
test_mapped_index_find_name_component_bounds ()
{
mock_mapped_index mock_index (test_symbols);
mock_index.build_name_components (NULL /* per_objfile */);
/* Test the lower-level mapped_index::find_name_component_bounds
method in completion mode. */
{
static const char *expected_syms[] = {
"t1_func",
"t1_func1",
};
SELF_CHECK (check_find_bounds_finds
(mock_index, "t1_func", expected_syms,
NULL /* per_objfile */));
}
/* Check that the increment-last-char in the name matching algorithm
for completion doesn't get confused with Ansi1 'ÿ' / 0xff. See
make_sort_after_prefix_name. */
{
static const char *expected_syms1[] = {
"\377",
"\377\377123",
};
SELF_CHECK (check_find_bounds_finds
(mock_index, "\377", expected_syms1, NULL /* per_objfile */));
static const char *expected_syms2[] = {
"\377\377123",
};
SELF_CHECK (check_find_bounds_finds
(mock_index, "\377\377", expected_syms2,
NULL /* per_objfile */));
}
}
/* Test dw2_expand_symtabs_matching_symbol. */
static void
test_dw2_expand_symtabs_matching_symbol ()
{
mock_mapped_index mock_index (test_symbols);
/* We let all tests run until the end even if some fails, for debug
convenience. */
bool any_mismatch = false;
/* Create the expected symbols list (an initializer_list). Needed
because lists have commas, and we need to pass them to CHECK,
which is a macro. */
#define EXPECT(...) { __VA_ARGS__ }
/* Wrapper for check_match that passes down the current
__FILE__/__LINE__. */
#define CHECK_MATCH(NAME, MATCH_TYPE, COMPLETION_MODE, EXPECTED_LIST) \
any_mismatch |= !check_match (__FILE__, __LINE__, \
mock_index, \
NAME, MATCH_TYPE, COMPLETION_MODE, \
EXPECTED_LIST, NULL)
/* Identity checks. */
for (const char *sym : test_symbols)
{
/* Should be able to match all existing symbols. */
CHECK_MATCH (sym, symbol_name_match_type::FULL, false,
EXPECT (sym));
/* Should be able to match all existing symbols with
parameters. */
std::string with_params = std::string (sym) + "(int)";
CHECK_MATCH (with_params.c_str (), symbol_name_match_type::FULL, false,
EXPECT (sym));
/* Should be able to match all existing symbols with
parameters and qualifiers. */
with_params = std::string (sym) + " ( int ) const";
CHECK_MATCH (with_params.c_str (), symbol_name_match_type::FULL, false,
EXPECT (sym));
/* This should really find sym, but cp-name-parser.y doesn't
know about lvalue/rvalue qualifiers yet. */
with_params = std::string (sym) + " ( int ) &&";
CHECK_MATCH (with_params.c_str (), symbol_name_match_type::FULL, false,
{});
}
/* Check that the name matching algorithm for completion doesn't get
confused with Latin1 'ÿ' / 0xff. See
make_sort_after_prefix_name. */
{
static const char str[] = "\377";
CHECK_MATCH (str, symbol_name_match_type::FULL, true,
EXPECT ("\377", "\377\377123"));
}
/* Check that the increment-last-char in the matching algorithm for
completion doesn't match "t1_fund" when completing "t1_func". */
{
static const char str[] = "t1_func";
CHECK_MATCH (str, symbol_name_match_type::FULL, true,
EXPECT ("t1_func", "t1_func1"));
}
/* Check that completion mode works at each prefix of the expected
symbol name. */
{
static const char str[] = "function(int)";
size_t len = strlen (str);
std::string lookup;
for (size_t i = 1; i < len; i++)
{
lookup.assign (str, i);
CHECK_MATCH (lookup.c_str (), symbol_name_match_type::FULL, true,
EXPECT ("function"));
}
}
/* While "w" is a prefix of both components, the match function
should still only be called once. */
{
CHECK_MATCH ("w", symbol_name_match_type::FULL, true,
EXPECT ("w1::w2"));
CHECK_MATCH ("w", symbol_name_match_type::WILD, true,
EXPECT ("w1::w2"));
}
/* Same, with a "complicated" symbol. */
{
static const char str[] = Z_SYM_NAME;
size_t len = strlen (str);
std::string lookup;
for (size_t i = 1; i < len; i++)
{
lookup.assign (str, i);
CHECK_MATCH (lookup.c_str (), symbol_name_match_type::FULL, true,
EXPECT (Z_SYM_NAME));
}
}
/* In FULL mode, an incomplete symbol doesn't match. */
{
CHECK_MATCH ("std::zfunction(int", symbol_name_match_type::FULL, false,
{});
}
/* A complete symbol with parameters matches any overload, since the
index has no overload info. */
{
CHECK_MATCH ("std::zfunction(int)", symbol_name_match_type::FULL, true,
EXPECT ("std::zfunction", "std::zfunction2"));
CHECK_MATCH ("zfunction(int)", symbol_name_match_type::WILD, true,
EXPECT ("std::zfunction", "std::zfunction2"));
CHECK_MATCH ("zfunc", symbol_name_match_type::WILD, true,
EXPECT ("std::zfunction", "std::zfunction2"));
}
/* Check that whitespace is ignored appropriately. A symbol with a
template argument list. */
{
static const char expected[] = "ns::foo<int>";
CHECK_MATCH ("ns :: foo < int > ", symbol_name_match_type::FULL, false,
EXPECT (expected));
CHECK_MATCH ("foo < int > ", symbol_name_match_type::WILD, false,
EXPECT (expected));
}
/* Check that whitespace is ignored appropriately. A symbol with a
template argument list that includes a pointer. */
{
static const char expected[] = "ns::foo<char*>";
/* Try both completion and non-completion modes. */
static const bool completion_mode[2] = {false, true};
for (size_t i = 0; i < 2; i++)
{
CHECK_MATCH ("ns :: foo < char * >", symbol_name_match_type::FULL,
completion_mode[i], EXPECT (expected));
CHECK_MATCH ("foo < char * >", symbol_name_match_type::WILD,
completion_mode[i], EXPECT (expected));
CHECK_MATCH ("ns :: foo < char * > (int)", symbol_name_match_type::FULL,
completion_mode[i], EXPECT (expected));
CHECK_MATCH ("foo < char * > (int)", symbol_name_match_type::WILD,
completion_mode[i], EXPECT (expected));
}
}
{
/* Check method qualifiers are ignored. */
static const char expected[] = "ns::foo<char*>";
CHECK_MATCH ("ns :: foo < char * > ( int ) const",
symbol_name_match_type::FULL, true, EXPECT (expected));
CHECK_MATCH ("ns :: foo < char * > ( int ) &&",
symbol_name_match_type::FULL, true, EXPECT (expected));
CHECK_MATCH ("foo < char * > ( int ) const",
symbol_name_match_type::WILD, true, EXPECT (expected));
CHECK_MATCH ("foo < char * > ( int ) &&",
symbol_name_match_type::WILD, true, EXPECT (expected));
}
/* Test lookup names that don't match anything. */
{
CHECK_MATCH ("bar2", symbol_name_match_type::WILD, false,
{});
CHECK_MATCH ("doesntexist", symbol_name_match_type::FULL, false,
{});
}
/* Some wild matching tests, exercising "(anonymous namespace)",
which should not be confused with a parameter list. */
{
static const char *syms[] = {
"A::B::C",
"B::C",
"C",
"A :: B :: C ( int )",
"B :: C ( int )",
"C ( int )",
};
for (const char *s : syms)
{
CHECK_MATCH (s, symbol_name_match_type::WILD, false,
EXPECT ("(anonymous namespace)::A::B::C"));
}
}
{
static const char expected[] = "ns2::tmpl<int>::foo2";
CHECK_MATCH ("tmp", symbol_name_match_type::WILD, true,
EXPECT (expected));
CHECK_MATCH ("tmpl<", symbol_name_match_type::WILD, true,
EXPECT (expected));
}
SELF_CHECK (!any_mismatch);
#undef EXPECT
#undef CHECK_MATCH
}
static void
run_test ()
{
test_mapped_index_find_name_component_bounds ();
test_dw2_expand_symtabs_matching_symbol ();
}
}} // namespace selftests::dw2_expand_symtabs_matching
#endif /* GDB_SELF_TEST */
/* See read.h. */
bool
dw2_expand_symtabs_matching_one
(dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify)
{
if (file_matcher == NULL || per_cu->mark)
{
bool symtab_was_null = !per_objfile->symtab_set_p (per_cu);
compunit_symtab *symtab
= dw2_instantiate_symtab (per_cu, per_objfile, false);
gdb_assert (symtab != nullptr);
if (expansion_notify != NULL && symtab_was_null)
return expansion_notify (symtab);
}
return true;
}
/* See read.h. */
void
dw_expand_symtabs_matching_file_matcher
(dwarf2_per_objfile *per_objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher)
{
if (file_matcher == NULL)
return;
htab_up visited_found (htab_create_alloc (10, htab_hash_pointer,
htab_eq_pointer,
NULL, xcalloc, xfree));
htab_up visited_not_found (htab_create_alloc (10, htab_hash_pointer,
htab_eq_pointer,
NULL, xcalloc, xfree));
/* The rule is CUs specify all the files, including those used by
any TU, so there's no need to scan TUs here. */
for (const auto &per_cu : per_objfile->per_bfd->all_units)
{
QUIT;
if (per_cu->is_debug_types)
continue;
per_cu->mark = 0;
/* We only need to look at symtabs not already expanded. */
if (per_objfile->symtab_set_p (per_cu.get ()))
continue;
if (per_cu->fnd != nullptr)
{
file_and_directory *fnd = per_cu->fnd.get ();
if (file_matcher (fnd->get_name (), false))
{
per_cu->mark = 1;
continue;
}
/* Before we invoke realpath, which can get expensive when many
files are involved, do a quick comparison of the basenames. */
if ((basenames_may_differ
|| file_matcher (lbasename (fnd->get_name ()), true))
&& file_matcher (fnd->get_fullname (), false))
{
per_cu->mark = 1;
continue;
}
}
quick_file_names *file_data = dw2_get_file_names (per_cu.get (),
per_objfile);
if (file_data == NULL)
continue;
if (htab_find (visited_not_found.get (), file_data) != NULL)
continue;
else if (htab_find (visited_found.get (), file_data) != NULL)
{
per_cu->mark = 1;
continue;
}
for (int j = 0; j < file_data->num_file_names; ++j)
{
const char *this_real_name;
if (file_matcher (file_data->file_names[j], false))
{
per_cu->mark = 1;
break;
}
/* Before we invoke realpath, which can get expensive when many
files are involved, do a quick comparison of the basenames. */
if (!basenames_may_differ
&& !file_matcher (lbasename (file_data->file_names[j]),
true))
continue;
this_real_name = dw2_get_real_path (per_objfile, file_data, j);
if (file_matcher (this_real_name, false))
{
per_cu->mark = 1;
break;
}
}
void **slot = htab_find_slot (per_cu->mark
? visited_found.get ()
: visited_not_found.get (),
file_data, INSERT);
*slot = file_data;
}
}
/* A helper for dw2_find_pc_sect_compunit_symtab which finds the most specific
symtab. */
static struct compunit_symtab *
recursively_find_pc_sect_compunit_symtab (struct compunit_symtab *cust,
CORE_ADDR pc)
{
int i;
if (cust->blockvector () != nullptr
&& blockvector_contains_pc (cust->blockvector (), pc))
return cust;
if (cust->includes == NULL)
return NULL;
for (i = 0; cust->includes[i]; ++i)
{
struct compunit_symtab *s = cust->includes[i];
s = recursively_find_pc_sect_compunit_symtab (s, pc);
if (s != NULL)
return s;
}
return NULL;
}
struct compunit_symtab *
dwarf2_base_index_functions::find_pc_sect_compunit_symtab
(struct objfile *objfile,
bound_minimal_symbol msymbol,
CORE_ADDR pc,
struct obj_section *section,
int warn_if_readin)
{
struct compunit_symtab *result;
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
if (per_bfd->index_table == nullptr)
return nullptr;
CORE_ADDR baseaddr = objfile->text_section_offset ();
struct dwarf2_per_cu_data *data
= per_bfd->index_table->lookup ((unrelocated_addr) (pc - baseaddr));
if (data == nullptr)
return nullptr;
if (warn_if_readin && per_objfile->symtab_set_p (data))
warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
paddress (objfile->arch (), pc));
result = recursively_find_pc_sect_compunit_symtab
(dw2_instantiate_symtab (data, per_objfile, false), pc);
if (warn_if_readin && result == nullptr)
warning (_("(Error: pc %s in address map, but not in symtab.)"),
paddress (objfile->arch (), pc));
return result;
}
void
dwarf2_base_index_functions::map_symbol_filenames
(struct objfile *objfile,
gdb::function_view<symbol_filename_ftype> fun,
bool need_fullname)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
/* Use caches to ensure we only call FUN once for each filename. */
filename_seen_cache filenames_cache;
std::unordered_set<quick_file_names *> qfn_cache;
/* The rule is CUs specify all the files, including those used by any TU,
so there's no need to scan TUs here. We can ignore file names coming
from already-expanded CUs. It is possible that an expanded CU might
reuse the file names data from a currently unexpanded CU, in this
case we don't want to report the files from the unexpanded CU. */
for (const auto &per_cu : per_objfile->per_bfd->all_units)
{
if (!per_cu->is_debug_types
&& per_objfile->symtab_set_p (per_cu.get ()))
{
if (per_cu->file_names != nullptr)
qfn_cache.insert (per_cu->file_names);
}
}
for (dwarf2_per_cu_data *per_cu
: all_units_range (per_objfile->per_bfd))
{
/* We only need to look at symtabs not already expanded. */
if (per_cu->is_debug_types || per_objfile->symtab_set_p (per_cu))
continue;
if (per_cu->fnd != nullptr)
{
file_and_directory *fnd = per_cu->fnd.get ();
const char *filename = fnd->get_name ();
const char *key = filename;
const char *fullname = nullptr;
if (need_fullname)
{
fullname = fnd->get_fullname ();
key = fullname;
}
if (!filenames_cache.seen (key))
fun (filename, fullname);
}
quick_file_names *file_data = dw2_get_file_names (per_cu, per_objfile);
if (file_data == nullptr
|| qfn_cache.find (file_data) != qfn_cache.end ())
continue;
for (int j = 0; j < file_data->num_file_names; ++j)
{
const char *filename = file_data->file_names[j];
const char *key = filename;
const char *fullname = nullptr;
if (need_fullname)
{
fullname = dw2_get_real_path (per_objfile, file_data, j);
key = fullname;
}
if (!filenames_cache.seen (key))
fun (filename, fullname);
}
}
}
bool
dwarf2_base_index_functions::has_symbols (struct objfile *objfile)
{
return true;
}
/* See quick_symbol_functions::has_unexpanded_symtabs in quick-symbol.h. */
bool
dwarf2_base_index_functions::has_unexpanded_symtabs (struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
for (const auto &per_cu : per_objfile->per_bfd->all_units)
{
/* Is this already expanded? */
if (per_objfile->symtab_set_p (per_cu.get ()))
continue;
/* It has not yet been expanded. */
return true;
}
return false;
}
/* Get the content of the .gdb_index section of OBJ. SECTION_OWNER should point
to either a dwarf2_per_bfd or dwz_file object. */
template <typename T>
static gdb::array_view<const gdb_byte>
get_gdb_index_contents_from_section (objfile *obj, T *section_owner)
{
dwarf2_section_info *section = &section_owner->gdb_index;
if (section->empty ())
return {};
/* Older elfutils strip versions could keep the section in the main
executable while splitting it for the separate debug info file. */
if ((section->get_flags () & SEC_HAS_CONTENTS) == 0)
return {};
section->read (obj);
/* dwarf2_section_info::size is a bfd_size_type, while
gdb::array_view works with size_t. On 32-bit hosts, with
--enable-64-bit-bfd, bfd_size_type is a 64-bit type, while size_t
is 32-bit. So we need an explicit narrowing conversion here.
This is fine, because it's impossible to allocate or mmap an
array/buffer larger than what size_t can represent. */
return gdb::make_array_view (section->buffer, section->size);
}
/* Lookup the index cache for the contents of the index associated to
DWARF2_OBJ. */
static gdb::array_view<const gdb_byte>
get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd)
{
const bfd_build_id *build_id = build_id_bfd_get (obj->obfd.get ());
if (build_id == nullptr)
return {};
return global_index_cache.lookup_gdb_index (build_id,
&dwarf2_per_bfd->index_cache_res);
}
/* Same as the above, but for DWZ. */
static gdb::array_view<const gdb_byte>
get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz)
{
const bfd_build_id *build_id = build_id_bfd_get (dwz->dwz_bfd.get ());
if (build_id == nullptr)
return {};
return global_index_cache.lookup_gdb_index (build_id, &dwz->index_cache_res);
}
static void start_debug_info_reader (dwarf2_per_objfile *);
/* See dwarf2/public.h. */
bool
dwarf2_initialize_objfile (struct objfile *objfile,
const struct dwarf2_debug_sections *names,
bool can_copy)
{
if (!dwarf2_has_info (objfile, names, can_copy))
return false;
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
dwarf_read_debug_printf ("called");
/* If we're about to read full symbols, don't bother with the
indices. In this case we also don't care if some other debug
format is making psymtabs, because they are all about to be
expanded anyway. */
if ((objfile->flags & OBJF_READNOW))
{
dwarf_read_debug_printf ("readnow requested");
create_all_units (per_objfile);
per_bfd->quick_file_names_table
= create_quick_file_names_table (per_bfd->all_units.size ());
objfile->qf.emplace_front (new readnow_functions);
}
/* Was a GDB index already read when we processed an objfile sharing
PER_BFD? */
else if (per_bfd->index_table != nullptr)
dwarf_read_debug_printf ("re-using symbols");
else if (dwarf2_read_debug_names (per_objfile))
dwarf_read_debug_printf ("found debug names");
else if (dwarf2_read_gdb_index (per_objfile,
get_gdb_index_contents_from_section<struct dwarf2_per_bfd>,
get_gdb_index_contents_from_section<dwz_file>))
dwarf_read_debug_printf ("found gdb index from file");
/* ... otherwise, try to find the index in the index cache. */
else if (dwarf2_read_gdb_index (per_objfile,
get_gdb_index_contents_from_cache,
get_gdb_index_contents_from_cache_dwz))
{
dwarf_read_debug_printf ("found gdb index from cache");
global_index_cache.hit ();
}
else
{
global_index_cache.miss ();
start_debug_info_reader (