/* Reading code for .debug_names

   Copyright (C) 2023-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "read-debug-names.h"
#include "dwarf2/aranges.h"
#include "dwarf2/cooked-index.h"

#include "complaints.h"
#include "cp-support.h"
#include "dwz.h"
#include "mapped-index.h"
#include "read.h"
#include "stringify.h"
#include "extract-store-integer.h"
#include "gdbsupport/thread-pool.h"

/* This is just like cooked_index_functions, but overrides a single
   method so the test suite can distinguish the .debug_names case from
   the ordinary case.  */
struct dwarf2_debug_names_index : public cooked_index_functions
{
  /* This dumps minimal information about .debug_names.  It is called
     via "mt print objfiles".  The gdb.dwarf2/gdb-index.exp testcase
     uses this to verify that .debug_names has been loaded.  */
  void dump (struct objfile *objfile) override
  {
    gdb_printf (".debug_names: exists\n");
    cooked_index_functions::dump (objfile);
  }
};

/* This is like a cooked index, but as it has been ingested from
   .debug_names, it can't be used to write out an index.  */
class debug_names_index : public cooked_index
{
public:

  using cooked_index::cooked_index;

  cooked_index *index_for_writing () override
  { return nullptr; }

  quick_symbol_functions_up make_quick_functions () const override
  { return quick_symbol_functions_up (new dwarf2_debug_names_index); }
};

/* A description of the mapped .debug_names.  */

struct mapped_debug_names_reader
{
  const gdb_byte *scan_one_entry (const char *name,
				  const gdb_byte *entry,
				  cooked_index_entry **result,
				  std::optional<ULONGEST> &parent);
  void scan_entries (uint32_t index, const char *name, const gdb_byte *entry);
  void scan_all_names ();

  dwarf2_per_objfile *per_objfile = nullptr;
  bfd *abfd = nullptr;
  bfd_endian dwarf5_byte_order {};
  bool dwarf5_is_dwarf64 = false;

  /* True if the augmentation string indicates the index was produced by
     GDB.  */
  bool augmentation_is_gdb = false;

  /* If AUGMENTATION_IS_GDB is true, this indicates the version.  Otherwise,
     this value is meaningless.  */
  unsigned int gdb_augmentation_version = 0;

  uint8_t offset_size = 0;
  uint32_t cu_count = 0;
  uint32_t tu_count = 0, bucket_count = 0, name_count = 0;
  const gdb_byte *cu_table_reordered = nullptr;
  const gdb_byte *tu_table_reordered = nullptr;
  const uint32_t *bucket_table_reordered = nullptr;
  const uint32_t *hash_table_reordered = nullptr;
  const gdb_byte *name_table_string_offs_reordered = nullptr;
  const gdb_byte *name_table_entry_offs_reordered = nullptr;
  const gdb_byte *entry_pool = nullptr;

  struct index_val
  {
    ULONGEST dwarf_tag;
    struct attr
    {
      /* Attribute name DW_IDX_*.  */
      ULONGEST dw_idx;

      /* Attribute form DW_FORM_*.  */
      ULONGEST form;

      /* Value if FORM is DW_FORM_implicit_const.  */
      LONGEST implicit_const;
    };
    std::vector<attr> attr_vec;
  };

  gdb::unordered_map<ULONGEST, index_val> abbrev_map;

  /* Even though the scanning of .debug_names and creation of the cooked index
     entries is done serially, we create multiple shards so that the
     finalization step can be parallelized.  The shards are filled in a round
     robin fashion.  */
  std::vector<cooked_index_shard_up> shards;

  /* Next shard to insert an entry in.  */
  int next_shard = 0;

  /* Maps entry pool offsets to cooked index entries.  */
  gdb::unordered_map<ULONGEST, cooked_index_entry *>
    entry_pool_offsets_to_entries;

