#include "go-lang.h"
#include "valprint.h"
#include "gdbcore.h" /* for gnutarget */
+#include "gdb/gdb-index.h"
#include <ctype.h>
#include <fcntl.h>
typedef struct symbol *symbolp;
DEF_VEC_P (symbolp);
+/* When non-zero, print basic high level tracing messages.
+ This is in contrast to the low level DIE reading of dwarf2_die_debug. */
+static int dwarf2_read_debug = 0;
+
/* When non-zero, dump DIEs after they are read in. */
static int dwarf2_die_debug = 0;
DEF_VEC_I (offset_type);
+/* Ensure only legit values are used. */
+#define DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE(cu_index, value) \
+ do { \
+ gdb_assert ((unsigned int) (value) <= 1); \
+ GDB_INDEX_SYMBOL_STATIC_SET_VALUE((cu_index), (value)); \
+ } while (0)
+
+/* Ensure only legit values are used. */
+#define DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE(cu_index, value) \
+ do { \
+ gdb_assert ((value) >= GDB_INDEX_SYMBOL_KIND_TYPE \
+ && (value) <= GDB_INDEX_SYMBOL_KIND_OTHER); \
+ GDB_INDEX_SYMBOL_KIND_SET_VALUE((cu_index), (value)); \
+ } while (0)
+
+/* Ensure we don't use more than the alloted nuber of bits for the CU. */
+#define DW2_GDB_INDEX_CU_SET_VALUE(cu_index, value) \
+ do { \
+ gdb_assert (((value) & ~GDB_INDEX_CU_MASK) == 0); \
+ GDB_INDEX_CU_SET_VALUE((cu_index), (value)); \
+ } while (0)
+
/* A description of the mapped index. The file format is described in
a comment by the code that writes the index. */
struct mapped_index
struct dwarf2_section_names info_dwo;
struct dwarf2_section_names line_dwo;
struct dwarf2_section_names loc_dwo;
+ struct dwarf2_section_names macinfo_dwo;
+ struct dwarf2_section_names macro_dwo;
struct dwarf2_section_names str_dwo;
struct dwarf2_section_names str_offsets_dwo;
struct dwarf2_section_names types_dwo;
{ ".debug_info.dwo", ".zdebug_info.dwo" },
{ ".debug_line.dwo", ".zdebug_line.dwo" },
{ ".debug_loc.dwo", ".zdebug_loc.dwo" },
+ { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo" },
+ { ".debug_macro.dwo", ".zdebug_macro.dwo" },
{ ".debug_str.dwo", ".zdebug_str.dwo" },
{ ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo" },
{ ".debug_types.dwo", ".zdebug_types.dwo" },
Note this value comes from the stub CU/TU's DIE. */
ULONGEST addr_base;
+ /* The DW_AT_ranges_base attribute if present, zero otherwise
+ (zero is a valid value though).
+ Note this value comes from the stub CU/TU's DIE.
+ Also note that the value is zero in the non-DWO case so this value can
+ be used without needing to know whether DWO files are in use or not. */
+ ULONGEST ranges_base;
+
/* Mark used when releasing cached dies. */
unsigned int mark : 1;
unsigned int checked_producer : 1;
unsigned int producer_is_gxx_lt_4_6 : 1;
unsigned int producer_is_icc : 1;
-
- /* Non-zero if DW_AT_addr_base was found.
- Used when processing DWO files. */
- unsigned int have_addr_base : 1;
};
/* Persistent data held for a compilation unit, even when not
struct dwarf2_section_info info;
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;
struct dwarf2_section_info str_offsets;
VEC (dwarf2_section_info_def) *types;
static struct die_info *dwarf_alloc_die (struct dwarf2_cu *, int);
-static void dwarf_decode_macros (struct line_header *, unsigned int,
- char *, bfd *, struct dwarf2_cu *,
- struct dwarf2_section_info *,
- int, const char *);
+static void dwarf_decode_macros (struct dwarf2_cu *, unsigned int,
+ char *, int);
static int attr_form_is_block (struct attribute *);
static char *file_full_name (int file, struct line_header *lh,
const char *comp_dir);
-static gdb_byte *read_and_check_comp_unit_head
- (struct comp_unit_head *header,
- struct dwarf2_section_info *section, gdb_byte *info_ptr,
- int is_debug_types_section);
-
static void init_cutu_and_read_dies
(struct dwarf2_per_cu_data *this_cu, int use_existing_cu, int keep,
die_reader_func_ftype *die_reader_func, void *data);
}
/* Indexes with higher version than the one supported by GDB may be no
longer backward compatible. */
- if (version > 6)
+ if (version > 7)
return 0;
map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
struct quick_file_names *qfn;
unsigned int line_offset;
+ /* 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)
+ {
+ this_cu->v.quick->no_file_data = 1;
+ return;
+ }
+
lh = NULL;
slot = NULL;
line_offset = 0;
}
/* A helper function that expands all symtabs that hold an object
- named NAME. */
+ named NAME. If WANT_SPECIFIC_BLOCK is non-zero, only look for
+ symbols in block BLOCK_KIND. */
static void
-dw2_do_expand_symtabs_matching (struct objfile *objfile, const char *name)
+dw2_do_expand_symtabs_matching (struct objfile *objfile,
+ int want_specific_block,
+ enum block_enum block_kind,
+ const char *name, domain_enum domain)
{
+ struct mapped_index *index;
+
dw2_setup (objfile);
+ index = dwarf2_per_objfile->index_table;
+
/* index_table is NULL if OBJF_READNOW. */
- if (dwarf2_per_objfile->index_table)
+ if (index)
{
offset_type *vec;
- if (find_slot_in_mapped_hash (dwarf2_per_objfile->index_table,
- name, &vec))
+ if (find_slot_in_mapped_hash (index, name, &vec))
{
offset_type i, len = MAYBE_SWAP (*vec);
for (i = 0; i < len; ++i)
{
- offset_type cu_index = MAYBE_SWAP (vec[i + 1]);
+ offset_type cu_index_and_attrs = MAYBE_SWAP (vec[i + 1]);
+ offset_type cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (cu_index);
+ int want_static = block_kind != GLOBAL_BLOCK;
+ /* This value is only valid for index versions >= 7. */
+ int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs);
+ gdb_index_symbol_kind symbol_kind =
+ GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
+
+ if (want_specific_block
+ && index->version >= 7
+ && want_static != is_static)
+ continue;
+
+ /* Only check the symbol's kind if it has one.
+ Indices prior to version 7 don't record it. */
+ if (index->version >= 7)
+ {
+ switch (domain)
+ {
+ case VAR_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION
+ /* Some types are also in VAR_DOMAIN. */
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
+ continue;
+ break;
+ case STRUCT_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
+ continue;
+ break;
+ case LABEL_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER)
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
dw2_instantiate_symtab (per_cu);
}
enum block_enum block_kind, const char *name,
domain_enum domain)
{
- dw2_do_expand_symtabs_matching (objfile, name);
+ dw2_do_expand_symtabs_matching (objfile, 1, block_kind, name, domain);
}
static void
dw2_expand_symtabs_for_function (struct objfile *objfile,
const char *func_name)
{
- dw2_do_expand_symtabs_matching (objfile, func_name);
+ /* Note: It doesn't matter what we pass for block_kind here. */
+ dw2_do_expand_symtabs_matching (objfile, 0, GLOBAL_BLOCK, func_name,
+ VAR_DOMAIN);
}
static void
}
}
+/* A helper function for dw2_find_symbol_file that finds the primary
+ file name for a given CU. This is a die_reader_func. */
+
+static void
+dw2_get_primary_filename_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
+{
+ const char **result_ptr = data;
+ struct dwarf2_cu *cu = reader->cu;
+ struct attribute *attr;
+
+ attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
+ if (attr == NULL)
+ *result_ptr = NULL;
+ else
+ *result_ptr = DW_STRING (attr);
+}
+
static const char *
dw2_find_symbol_file (struct objfile *objfile, const char *name)
{
struct dwarf2_per_cu_data *per_cu;
offset_type *vec;
struct quick_file_names *file_data;
+ const char *filename;
dw2_setup (objfile);
should be rewritten so that it doesn't require a custom hook. It
could just use the ordinary symbol tables. */
/* vec[0] is the length, which must always be >0. */
- per_cu = dw2_get_cu (MAYBE_SWAP (vec[1]));
+ per_cu = dw2_get_cu (GDB_INDEX_CU_VALUE (MAYBE_SWAP (vec[1])));
- file_data = dw2_get_file_names (objfile, per_cu);
- if (file_data == NULL
- || file_data->num_file_names == 0)
- return NULL;
+ if (per_cu->v.quick->symtab != NULL)
+ return per_cu->v.quick->symtab->filename;
+
+ init_cutu_and_read_dies (per_cu, 0, 0, dw2_get_primary_filename_reader,
+ &filename);
- return file_data->file_names[file_data->num_file_names - 1];
+ return filename;
}
static void
for (vec_idx = 0; vec_idx < vec_len; ++vec_idx)
{
struct dwarf2_per_cu_data *per_cu;
+ offset_type cu_index_and_attrs = MAYBE_SWAP (vec[vec_idx + 1]);
+ gdb_index_symbol_kind symbol_kind =
+ GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
+ int cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
+
+ /* Don't crash on bad data. */
+ if (cu_index >= (dwarf2_per_objfile->n_comp_units
+ + dwarf2_per_objfile->n_comp_units))
+ continue;
- per_cu = dw2_get_cu (MAYBE_SWAP (vec[vec_idx + 1]));
+ /* Only check the symbol's kind if it has one.
+ Indices prior to version 7 don't record it. */
+ if (index->version >= 7)
+ {
+ switch (kind)
+ {
+ case VARIABLES_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE)
+ continue;
+ break;
+ case FUNCTIONS_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION)
+ continue;
+ break;
+ case TYPES_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
+
+ per_cu = dw2_get_cu (cu_index);
if (file_matcher == NULL || per_cu->v.quick->mark)
dw2_instantiate_symtab (per_cu);
}
static void
error_check_comp_unit_head (struct comp_unit_head *header,
- struct dwarf2_section_info *section)
+ struct dwarf2_section_info *section,
+ struct dwarf2_section_info *abbrev_section)
{
bfd *abfd = section->asection->owner;
const char *filename = bfd_get_filename (abfd);
static gdb_byte *
read_and_check_comp_unit_head (struct comp_unit_head *header,
struct dwarf2_section_info *section,
+ struct dwarf2_section_info *abbrev_section,
gdb_byte *info_ptr,
int is_debug_types_section)
{
header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
- error_check_comp_unit_head (header, section);
+ error_check_comp_unit_head (header, section, abbrev_section);
return info_ptr;
}
static gdb_byte *
read_and_check_type_unit_head (struct comp_unit_head *header,
struct dwarf2_section_info *section,
+ struct dwarf2_section_info *abbrev_section,
gdb_byte *info_ptr,
ULONGEST *signature,
cu_offset *type_offset_in_tu)
header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
- error_check_comp_unit_head (header, section);
+ error_check_comp_unit_head (header, section, abbrev_section);
return info_ptr;
}
htab_t types_htab = NULL;
int ix;
struct dwarf2_section_info *section;
+ struct dwarf2_section_info *abbrev_section;
if (VEC_empty (dwarf2_section_info_def, types))
return NULL;
+ abbrev_section = (dwo_file != NULL
+ ? &dwo_file->sections.abbrev
+ : &dwarf2_per_objfile->abbrev);
+
for (ix = 0;
VEC_iterate (dwarf2_section_info_def, types, ix, section);
++ix)
/* We need to read the type's signature in order to build the hash
table, but we don't need anything else just yet. */
- ptr = read_and_check_type_unit_head (&header, section, ptr,
+ ptr = read_and_check_type_unit_head (&header, section,
+ abbrev_section, ptr,
&signature, &type_offset_in_tu);
length = header.initial_length_size + header.length;
struct attribute *attr;
struct cleanup *cleanups, *free_cu_cleanup = NULL;
struct signatured_type *sig_type = NULL;
+ struct dwarf2_section_info *abbrev_section;
if (use_existing_cu)
gdb_assert (keep);
dwarf2_read_section (objfile, section);
begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
+ abbrev_section = &dwarf2_per_objfile->abbrev;
if (use_existing_cu && this_cu->cu != NULL)
{
{
ULONGEST signature;
- info_ptr = read_and_check_type_unit_head (&cu->header,
- section, info_ptr,
+ info_ptr = read_and_check_type_unit_head (&cu->header, section,
+ abbrev_section, info_ptr,
&signature, NULL);
/* There's no way to get from PER_CU to its containing
}
else
{
- info_ptr = read_and_check_comp_unit_head (&cu->header,
- section, info_ptr, 0);
+ info_ptr = read_and_check_comp_unit_head (&cu->header, section,
+ abbrev_section,
+ info_ptr, 0);
gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off);
gdb_assert (this_cu->length
/* Read the abbrevs for this compilation unit into a table. */
if (cu->dwarf2_abbrevs == NULL)
{
- dwarf2_read_abbrevs (cu, &dwarf2_per_objfile->abbrev);
+ dwarf2_read_abbrevs (cu, abbrev_section);
make_cleanup (dwarf2_free_abbrev_table, cu);
}
ULONGEST signature; /* Or dwo_id. */
struct attribute *stmt_list, *low_pc, *high_pc, *ranges;
int i,num_extra_attrs;
+ struct dwarf2_section_info *dwo_abbrev_section;
if (has_children)
error (_("Dwarf Error: compilation unit with DW_AT_GNU_dwo_name"
/* There should be a DW_AT_addr_base attribute here (if needed).
We need the value before we can process DW_FORM_GNU_addr_index. */
cu->addr_base = 0;
- cu->have_addr_base = 0;
attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_addr_base, cu);
if (attr)
- {
- cu->addr_base = DW_UNSND (attr);
- cu->have_addr_base = 1;
- }
+ cu->addr_base = DW_UNSND (attr);
+
+ /* There should be a DW_AT_ranges_base attribute here (if needed).
+ We need the value before we can process DW_AT_ranges. */
+ cu->ranges_base = 0;
+ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_ranges_base, cu);
+ if (attr)
+ cu->ranges_base = DW_UNSND (attr);
if (this_cu->is_debug_types)
{
cu->dwo_unit = dwo_unit;
section = dwo_unit->info_or_types_section;
begin_info_ptr = info_ptr = section->buffer + dwo_unit->offset.sect_off;
+ dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev;
init_cu_die_reader (&reader, cu, section, dwo_unit->dwo_file);
if (this_cu->is_debug_types)
{
ULONGEST signature;
- info_ptr = read_and_check_type_unit_head (&cu->header,
- section, info_ptr,
+ info_ptr = read_and_check_type_unit_head (&cu->header, section,
+ dwo_abbrev_section,
+ info_ptr,
&signature, NULL);
gdb_assert (sig_type->signature == signature);
gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
}
else
{
- info_ptr = read_and_check_comp_unit_head (&cu->header,
- section, info_ptr, 0);
+ info_ptr = read_and_check_comp_unit_head (&cu->header, section,
+ dwo_abbrev_section,
+ info_ptr, 0);
gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
gdb_assert (dwo_unit->length
== cu->header.length + cu->header.initial_length_size);
/* Discard the original CU's abbrev table, and read the DWO's. */
dwarf2_free_abbrev_table (cu);
- dwarf2_read_abbrevs (cu, &dwo_unit->dwo_file->sections.abbrev);
+ dwarf2_read_abbrevs (cu, dwo_abbrev_section);
/* Read in the die, but leave space to copy over the attributes
from the stub. This has the benefit of simplifying the rest of
cleanups = make_cleanup (free_stack_comp_unit, &cu);
begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
- info_ptr = read_and_check_comp_unit_head (&cu.header, section, info_ptr,
+ info_ptr = read_and_check_comp_unit_head (&cu.header, section,
+ abbrev_section, info_ptr,
this_cu->is_debug_types);
this_cu->length = cu.header.length + cu.header.initial_length_size;
struct obstack temp_obstack;
int i;
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Building psymtabs of objfile %s ...\n",
+ objfile->name);
+ }
+
dwarf2_per_objfile->reading_partial_symbols = 1;
dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
discard_cleanups (addrmap_cleanup);
do_cleanups (back_to);
+
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "Done building psymtabs of %s\n",
+ objfile->name);
}
/* die_reader_func for load_partial_comp_unit. */
{
struct dwarf2_queue_item *item, *next_item;
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Expanding one or more symtabs of objfile %s ...\n",
+ dwarf2_per_objfile->objfile->name);
+ }
+
/* The queue starts out with one item, but following a DIE reference
may load a new CU, adding it to the end of the queue. */
for (item = dwarf2_queue; item != NULL; dwarf2_queue = item = next_item)
}
dwarf2_queue_tail = NULL;
+
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Done expanding symtabs of %s.\n",
+ dwarf2_per_objfile->objfile->name);
+ }
}
/* Free all allocated queue entries. This function only releases anything if
struct cleanup *back_to, *delayed_list_cleanup;
CORE_ADDR baseaddr;
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Expanding symtab of %s at offset 0x%x\n",
+ per_cu->is_debug_types ? "TU" : "CU",
+ per_cu->offset.sect_off);
+ }
+
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
buildsym_init ();
VEC_safe_push (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus, per_cu);
do_cleanups (back_to);
+
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Done expanding symtab of %s at offset 0x%x\n",
+ per_cu->is_debug_types ? "TU" : "CU",
+ per_cu->offset.sect_off);
+ }
}
/* Process an imported unit DIE. */
complaint (&symfile_complaints,
_("CU refers to both DW_AT_GNU_macros and DW_AT_macro_info"));
- dwarf_decode_macros (cu->line_header, DW_UNSND (attr),
- comp_dir, abfd, cu,
- &dwarf2_per_objfile->macro, 1,
- ".debug_macro");
+ dwarf_decode_macros (cu, DW_UNSND (attr), comp_dir, 1);
}
else
{
{
unsigned int macro_offset = DW_UNSND (attr);
- dwarf_decode_macros (cu->line_header, macro_offset,
- comp_dir, abfd, cu,
- &dwarf2_per_objfile->macinfo, 0,
- ".debug_macinfo");
+ dwarf_decode_macros (cu, macro_offset, comp_dir, 0);
}
}
dwo_file->sections.loc.asection = sectp;
dwo_file->sections.loc.size = bfd_get_section_size (sectp);
}
+ else if (section_is_p (sectp->name, &names->macinfo_dwo))
+ {
+ dwo_file->sections.macinfo.asection = sectp;
+ dwo_file->sections.macinfo.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macro_dwo))
+ {
+ dwo_file->sections.macro.asection = sectp;
+ dwo_file->sections.macro.size = bfd_get_section_size (sectp);
+ }
else if (section_is_p (sectp->name, &names->str_dwo))
{
dwo_file->sections.str.asection = sectp;
If non-NULL, comp_dir is the DW_AT_comp_dir attribute.
SIGNATURE is the "dwo_id" of the CU (for consistency we use the same
nomenclature as TUs).
- The result is the DWO CU or NULL if we didn't find it
+ The result is a pointer to the dwo_unit object or NULL if we didn't find it
(dwo_id mismatch or couldn't find the DWO file). */
static struct dwo_unit *
/* Lookup the DWO TU referenced from THIS_TU in DWO file DWO_NAME.
If non-NULL, comp_dir is the DW_AT_comp_dir attribute.
- The result is the DWO CU or NULL if we didn't find it
+ The result is a pointer to the dwo_unit object or NULL if we didn't find it
(dwo_id mismatch or couldn't find the DWO file). */
static struct dwo_unit *
child_die = sibling_die (child_die))
{
struct call_site_parameter *parameter;
+ struct attribute *loc, *origin;
if (child_die->tag != DW_TAG_GNU_call_site_parameter)
{
gdb_assert (call_site->parameter_count < nparams);
parameter = &call_site->parameter[call_site->parameter_count];
- /* DW_AT_location specifies the register number. Value of the data
- assumed for the register is contained in DW_AT_GNU_call_site_value. */
+ /* DW_AT_location specifies the register number or DW_AT_abstract_origin
+ specifies DW_TAG_formal_parameter. Value of the data assumed for the
+ register is contained in DW_AT_GNU_call_site_value. */
+
+ loc = dwarf2_attr (child_die, DW_AT_location, cu);
+ origin = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
+ if (loc == NULL && origin != NULL && is_ref_attr (origin))
+ {
+ sect_offset offset;
- attr = dwarf2_attr (child_die, DW_AT_location, cu);
- if (!attr || !attr_form_is_block (attr))
+ parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET;
+ offset = dwarf2_get_ref_die_offset (origin);
+ gdb_assert (offset.sect_off >= cu->header.offset.sect_off);
+ parameter->u.param_offset.cu_off = (offset.sect_off
+ - cu->header.offset.sect_off);
+ }
+ else if (loc == NULL || origin != NULL || !attr_form_is_block (loc))
{
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_location for "
child_die->offset.sect_off, objfile->name);
continue;
}
- parameter->dwarf_reg = dwarf_block_to_dwarf_reg (DW_BLOCK (attr)->data,
- &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size]);
- if (parameter->dwarf_reg == -1
- && !dwarf_block_to_sp_offset (gdbarch, DW_BLOCK (attr)->data,
- &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size],
- ¶meter->fb_offset))
+ else
{
- complaint (&symfile_complaints,
- _("Only single DW_OP_reg or DW_OP_fbreg is supported "
- "for DW_FORM_block* DW_AT_location for "
- "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile->name);
- continue;
+ parameter->u.dwarf_reg = dwarf_block_to_dwarf_reg
+ (DW_BLOCK (loc)->data, &DW_BLOCK (loc)->data[DW_BLOCK (loc)->size]);
+ if (parameter->u.dwarf_reg != -1)
+ parameter->kind = CALL_SITE_PARAMETER_DWARF_REG;
+ else if (dwarf_block_to_sp_offset (gdbarch, DW_BLOCK (loc)->data,
+ &DW_BLOCK (loc)->data[DW_BLOCK (loc)->size],
+ ¶meter->u.fb_offset))
+ parameter->kind = CALL_SITE_PARAMETER_FB_OFFSET;
+ else
+ {
+ complaint (&symfile_complaints,
+ _("Only single DW_OP_reg or DW_OP_fbreg is supported "
+ "for DW_FORM_block* DW_AT_location is supported for "
+ "DW_TAG_GNU_call_site child DIE 0x%x "
+ "[in module %s]"),
+ child_die->offset.sect_off, objfile->name);
+ continue;
+ }
}
attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu);
attr = dwarf2_attr (die, DW_AT_ranges, cu);
if (attr != NULL)
{
+ unsigned int ranges_offset = DW_UNSND (attr) + cu->ranges_base;
+
/* Value of the DW_AT_ranges attribute is the offset in the
.debug_ranges section. */
- if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, pst))
+ if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, pst))
return 0;
/* Found discontinuous range of addresses. */
ret = -1;
/* The value of the DW_AT_ranges attribute is the offset of the
address range list in the .debug_ranges section. */
- unsigned long offset = DW_UNSND (attr);
+ unsigned long offset = DW_UNSND (attr) + cu->ranges_base;
gdb_byte *buffer = dwarf2_per_objfile->ranges.buffer + offset;
/* For some target architectures, but not others, the
break;
case DW_OP_GNU_addr_index:
+ case DW_OP_GNU_const_index:
stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i],
&bytes_read);
i += bytes_read;
}
static void
-dwarf_decode_macros (struct line_header *lh, unsigned int offset,
- char *comp_dir, bfd *abfd,
- struct dwarf2_cu *cu,
- struct dwarf2_section_info *section,
- int section_is_gnu, const char *section_name)
+dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
+ char *comp_dir, int section_is_gnu)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct line_header *lh = cu->line_header;
+ bfd *abfd;
gdb_byte *mac_ptr, *mac_end;
struct macro_source_file *current_file = 0;
enum dwarf_macro_record_type macinfo_type;
struct cleanup *cleanup;
htab_t include_hash;
void **slot;
+ struct dwarf2_section_info *section;
+ const char *section_name;
+
+ if (cu->dwo_unit != NULL)
+ {
+ if (section_is_gnu)
+ {
+ section = &cu->dwo_unit->dwo_file->sections.macro;
+ section_name = ".debug_macro.dwo";
+ }
+ else
+ {
+ section = &cu->dwo_unit->dwo_file->sections.macinfo;
+ section_name = ".debug_macinfo.dwo";
+ }
+ }
+ else
+ {
+ if (section_is_gnu)
+ {
+ section = &dwarf2_per_objfile->macro;
+ section_name = ".debug_macro";
+ }
+ else
+ {
+ section = &dwarf2_per_objfile->macinfo;
+ section_name = ".debug_macinfo";
+ }
+ }
dwarf2_read_section (objfile, section);
if (section->buffer == NULL)
complaint (&symfile_complaints, _("missing %s section"), section_name);
return;
}
+ abfd = section->asection->owner;
/* First pass: Find the name of the base filename.
This filename is needed in order to process all macros whose definition
per_cu_header_read_in (struct comp_unit_head *cu_headerp,
struct dwarf2_per_cu_data *per_cu)
{
- struct objfile *objfile;
- struct dwarf2_per_objfile *per_objfile;
gdb_byte *info_ptr;
if (per_cu->cu)
return &per_cu->cu->header;
- objfile = per_cu->objfile;
- per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
- info_ptr = per_objfile->info.buffer + per_cu->offset.sect_off;
+ info_ptr = per_cu->info_or_types_section->buffer + per_cu->offset.sect_off;
memset (cu_headerp, 0, sizeof (*cu_headerp));
- read_comp_unit_head (cu_headerp, info_ptr, objfile->obfd);
+ read_comp_unit_head (cu_headerp, info_ptr, per_cu->objfile->obfd);
return cu_headerp;
}
xfree (old_entries);
}
-/* Add an entry to SYMTAB. NAME is the name of the symbol. CU_INDEX
- is the index of the CU in which the symbol appears. */
+/* Add an entry to SYMTAB. NAME is the name of the symbol.
+ CU_INDEX is the index of the CU in which the symbol appears.
+ IS_STATIC is one if the symbol is static, otherwise zero (global). */
static void
add_index_entry (struct mapped_symtab *symtab, const char *name,
+ int is_static, gdb_index_symbol_kind kind,
offset_type cu_index)
{
struct symtab_index_entry **slot;
+ offset_type cu_index_and_attrs;
++symtab->n_elements;
if (4 * symtab->n_elements / 3 >= symtab->size)
{
*slot = XNEW (struct symtab_index_entry);
(*slot)->name = name;
+ /* index_offset is set later. */
(*slot)->cu_indices = NULL;
}
- /* Don't push an index twice. Due to how we add entries we only
- have to check the last one. */
- if (VEC_empty (offset_type, (*slot)->cu_indices)
- || VEC_last (offset_type, (*slot)->cu_indices) != cu_index)
- VEC_safe_push (offset_type, (*slot)->cu_indices, cu_index);
+
+ cu_index_and_attrs = 0;
+ DW2_GDB_INDEX_CU_SET_VALUE (cu_index_and_attrs, cu_index);
+ DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE (cu_index_and_attrs, is_static);
+ DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE (cu_index_and_attrs, kind);
+
+ /* We don't want to record an index value twice as we want to avoid the
+ duplication.
+ We process all global symbols and then all static symbols
+ (which would allow us to avoid the duplication by only having to check
+ the last entry pushed), but a symbol could have multiple kinds in one CU.
+ To keep things simple we don't worry about the duplication here and
+ sort and uniqufy the list after we've processed all symbols. */
+ VEC_safe_push (offset_type, (*slot)->cu_indices, cu_index_and_attrs);
+}
+
+/* qsort helper routine for uniquify_cu_indices. */
+
+static int
+offset_type_compare (const void *ap, const void *bp)
+{
+ offset_type a = *(offset_type *) ap;
+ offset_type b = *(offset_type *) bp;
+
+ return (a > b) - (b > a);
+}
+
+/* Sort and remove duplicates of all symbols' cu_indices lists. */
+
+static void
+uniquify_cu_indices (struct mapped_symtab *symtab)
+{
+ int i;
+
+ for (i = 0; i < symtab->size; ++i)
+ {
+ struct symtab_index_entry *entry = symtab->data[i];
+
+ if (entry
+ && entry->cu_indices != NULL)
+ {
+ unsigned int next_to_insert, next_to_check;
+ offset_type last_value;
+
+ qsort (VEC_address (offset_type, entry->cu_indices),
+ VEC_length (offset_type, entry->cu_indices),
+ sizeof (offset_type), offset_type_compare);
+
+ last_value = VEC_index (offset_type, entry->cu_indices, 0);
+ next_to_insert = 1;
+ for (next_to_check = 1;
+ next_to_check < VEC_length (offset_type, entry->cu_indices);
+ ++next_to_check)
+ {
+ if (VEC_index (offset_type, entry->cu_indices, next_to_check)
+ != last_value)
+ {
+ last_value = VEC_index (offset_type, entry->cu_indices,
+ next_to_check);
+ VEC_replace (offset_type, entry->cu_indices, next_to_insert,
+ last_value);
+ ++next_to_insert;
+ }
+ }
+ VEC_truncate (offset_type, entry->cu_indices, next_to_insert);
+ }
+ }
}
/* Add a vector of indices to the constant pool. */
addrmap_index_data.previous_cu_index);
}
+/* Return the symbol kind of PSYM. */
+
+static gdb_index_symbol_kind
+symbol_kind (struct partial_symbol *psym)
+{
+ domain_enum domain = PSYMBOL_DOMAIN (psym);
+ enum address_class aclass = PSYMBOL_CLASS (psym);
+
+ switch (domain)
+ {
+ case VAR_DOMAIN:
+ switch (aclass)
+ {
+ case LOC_BLOCK:
+ return GDB_INDEX_SYMBOL_KIND_FUNCTION;
+ case LOC_TYPEDEF:
+ return GDB_INDEX_SYMBOL_KIND_TYPE;
+ case LOC_COMPUTED:
+ case LOC_CONST_BYTES:
+ case LOC_OPTIMIZED_OUT:
+ case LOC_STATIC:
+ return GDB_INDEX_SYMBOL_KIND_VARIABLE;
+ case LOC_CONST:
+ /* Note: It's currently impossible to recognize psyms as enum values
+ short of reading the type info. For now punt. */
+ return GDB_INDEX_SYMBOL_KIND_VARIABLE;
+ default:
+ /* There are other LOC_FOO values that one might want to classify
+ as variables, but dwarf2read.c doesn't currently use them. */
+ return GDB_INDEX_SYMBOL_KIND_OTHER;
+ }
+ case STRUCT_DOMAIN:
+ return GDB_INDEX_SYMBOL_KIND_TYPE;
+ default:
+ return GDB_INDEX_SYMBOL_KIND_OTHER;
+ }
+}
+
/* Add a list of partial symbols to SYMTAB. */
static void
{
for (; count-- > 0; ++psymp)
{
- void **slot, *lookup;
+ struct partial_symbol *psym = *psymp;
+ void **slot;
- if (SYMBOL_LANGUAGE (*psymp) == language_ada)
+ if (SYMBOL_LANGUAGE (psym) == language_ada)
error (_("Ada is not currently supported by the index"));
- /* We only want to add a given psymbol once. However, we also
- want to account for whether it is global or static. So, we
- may add it twice, using slightly different values. */
- if (is_static)
- {
- uintptr_t val = 1 | (uintptr_t) *psymp;
-
- lookup = (void *) val;
- }
- else
- lookup = *psymp;
-
/* Only add a given psymbol once. */
- slot = htab_find_slot (psyms_seen, lookup, INSERT);
+ slot = htab_find_slot (psyms_seen, psym, INSERT);
if (!*slot)
{
- *slot = lookup;
- add_index_entry (symtab, SYMBOL_SEARCH_NAME (*psymp), cu_index);
+ gdb_index_symbol_kind kind = symbol_kind (psym);
+
+ *slot = psym;
+ add_index_entry (symtab, SYMBOL_SEARCH_NAME (psym),
+ is_static, kind, cu_index);
}
}
}
write_one_signatured_type, &sig_data);
}
+ /* Now that we've processed all symbols we can shrink their cu_indices
+ lists. */
+ uniquify_cu_indices (symtab);
+
obstack_init (&constant_pool);
make_cleanup_obstack_free (&constant_pool);
obstack_init (&symtab_obstack);
total_len = size_of_contents;
/* The version number. */
- val = MAYBE_SWAP (6);
+ val = MAYBE_SWAP (7);
obstack_grow (&contents, &val, sizeof (val));
/* The offset of the CU list from the start of the file. */
&set_dwarf2_cmdlist,
&show_dwarf2_cmdlist);
+ add_setshow_boolean_cmd ("dwarf2-read", no_class, &dwarf2_read_debug, _("\
+Set debugging of the dwarf2 reader."), _("\
+Show debugging of the dwarf2 reader."), _("\
+When enabled, debugging messages are printed during dwarf2 reading\n\
+and symtab expansion."),
+ NULL,
+ NULL,
+ &setdebuglist, &showdebuglist);
+
add_setshow_zinteger_cmd ("dwarf2-die", no_class, &dwarf2_die_debug, _("\
Set debugging of the dwarf2 DIE reader."), _("\
Show debugging of the dwarf2 DIE reader."), _("\