// gdb-index.cc -- generate .gdb_index section for fast debug lookup
-// Copyright 2012 Free Software Foundation, Inc.
+// Copyright (C) 2012-2020 Free Software Foundation, Inc.
// Written by Cary Coutant <ccoutant@google.com>.
// This file is part of gold.
namespace gold
{
-const int gdb_index_version = 5;
+const int gdb_index_version = 7;
// Sizes of various records in the .gdb_index section.
const int gdb_index_offset_size = 4;
// Visit a type unit.
virtual void
- visit_type_unit(off_t tu_offset, off_t type_offset, uint64_t signature,
- Dwarf_die*);
+ visit_type_unit(off_t tu_offset, off_t tu_length, off_t type_offset,
+ uint64_t signature, Dwarf_die*);
private:
// A map for recording DIEs we've seen that may be referred to be
// Process a type unit and parse its child DIE.
void
-Gdb_index_info_reader::visit_type_unit(off_t tu_offset, off_t type_offset,
- uint64_t signature, Dwarf_die* root_die)
+Gdb_index_info_reader::visit_type_unit(off_t tu_offset, off_t,
+ off_t type_offset, uint64_t signature,
+ Dwarf_die* root_die)
{
++Gdb_index_info_reader::dwarf_tu_count;
// Use a negative index to flag this as a TU instead of a CU.
case elfcpp::DW_TAG_compile_unit:
case elfcpp::DW_TAG_type_unit:
this->cu_language_ = die->int_attribute(elfcpp::DW_AT_language);
- // Check for languages that require specialized knowledge to
- // construct fully-qualified names, that we don't yet support.
- if (this->cu_language_ == elfcpp::DW_LANG_Ada83
- || this->cu_language_ == elfcpp::DW_LANG_Fortran77
- || this->cu_language_ == elfcpp::DW_LANG_Fortran90
- || this->cu_language_ == elfcpp::DW_LANG_Java
- || this->cu_language_ == elfcpp::DW_LANG_Ada95
- || this->cu_language_ == elfcpp::DW_LANG_Fortran95)
- {
- gold_warning(_("%s: --gdb-index currently supports "
- "only C and C++ languages"),
- this->object()->name().c_str());
- return;
- }
if (die->tag() == elfcpp::DW_TAG_compile_unit)
this->record_cu_ranges(die);
// If there is a pubnames and/or pubtypes section for this
// info to extract the names.
if (!this->read_pubnames_and_pubtypes(die))
{
+ // Check for languages that require specialized knowledge to
+ // construct fully-qualified names, that we don't yet support.
+ if (this->cu_language_ == elfcpp::DW_LANG_Ada83
+ || this->cu_language_ == elfcpp::DW_LANG_Fortran77
+ || this->cu_language_ == elfcpp::DW_LANG_Fortran90
+ || this->cu_language_ == elfcpp::DW_LANG_Java
+ || this->cu_language_ == elfcpp::DW_LANG_Ada95
+ || this->cu_language_ == elfcpp::DW_LANG_Fortran95
+ || this->cu_language_ == elfcpp::DW_LANG_Fortran03
+ || this->cu_language_ == elfcpp::DW_LANG_Fortran08)
+ {
+ gold_warning(_("%s: --gdb-index currently supports "
+ "only C and C++ languages"),
+ this->object()->name().c_str());
+ return;
+ }
if (die->tag() == elfcpp::DW_TAG_compile_unit)
++Gdb_index_info_reader::dwarf_cu_nopubnames_count;
else
this->object()->name().c_str());
return;
}
-
}
// Visit the children of PARENT, looking for symbols to add to the index.
// If the DIE is not a declaration, add it to the index.
std::string full_name = this->get_qualified_name(die, context);
if (!full_name.empty())
- this->gdb_index_->add_symbol(this->cu_index_, full_name.c_str());
+ this->gdb_index_->add_symbol(this->cu_index_,
+ full_name.c_str(), 0);
}
break;
case elfcpp::DW_TAG_typedef:
full_name = this->get_qualified_name(die, context);
if (!full_name.empty())
this->gdb_index_->add_symbol(this->cu_index_,
- full_name.c_str());
+ full_name.c_str(), 0);
}
// We're interested in the children only for namespaces and
return false;
while (true)
{
- const char* name = table->next_name();
+ uint8_t flag_byte;
+ const char* name = table->next_name(&flag_byte);
if (name == NULL)
break;
- this->gdb_index_->add_symbol(this->cu_index_, name);
+ this->gdb_index_->add_symbol(this->cu_index_, name, flag_byte);
}
return true;
}
bool
Gdb_index_info_reader::read_pubnames_and_pubtypes(Dwarf_die* die)
{
+ // If this is a skeleton debug-type die (generated via
+ // -gsplit-dwarf), then the associated pubnames should have been
+ // read along with the corresponding CU. In any case, there isn't
+ // enough info inside to build a gdb index entry.
+ if (die->tag() == elfcpp::DW_TAG_type_unit
+ && die->string_attribute(elfcpp::DW_AT_GNU_dwo_name))
+ return true;
+
// We use stmt_list_off as a unique identifier for the
// compilation unit and its associated type units.
unsigned int shndx;
// Add a symbol.
void
-Gdb_index::add_symbol(int cu_index, const char* sym_name)
+Gdb_index::add_symbol(int cu_index, const char* sym_name, uint8_t flags)
{
unsigned int hash = mapped_index_string_hash(
reinterpret_cast<const unsigned char*>(sym_name));
// if it's not already on the list. We only need to
// check the last added entry.
Cu_vector* cu_vec = this->cu_vector_list_[found->cu_vector_index];
- if (cu_vec->size() == 0 || cu_vec->back() != cu_index)
- cu_vec->push_back(cu_index);
+ if (cu_vec->size() == 0
+ || cu_vec->back().first != cu_index
+ || cu_vec->back().second != flags)
+ cu_vec->push_back(std::make_pair(cu_index, flags));
}
// Return TRUE if we have already processed the pubnames associated
pov += 4;
for (unsigned int j = 0; j < cu_vec->size(); ++j)
{
- int cu_index = (*cu_vec)[j];
+ int cu_index = (*cu_vec)[j].first;
+ uint8_t flags = (*cu_vec)[j].second;
if (cu_index < 0)
cu_index = comp_units_count + (-1 - cu_index);
+ cu_index |= flags << 24;
elfcpp::Swap<32, false>::writeval(pov, cu_index);
pov += 4;
}