  /* Cooked index entries for which the parent needs to be resolved.

     The second value of the pair is the DW_IDX_parent value.  Its meaning
     depends on the augmentation string:

       - GDB2: an index in the name table
       - GDB3: an offset offset into the entry pool  */
  std::vector<std::pair<cooked_index_entry *, ULONGEST>> needs_parent;

  /* All the cooked index entries created, in the same order and groups as
     listed in the name table.

     The size of the outer vector is equal to the number of entries in the name
     table (NAME_COUNT).  */
  std::vector<std::vector<cooked_index_entry *>> all_entries;
};

/* Scan a single entry from the entries table.  Set *RESULT and PARENT
   (if needed) and return the updated pointer on success, or return
   nullptr on error, or at the end of the table.  */

const gdb_byte *
mapped_debug_names_reader::scan_one_entry (const char *name,
					   const gdb_byte *entry,
					   cooked_index_entry **result,
					   std::optional<ULONGEST> &parent)
{
  unsigned int bytes_read;
  const auto offset_in_entry_pool = entry - entry_pool;
  const ULONGEST abbrev = read_unsigned_leb128 (abfd, entry, &bytes_read);
  entry += bytes_read;
  if (abbrev == 0)
    return nullptr;

  const auto indexval_it = abbrev_map.find (abbrev);
  if (indexval_it == abbrev_map.cend ())
    {
      complaint (_("Wrong .debug_names undefined abbrev code %s "
		   "[in module %s]"),
		 pulongest (abbrev), bfd_get_filename (abfd));
      return nullptr;
    }

  const auto &indexval = indexval_it->second;
  cooked_index_flag flags = 0;
  sect_offset die_offset {};
  enum language lang = language_unknown;
  dwarf2_per_cu *per_cu = nullptr;
  for (const auto &attr : indexval.attr_vec)
    {
      ULONGEST ull;
      switch (attr.form)
	{
	case DW_FORM_implicit_const:
	  ull = attr.implicit_const;
	  break;
	case DW_FORM_flag_present:
	  ull = 1;
	  break;
	case DW_FORM_udata:
	  ull = read_unsigned_leb128 (abfd, entry, &bytes_read);
	  entry += bytes_read;
	  break;
	case DW_FORM_ref_addr:
	  ull = read_offset (abfd, entry, offset_size);
	  entry += offset_size;
	  break;
	case DW_FORM_data1:
	  ull = *entry++;
	  break;
	case DW_FORM_data2:
	  ull = read_2_bytes (abfd, entry);
	  entry += 2;
	  break;
	case DW_FORM_data4:
	  ull = read_4_bytes (abfd, entry);
	  entry += 4;
	  break;
	case DW_FORM_ref4:
	  ull = read_4_bytes (abfd, entry);
	  entry += 4;
	  break;
	case DW_FORM_ref8:
	  ull = read_8_bytes (abfd, entry);
	  entry += 8;
	  break;
	case DW_FORM_ref_sig8:
	  ull = read_8_bytes (abfd, entry);
	  entry += 8;
	  break;
	default:
	  /* A warning instead of a complaint, because this one is
	     more like a bug in gdb.  */
	  warning (_("Unsupported .debug_names form %s [in module %s].\n"
		     "This normally should not happen, please file a bug report."),
		   dwarf_form_name (attr.form),
		   bfd_get_filename (abfd));
	  return nullptr;
	}
      switch (attr.dw_idx)
	{
	case DW_IDX_compile_unit:
	  {
	    /* Don't crash on bad data.  */
	    if (ull >= per_objfile->per_bfd->all_comp_units.size ())
	      {
		complaint (_(".debug_names entry has bad CU index %s"
			     " [in module %s]"),
			   pulongest (ull),
			   bfd_get_filename (abfd));
		continue;
	      }
	  }
	  per_cu = per_objfile->per_bfd->get_cu (ull);
	  break;
	case DW_IDX_type_unit:
	  /* Don't crash on bad data.  */
	  if (ull >= per_objfile->per_bfd->all_type_units.size ())
	    {
	      complaint (_(".debug_names entry has bad TU index %s"
			   " [in module %s]"),
			 pulongest (ull),
			 bfd_get_filename (abfd));
	      continue;
	    }
	  {
	    int nr_cus = per_objfile->per_bfd->all_comp_units.size ();
	    per_cu = per_objfile->per_bfd->get_cu (nr_cus + ull);
	  }
	  break;
	case DW_IDX_die_offset:
	  die_offset = sect_offset (ull);
	  /* In a per-CU index (as opposed to a per-module index), index
	     entries without CU attribute implicitly refer to the single CU.  */
	  if (per_cu == NULL)
	    per_cu = per_objfile->per_bfd->get_cu (0);
	  break;
	case DW_IDX_parent:
	  parent = ull;
	  break;
	case DW_IDX_GNU_internal:
	  if (augmentation_is_gdb && ull != 0)
	    flags |= IS_STATIC;
	  break;
	case DW_IDX_GNU_main:
	  if (augmentation_is_gdb && ull != 0)
	    flags |= IS_MAIN;
	  break;
	case DW_IDX_GNU_language:
	  if (augmentation_is_gdb)
	    lang = dwarf_lang_to_enum_language (ull);
	  break;
	case DW_IDX_GNU_linkage_name:
	  if (augmentation_is_gdb && ull != 0)
	    flags |= IS_LINKAGE;
	  break;
	}
    }

  /* Skip if we couldn't find a valid CU/TU index.  */
  if (per_cu != nullptr)
    {
      *result
	= shards[next_shard]->add (die_offset, (dwarf_tag) indexval.dwarf_tag,
				   flags, lang, name, nullptr, per_cu);

      ++next_shard;
      if (next_shard == shards.size ())
	next_shard = 0;

      entry_pool_offsets_to_entries.emplace (offset_in_entry_pool, *result);
    }

  return entry;
}

/* Scan all the entries for NAME, at name slot INDEX.  */

void
mapped_debug_names_reader::scan_entries (uint32_t index,
					 const char *name,
					 const gdb_byte *entry)
{
  std::vector<cooked_index_entry *> these_entries;
  
  while (true)
    {
      std::optional<ULONGEST> parent;
      cooked_index_entry *this_entry;
      entry = scan_one_entry (name, entry, &this_entry, parent);

      if (entry == nullptr)
	break;

      these_entries.push_back (this_entry);
      if (parent.has_value ())
	needs_parent.emplace_back (this_entry, *parent);
    }

  all_entries[index] = std::move (these_entries);
}

/* Scan the name table and create all the entries.  */

void
mapped_debug_names_reader::scan_all_names ()
{
  all_entries.resize (name_count);

  /* In the first pass, create all the entries.  */
  for (uint32_t i = 0; i < name_count; ++i)
    {
      const ULONGEST namei_string_offs
	= extract_unsigned_integer ((name_table_string_offs_reordered
				     + i * offset_size),
				    offset_size, dwarf5_byte_order);
      const char *name = read_indirect_string_at_offset (per_objfile,
							 namei_string_offs);

      const ULONGEST namei_entry_offs
	= extract_unsigned_integer ((name_table_entry_offs_reordered
				     + i * offset_size),
				    offset_size, dwarf5_byte_order);
      const gdb_byte *entry = entry_pool + namei_entry_offs;

      scan_entries (i, name, entry);
    }

  /* Resolve the parent pointers for all entries that have a parent.

     If the augmentation string is "GDB2", the DW_IDX_parent value is an index
     into the name table.  Since there may be multiple index entries associated
     to that name, we have a little heuristic to figure out which is the right
     one.

     Otherwise, the DW_IDX_parent value is an offset into the entry pool, which
     is not ambiguous.  */
  for (auto &[entry, parent_val] : needs_parent)
    {
      if (augmentation_is_gdb && gdb_augmentation_version == 2)
	{
	  /* Name entries are indexed from 1 in DWARF.  */
	  std::vector<cooked_index_entry *> &entries
	    = all_entries[parent_val - 1];

	  for (const auto &parent : entries)
	    if (parent->lang == entry->lang)
	      {
		entry->set_parent (parent);
		break;
	      }
	}
      else
	{
	  const auto parent_it
	    = entry_pool_offsets_to_entries.find (parent_val);

	  if (parent_it == entry_pool_offsets_to_entries.cend ())
	    {
	      complaint (_ ("Parent entry not found for .debug_names entry"));
	      continue;
	    }

	  entry->set_parent (parent_it->second);
	}
    }
}

/* A reader for .debug_names.  */

struct cooked_index_worker_debug_names : public cooked_index_worker
{
  cooked_index_worker_debug_names (dwarf2_per_objfile *per_objfile,
			    mapped_debug_names_reader &&map)
    : cooked_index_worker (per_objfile),
      m_map (std::move (map))
  { }

  void do_reading () override;

  mapped_debug_names_reader m_map;
};

void
cooked_index_worker_debug_names::do_reading ()
{
  complaint_interceptor complaint_handler;
  std::vector<gdb_exception> exceptions;
  try
    {
      m_map.scan_all_names ();
    }
  catch (const gdb_exception &exc)
    {
      exceptions.push_back (std::move (exc));
    }

  m_results.emplace_back (nullptr,
			  complaint_handler.release (),
			  std::move (exceptions),
			  parent_map ());

  dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd;
  cooked_index *table
    = (gdb::checked_static_cast<cooked_index *>
       (per_bfd->index_table.get ()));

  /* Note that this code never uses IS_PARENT_DEFERRED, so it is safe
     to pass nullptr here.  */
  table->set_contents (std::move (m_map.shards), &m_warnings, nullptr);

  bfd_thread_cleanup ();
}

/* Check the signatured type hash table from .debug_names.  */

static bool
check_signatured_type_table_from_debug_names
  (dwarf2_per_objfile *per_objfile,
   const mapped_debug_names_reader &map,
   struct dwarf2_section_info *section)
{
  struct objfile *objfile = per_objfile->objfile;
  dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
  int nr_cus = per_bfd->all_comp_units.size ();
  int nr_cus_tus = per_bfd->all_units.size ();

  section->read (objfile);

  uint32_t j = nr_cus;
  for (uint32_t i = 0; i < map.tu_count; ++i)
    {
      sect_offset sect_off
	= (sect_offset) (extract_unsigned_integer
			 (map.tu_table_reordered + i * map.offset_size,
			  map.offset_size,
			  map.dwarf5_byte_order));

      bool found = false;
      for (; j < nr_cus_tus; j++)
	if (per_bfd->get_cu (j)->sect_off == sect_off)
	  {
	    found = true;
	    break;
	  }
      if (!found)
	{
	  warning (_("Section .debug_names has incorrect entry in TU table,"
		     " ignoring .debug_names."));
	  return false;
	}
      per_bfd->all_comp_units_index_tus.push_back (per_bfd->get_cu (j));
    }
  return true;
}

/* DWARF-5 debug_names reader.  */

/* A helper function that reads the .debug_names section in SECTION
   and fills in MAP.  FILENAME is the name of the file containing the
   section; it is used for error reporting.

   Returns true if all went well, false otherwise.  */

static bool
read_debug_names_from_section (dwarf2_per_objfile *per_objfile,
			       const char *filename,
			       struct dwarf2_section_info *section,
			       mapped_debug_names_reader &map)
{
  struct objfile *objfile = per_objfile->objfile;

  if (section->empty ())
    return false;

  /* 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 false;

  section->read (objfile);

  map.per_objfile = per_objfile;
  map.dwarf5_byte_order = gdbarch_byte_order (objfile->arch ());

  const gdb_byte *addr = section->buffer;

  bfd *abfd = section->get_bfd_owner ();
  map.abfd = abfd;

  unsigned int bytes_read;
  LONGEST length = read_initial_length (abfd, addr, &bytes_read);
  addr += bytes_read;

  map.dwarf5_is_dwarf64 = bytes_read != 4;
  map.offset_size = map.dwarf5_is_dwarf64 ? 8 : 4;
  if (bytes_read + length != section->size)
    {
      /* There may be multiple per-CU indices.  */
      warning (_("Section .debug_names in %s length %s does not match "
		 "section length %s, ignoring .debug_names."),
	       filename, plongest (bytes_read + length),
	       pulongest (section->size));
      return false;
    }

  /* The version number.  */
  uint16_t version = read_2_bytes (abfd, addr);
  addr += 2;
  if (version != 5)
    {
      warning (_("Section .debug_names in %s has unsupported version %d, "
		 "ignoring .debug_names."),
	       filename, version);
      return false;
    }

  /* Padding.  */
  uint16_t padding = read_2_bytes (abfd, addr);
  addr += 2;
  if (padding != 0)
    {
      warning (_("Section .debug_names in %s has unsupported padding %d, "
		 "ignoring .debug_names."),
	       filename, padding);
      return false;
    }

  /* comp_unit_count - The number of CUs in the CU list.  */
  map.cu_count = read_4_bytes (abfd, addr);
  addr += 4;

  /* local_type_unit_count - The number of TUs in the local TU
     list.  */
  map.tu_count = read_4_bytes (abfd, addr);
  addr += 4;

  /* foreign_type_unit_count - The number of TUs in the foreign TU
     list.  */
  uint32_t foreign_tu_count = read_4_bytes (abfd, addr);
  addr += 4;
  if (foreign_tu_count != 0)
    {
      warning (_("Section .debug_names in %s has unsupported %lu foreign TUs, "
		 "ignoring .debug_names."),
	       filename, static_cast<unsigned long> (foreign_tu_count));
      return false;
    }

  /* bucket_count - The number of hash buckets in the hash lookup
     table.  */
  map.bucket_count = read_4_bytes (abfd, addr);
  addr += 4;

  /* name_count - The number of unique names in the index.  */
  map.name_count = read_4_bytes (abfd, addr);
  addr += 4;

  /* abbrev_table_size - The size in bytes of the abbreviations
     table.  */
  uint32_t abbrev_table_size = read_4_bytes (abfd, addr);
  addr += 4;

  /* augmentation_string_size - The size in bytes of the augmentation
     string.  This value is rounded up to a multiple of 4.  */
  uint32_t augmentation_string_size = read_4_bytes (abfd, addr);
  addr += 4;
  augmentation_string_size += (-augmentation_string_size) & 3;

  const auto augmentation_string
    = gdb::make_array_view (addr, augmentation_string_size);

  if (augmentation_string == gdb::make_array_view (dwarf5_augmentation_1))
    {
      warning (_(".debug_names created by an old version of gdb; ignoring"));
      return false;
    }
  else if (augmentation_string == gdb::make_array_view (dwarf5_augmentation_2))
    {
      map.augmentation_is_gdb = true;
      map.gdb_augmentation_version = 2;
    }
  else if (augmentation_string == gdb::make_array_view (dwarf5_augmentation_3))
    {
      map.augmentation_is_gdb = true;
      map.gdb_augmentation_version = 3;
    }

  if (!map.augmentation_is_gdb)
    {
      warning (_(".debug_names not created by gdb; ignoring"));
      return false;
    }

  /* Skip past augmentation string.  */
  addr += augmentation_string_size;

  /* List of CUs */
  map.cu_table_reordered = addr;
  addr += map.cu_count * map.offset_size;

  /* List of Local TUs */
  map.tu_table_reordered = addr;
  addr += map.tu_count * map.offset_size;

  /* Hash Lookup Table */
  map.bucket_table_reordered = reinterpret_cast<const uint32_t *> (addr);
  addr += map.bucket_count * 4;
  map.hash_table_reordered = reinterpret_cast<const uint32_t *> (addr);
  if (map.bucket_count != 0)
    addr += map.name_count * 4;

  /* Name Table */
  map.name_table_string_offs_reordered = addr;
  addr += map.name_count * map.offset_size;
  map.name_table_entry_offs_reordered = addr;
  addr += map.name_count * map.offset_size;

  const gdb_byte *abbrev_table_start = addr;
  for (;;)
    {
      const ULONGEST index_num = read_unsigned_leb128 (abfd, addr, &bytes_read);
      addr += bytes_read;
      if (index_num == 0)
	break;

      const auto insertpair
	= map.abbrev_map.emplace (index_num, mapped_debug_names_reader::index_val ());
      if (!insertpair.second)
	{
	  warning (_("Section .debug_names in %s has duplicate index %s, "
		     "ignoring .debug_names."),
		   filename, pulongest (index_num));
	  return false;
	}
      mapped_debug_names_reader::index_val &indexval = insertpair.first->second;
      indexval.dwarf_tag = read_unsigned_leb128 (abfd, addr, &bytes_read);
      addr += bytes_read;

      for (;;)
	{
	  mapped_debug_names_reader::index_val::attr attr;
	  attr.dw_idx = read_unsigned_leb128 (abfd, addr, &bytes_read);
	  addr += bytes_read;
	  attr.form = read_unsigned_leb128 (abfd, addr, &bytes_read);
	  addr += bytes_read;
	  if (attr.form == DW_FORM_implicit_const)
	    {
	      attr.implicit_const = read_signed_leb128 (abfd, addr,
							&bytes_read);
	      addr += bytes_read;
	    }
	  if (attr.dw_idx == 0 && attr.form == 0)
	    break;
	  indexval.attr_vec.push_back (std::move (attr));
	}
    }
  if (addr != abbrev_table_start + abbrev_table_size)
    {
      warning (_("Section .debug_names in %s has abbreviation_table "
		 "of size %s vs. written as %u, ignoring .debug_names."),
	       filename, plongest (addr - abbrev_table_start),
	       abbrev_table_size);
      return false;
    }
  map.entry_pool = addr;

  return true;
}

/* A helper for check_cus_from_debug_names that handles the MAP's CU
   list.  */

static bool
check_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd,
				  const mapped_debug_names_reader &map,
				  dwarf2_section_info &section,
				  bool is_dwz)
{
  int nr_cus = per_bfd->all_comp_units.size ();

  if (!map.augmentation_is_gdb)
    {
      uint32_t j = 0;
      for (uint32_t i = 0; i < map.cu_count; ++i)
	{
	  sect_offset sect_off
	    = (sect_offset) (extract_unsigned_integer
			     (map.cu_table_reordered + i * map.offset_size,
			      map.offset_size,
			      map.dwarf5_byte_order));
	  bool found = false;
	  for (; j < nr_cus; j++)
	    if (per_bfd->get_cu (j)->sect_off == sect_off)
	      {
		found = true;
		break;
	      }
	  if (!found)
	    {
	      warning (_("Section .debug_names has incorrect entry in CU table,"
			 " ignoring .debug_names."));
	      return false;
	    }
	  per_bfd->all_comp_units_index_cus.push_back (per_bfd->get_cu (j));
	}
      return true;
    }

  if (map.cu_count != nr_cus)
    {
      warning (_("Section .debug_names has incorrect number of CUs in CU table,"
		 " ignoring .debug_names."));
      return false;
    }

  for (uint32_t i = 0; i < map.cu_count; ++i)
    {
      sect_offset sect_off
	= (sect_offset) (extract_unsigned_integer
			 (map.cu_table_reordered + i * map.offset_size,
			  map.offset_size,
			  map.dwarf5_byte_order));
      if (sect_off != per_bfd->get_cu (i)->sect_off)
	{
	  warning (_("Section .debug_names has incorrect entry in CU table,"
		     " ignoring .debug_names."));
	  return false;
	}
    }

  return true;
}

/* Read the CU list from the mapped index, and use it to create all
   the CU objects for this dwarf2_per_objfile.  */

static bool
check_cus_from_debug_names (dwarf2_per_bfd *per_bfd,
			     const mapped_debug_names_reader &map,
			     const mapped_debug_names_reader &dwz_map)
{
  if (!check_cus_from_debug_names_list (per_bfd, map, per_bfd->infos[0],
					false /* is_dwz */))
    return false;

  if (dwz_map.cu_count == 0)
    return true;

  dwz_file *dwz = per_bfd->get_dwz_file ();
  return check_cus_from_debug_names_list (per_bfd, dwz_map, dwz->info,
					  true /* is_dwz */);
}

/* This does all the work for dwarf2_read_debug_names, but putting it
   into a separate function makes some cleanup a bit simpler.  */

static bool
do_dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)
{
  mapped_debug_names_reader map;
  mapped_debug_names_reader dwz_map;
  struct objfile *objfile = per_objfile->objfile;
  dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;

  if (!read_debug_names_from_section (per_objfile, objfile_name (objfile),
				      &per_bfd->debug_names, map))
    return false;

  /* Don't use the index if it's empty.  */
  if (map.name_count == 0)
    return false;

  /* If there is a .dwz file, read it so we can get its CU list as
     well.  */
  dwz_file *dwz = per_bfd->get_dwz_file ();
  if (dwz != NULL)
    {
      if (!read_debug_names_from_section (per_objfile,
					  bfd_get_filename (dwz->dwz_bfd.get ()),
					  &dwz->debug_names, dwz_map))
	{
	  warning (_("could not read '.debug_names' section from %s; skipping"),
		   bfd_get_filename (dwz->dwz_bfd.get ()));
	  return false;
	}
    }

  create_all_units (per_objfile);
  if (!check_cus_from_debug_names (per_bfd, map, dwz_map))
    return false;

  if (map.tu_count != 0)
    {
      /* We can only handle a single .debug_info and .debug_types when we have
	 an index.  */
      if (per_bfd->infos.size () > 1
	  || per_bfd->types.size () > 1)
	return false;

      dwarf2_section_info *section
	= (per_bfd->types.size () == 1
	   ? &per_bfd->types[0]
	   : &per_bfd->infos[0]);

      if (!check_signatured_type_table_from_debug_names (per_objfile,
							 map, section))
	return false;
    }

  per_bfd->debug_aranges.read (per_objfile->objfile);
  addrmap_mutable addrmap;
  deferred_warnings warnings;
  read_addrmap_from_aranges (per_objfile, &per_bfd->debug_aranges,
			     &addrmap, &warnings);
  warnings.emit ();

  const auto n_workers
    = std::max<std::size_t> (gdb::thread_pool::g_thread_pool->thread_count (),
			     1);

  /* Create as many index shard as there are worker threads.  */
  for (int i = 0; i < n_workers; ++i)
    map.shards.emplace_back (std::make_unique<cooked_index_shard> ());

  /* There is a single address map for the whole index (coming from
     .debug_aranges).  We only need to install it into a single shard for it to
     get searched by cooked_index.  */
  map.shards[0]->install_addrmap (&addrmap);

  auto cidn = (std::make_unique<cooked_index_worker_debug_names>
	       (per_objfile, std::move (map)));
  auto idx = std::make_unique<debug_names_index> (std::move (cidn));
  per_bfd->start_reading (std::move (idx));

  return true;
}

/* See read-debug-names.h.  */

bool
dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile)
{
  bool result = do_dwarf2_read_debug_names (per_objfile);
  if (!result)
    per_objfile->per_bfd->all_units.clear ();
  return result;
}
