// dwp.cc -- DWARF packaging utility

// Copyright (C) 2012-2021 Free Software Foundation, Inc.
// Written by Cary Coutant <ccoutant@google.com>.

// This file is part of dwp, the DWARF packaging utility.

// 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, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.

#include "dwp.h"

#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cerrno>

#include <vector>
#include <algorithm>

#include "getopt.h"
#include "libiberty.h"
#include "../bfd/bfdver.h"

#include "elfcpp.h"
#include "elfcpp_file.h"
#include "dwarf.h"
#include "dirsearch.h"
#include "fileread.h"
#include "object.h"
#include "compressed_output.h"
#include "stringpool.h"
#include "dwarf_reader.h"

static void
usage(FILE* fd, int) ATTRIBUTE_NORETURN;

static void
print_version() ATTRIBUTE_NORETURN;

namespace gold {

class Dwp_output_file;

template <int size, bool big_endian>
class Sized_relobj_dwo;

// List of .dwo files to process.
struct Dwo_file_entry
{
  Dwo_file_entry(uint64_t id, std::string name)
    : dwo_id(id), dwo_name(name)
  { }
  uint64_t dwo_id;
  std::string dwo_name;
};
typedef std::vector<Dwo_file_entry> File_list;

// Type to hold the offset and length of an input section
// within an output section.

struct Section_bounds
{
  section_offset_type offset;
  section_size_type size;

  Section_bounds()
    : offset(0), size(0)
  { }

  Section_bounds(section_offset_type o, section_size_type s)
    : offset(o), size(s)
  { }
};

// A set of sections for a compilation unit or type unit.

struct Unit_set
{
  uint64_t signature;
  Section_bounds sections[elfcpp::DW_SECT_MAX + 1];

  Unit_set()
    : signature(0), sections()
  { }
};

// An input file.
// This class may represent a .dwo file, a .dwp file
// produced by an earlier run, or an executable file whose
// debug section identifies a set of .dwo files to read.

class Dwo_file
{
 public:
  Dwo_file(const char* name)
    : name_(name), obj_(NULL), input_file_(NULL), is_compressed_(),
      sect_offsets_(), str_offset_map_()
  { }

  ~Dwo_file();

  // Read the input executable file and extract the list of .dwo files
  // that it references.
  void
  read_executable(File_list* files);

  // Read the input file and send its contents to OUTPUT_FILE.
  void
  read(Dwp_output_file* output_file);

  // Verify a .dwp file given a list of .dwo files referenced by the
  // corresponding executable file.  Returns true if no problems
  // were found.
  bool
  verify(const File_list& files);

 private:
  // Types for mapping input string offsets to output string offsets.
  typedef std::pair<section_offset_type, section_offset_type>
      Str_offset_map_entry;
  typedef std::vector<Str_offset_map_entry> Str_offset_map;

  // A less-than comparison routine for Str_offset_map.
  struct Offset_compare
  {
    bool
    operator()(const Str_offset_map_entry& i1,
	       const Str_offset_map_entry& i2) const
    { return i1.first < i2.first; }
  };

  // Create a Sized_relobj_dwo of the given size and endianness,
  // and record the target info.  P is a pointer to the ELF header
  // in memory.
  Relobj*
  make_object(Dwp_output_file* output_file);

  template <int size, bool big_endian>
  Relobj*
  sized_make_object(const unsigned char* p, Input_file* input_file,
		    Dwp_output_file* output_file);

  // Return the number of sections in the input object file.
  unsigned int
  shnum() const
  { return this->obj_->shnum(); }

  // Return section type.
  unsigned int
  section_type(unsigned int shndx)
  { return this->obj_->section_type(shndx); }

  // Get the name of a section.
  std::string
  section_name(unsigned int shndx)
  { return this->obj_->section_name(shndx); }

  // Return a view of the contents of a section, decompressed if necessary.
  // Set *PLEN to the size.  Set *IS_NEW to true if the contents need to be
  // deleted by the caller.
  const unsigned char*
  section_contents(unsigned int shndx, section_size_type* plen, bool* is_new)
  { return this->obj_->decompressed_section_contents(shndx, plen, is_new); }

  // Read the .debug_cu_index or .debug_tu_index section of a .dwp file,
  // and process the CU or TU sets.
  void
  read_unit_index(unsigned int, unsigned int *, Dwp_output_file*,
		  bool is_tu_index);

  template <bool big_endian>
  void
  sized_read_unit_index(unsigned int, unsigned int *, Dwp_output_file*,
			bool is_tu_index);

  // Verify the .debug_cu_index section of a .dwp file, comparing it
  // against the list of .dwo files referenced by the corresponding
  // executable file.
  bool
  verify_dwo_list(unsigned int, const File_list& files);

  template <bool big_endian>
  bool
  sized_verify_dwo_list(unsigned int, const File_list& files);

  // Merge the input string table section into the output file.
  void
  add_strings(Dwp_output_file*, unsigned int);

  // Copy a section from the input file to the output file.
  Section_bounds
  copy_section(Dwp_output_file* output_file, unsigned int shndx,
	       elfcpp::DW_SECT section_id);

  // Remap the string offsets in the .debug_str_offsets.dwo section.
  const unsigned char*
  remap_str_offsets(const unsigned char* contents, section_size_type len);

  template <bool big_endian>
  const unsigned char*
  sized_remap_str_offsets(const unsigned char* contents, section_size_type len);

  // Remap a single string offsets from an offset in the input string table
  // to an offset in the output string table.
  unsigned int
  remap_str_offset(section_offset_type val);

  // Add a set of .debug_info.dwo or .debug_types.dwo and related sections
  // to OUTPUT_FILE.
  void
  add_unit_set(Dwp_output_file* output_file, unsigned int *debug_shndx,
	       bool is_debug_types);

  // The filename.
  const char* name_;
  // The ELF file, represented as a gold Relobj instance.
  Relobj* obj_;
  // The Input_file object.
  Input_file* input_file_;
  // Flags indicating which sections are compressed.
  std::vector<bool> is_compressed_;
  // Map input section index onto output section offset and size.
  std::vector<Section_bounds> sect_offsets_;
  // Map input string offsets to output string offsets.
  Str_offset_map str_offset_map_;
};

// An ELF input file.
// We derive from Sized_relobj so that we can use interfaces
// in libgold to access the file.

template <int size, bool big_endian>
class Sized_relobj_dwo : public Sized_relobj<size, big_endian>
{
 public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef typename Sized_relobj<size, big_endian>::Symbols Symbols;

  Sized_relobj_dwo(const char* name, Input_file* input_file,
		   const elfcpp::Ehdr<size, big_endian>& ehdr)
    : Sized_relobj<size, big_endian>(name, input_file),
      elf_file_(this, ehdr)
  { }

  ~Sized_relobj_dwo()
  { }

  // Setup the section information.
  void
  setup();

 protected:
  // Return section type.
  unsigned int
  do_section_type(unsigned int shndx)
  { return this->elf_file_.section_type(shndx); }

  // Get the name of a section.
  std::string
  do_section_name(unsigned int shndx) const
  { return this->elf_file_.section_name(shndx); }

  // Get the size of a section.
  uint64_t
  do_section_size(unsigned int shndx)
  { return this->elf_file_.section_size(shndx); }

  // Return a view of the contents of a section.
  const unsigned char*
  do_section_contents(unsigned int, section_size_type*, bool);

  // The following virtual functions are abstract in the base classes,
  // but are not used here.

  // Read the symbols.
  void
  do_read_symbols(Read_symbols_data*)
  { gold_unreachable(); }

  // Lay out the input sections.
  void
  do_layout(Symbol_table*, Layout*, Read_symbols_data*)
  { gold_unreachable(); }

  // Layout sections whose layout was deferred while waiting for
  // input files from a plugin.
  void
  do_layout_deferred_sections(Layout*)
  { gold_unreachable(); }

  // Add the symbols to the symbol table.
  void
  do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*)
  { gold_unreachable(); }

  Archive::Should_include
  do_should_include_member(Symbol_table*, Layout*, Read_symbols_data*,
                           std::string*)
  { gold_unreachable(); }

  // Iterate over global symbols, calling a visitor class V for each.
  void
  do_for_all_global_symbols(Read_symbols_data*,
			    Library_base::Symbol_visitor_base*)
  { gold_unreachable(); }

  // Return section flags.
  uint64_t
  do_section_flags(unsigned int)
  { gold_unreachable(); }

  // Return section entsize.
  uint64_t
  do_section_entsize(unsigned int)
  { gold_unreachable(); }

  // Return section address.
  uint64_t
  do_section_address(unsigned int)
  { gold_unreachable(); }

  // Return the section link field.
  unsigned int
  do_section_link(unsigned int)
  { gold_unreachable(); }

  // Return the section link field.
  unsigned int
  do_section_info(unsigned int)
  { gold_unreachable(); }

  // Return the section alignment.
  uint64_t
  do_section_addralign(unsigned int)
  { gold_unreachable(); }

  // Return the Xindex structure to use.
  Xindex*
  do_initialize_xindex()
  { gold_unreachable(); }

  // Get symbol counts.
  void
  do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const
  { gold_unreachable(); }

  // Get global symbols.
  const Symbols*
  do_get_global_symbols() const
  { return NULL; }

  // Return the value of a local symbol.
  uint64_t
  do_local_symbol_value(unsigned int, uint64_t) const
  { gold_unreachable(); }

  unsigned int
  do_local_plt_offset(unsigned int) const
  { gold_unreachable(); }

  // Return whether local symbol SYMNDX is a TLS symbol.
  bool
  do_local_is_tls(unsigned int) const
  { gold_unreachable(); }

  // Return the number of local symbols.
  unsigned int
  do_local_symbol_count() const
  { gold_unreachable(); }

  // Return the number of local symbols in the output symbol table.
  unsigned int
  do_output_local_symbol_count() const
  { gold_unreachable(); }

  // Return the file offset for local symbols in the output symbol table.
  off_t
  do_local_symbol_offset() const
  { gold_unreachable(); }

  // Read the relocs.
  void
  do_read_relocs(Read_relocs_data*)
  { gold_unreachable(); }

  // Process the relocs to find list of referenced sections. Used only
  // during garbage collection.
  void
  do_gc_process_relocs(Symbol_table*, Layout*, Read_relocs_data*)
  { gold_unreachable(); }

  // Scan the relocs and adjust the symbol table.
  void
  do_scan_relocs(Symbol_table*, Layout*, Read_relocs_data*)
  { gold_unreachable(); }

  // Count the local symbols.
  void
  do_count_local_symbols(Stringpool_template<char>*,
			 Stringpool_template<char>*)
  { gold_unreachable(); }

  // Finalize the local symbols.
  unsigned int
  do_finalize_local_symbols(unsigned int, off_t, Symbol_table*)
  { gold_unreachable(); }

  // Set the offset where local dynamic symbol information will be stored.
  unsigned int
  do_set_local_dynsym_indexes(unsigned int)
  { gold_unreachable(); }

  // Set the offset where local dynamic symbol information will be stored.
  unsigned int
  do_set_local_dynsym_offset(off_t)
  { gold_unreachable(); }

  // Relocate the input sections and write out the local symbols.
  void
  do_relocate(const Symbol_table*, const Layout*, Output_file*)
  { gold_unreachable(); }

 private:
  // General access to the ELF file.
  elfcpp::Elf_file<size, big_endian, Object> elf_file_;
};

// The output file.
// This class is responsible for collecting the debug index information
// and writing the .dwp file in ELF format.

class Dwp_output_file
{
 public:
  Dwp_output_file(const char* name)
    : name_(name), machine_(0), size_(0), big_endian_(false), osabi_(0),
      abiversion_(0), fd_(NULL), next_file_offset_(0), shnum_(1), sections_(),
      section_id_map_(), shoff_(0), shstrndx_(0), have_strings_(false),
      stringpool_(), shstrtab_(), cu_index_(), tu_index_(), last_type_sig_(0),
      last_tu_slot_(0)
  {
    this->section_id_map_.resize(elfcpp::DW_SECT_MAX + 1);
    this->stringpool_.set_no_zero_null();
  }

  // Record the target info from an input file.
  void
  record_target_info(const char* name, int machine, int size, bool big_endian,
		     int osabi, int abiversion);

  // Add a string to the debug strings section.
  section_offset_type
  add_string(const char* str, size_t len);

  // Add a section to the output file, and return the new section offset.
  section_offset_type
  add_contribution(elfcpp::DW_SECT section_id, const unsigned char* contents,
		   section_size_type len, int align);

  // Add a set of .debug_info and related sections to the output file.
  void
  add_cu_set(Unit_set* cu_set);

  // Lookup a type signature and return TRUE if we have already seen it.
  bool
  lookup_tu(uint64_t type_sig);

  // Add a set of .debug_types and related sections to the output file.
  void
  add_tu_set(Unit_set* tu_set);

  // Finalize the file, write the string tables and index sections,
  // and close the file.
  void
  finalize();

 private:
  // Contributions to output sections.
  struct Contribution
  {
    section_offset_type output_offset;
    section_size_type size;
    const unsigned char* contents;
  };

  // Sections in the output file.
  struct Section
  {
    const char* name;
    off_t offset;
    section_size_type size;
    int align;
    std::vector<Contribution> contributions;

    Section(const char* n, int a)
      : name(n), offset(0), size(0), align(a), contributions()
    { }
  };

  // The index sections defined by the DWARF Package File Format spec.
  class Dwp_index
  {
   public:
    // Vector for the section table.
    typedef std::vector<const Unit_set*> Section_table;

    Dwp_index()
      : capacity_(0), used_(0), hash_table_(NULL), section_table_(),
        section_mask_(0)
    { }

    ~Dwp_index()
    { }

    // Find a slot in the hash table for SIGNATURE.  Return TRUE
    // if the entry already exists.
    bool
    find_or_add(uint64_t signature, unsigned int* slotp);

    // Enter a CU or TU set at the given SLOT in the hash table.
    void
    enter_set(unsigned int slot, const Unit_set* set);

    // Return the contents of the given SLOT in the hash table of signatures.
    uint64_t
    hash_table(unsigned int slot) const
    { return this->hash_table_[slot]; }

    // Return the contents of the given SLOT in the parallel table of
    // shndx pool indexes.
    uint32_t
    index_table(unsigned int slot) const
    { return this->index_table_[slot]; }

    // Return the total number of slots in the hash table.
    unsigned int
    hash_table_total_slots() const
    { return this->capacity_; }

    // Return the number of used slots in the hash table.
    unsigned int
    hash_table_used_slots() const
    { return this->used_; }

    // Return an iterator into the shndx pool.
    Section_table::const_iterator
    section_table() const
    { return this->section_table_.begin(); }

    Section_table::const_iterator
    section_table_end() const
    { return this->section_table_.end(); }

    // Return the number of rows in the section table.
    unsigned int
    section_table_rows() const
    { return this->section_table_.size(); }

    // Return the mask indicating which columns will be used
    // in the section table.
    int
    section_table_cols() const
    { return this->section_mask_; }

   private:
    // Initialize the hash table.
    void
    initialize();

    // Grow the hash table when we reach 2/3 capacity.
    void
    grow();

    // The number of slots in the table, a power of 2 such that
    // capacity > 3 * size / 2.
    unsigned int capacity_;
    // The current number of used slots in the hash table.
    unsigned int used_;
    // The storage for the hash table of signatures.
    uint64_t* hash_table_;
    // The storage for the parallel table of shndx pool indexes.
    uint32_t* index_table_;
    // The table of section offsets and sizes.
    Section_table section_table_;
    // Bit mask to indicate which debug sections are present in the file.
    int section_mask_;
  };  // End class Dwp_output_file::Dwp_index.

  // Add a new output section and return the section index.
  unsigned int
  add_output_section(const char* section_name, int align);

  // Write a new section to the output file.
  void
  write_new_section(const char* section_name, const unsigned char* contents,
		    section_size_type len, int align);

  // Write the ELF header.
  void
  write_ehdr();

  template<unsigned int size, bool big_endian>
  void
  sized_write_ehdr();

  // Write a section header.
  void
  write_shdr(const char* name, unsigned int type, unsigned int flags,
	     uint64_t addr, off_t offset, section_size_type sect_size,
	     unsigned int link, unsigned int info,
	     unsigned int align, unsigned int ent_size);

  template<unsigned int size, bool big_endian>
  void
  sized_write_shdr(const char* name, unsigned int type, unsigned int flags,
		   uint64_t addr, off_t offset, section_size_type sect_size,
		   unsigned int link, unsigned int info,
		   unsigned int align, unsigned int ent_size);

  // Write the contributions to an output section.
  void
  write_contributions(const Section& sect);

  // Write a CU or TU index section.
  template<bool big_endian>
  void
  write_index(const char* sect_name, const Dwp_index& index);

  // The output filename.
  const char* name_;
  // ELF header parameters.
  int machine_;
  int size_;
  int big_endian_;
  int osabi_;
  int abiversion_;
  // The output file descriptor.
  FILE* fd_;
  // Next available file offset.
  off_t next_file_offset_;
  // The number of sections.
  unsigned int shnum_;
  // Section table. The first entry is shndx 1.
  std::vector<Section> sections_;
  // Section id map. This maps a DW_SECT enum to an shndx.
  std::vector<unsigned int> section_id_map_;
  // File offset of the section header table.
  off_t shoff_;
  // Section index of the section string table.
  unsigned int shstrndx_;
  // TRUE if we have added any strings to the string pool.
  bool have_strings_;
  // String pool for the output .debug_str.dwo section.
  Stringpool stringpool_;
  // String pool for the .shstrtab section.
  Stringpool shstrtab_;
  // The compilation unit index.
  Dwp_index cu_index_;
  // The type unit index.
  Dwp_index tu_index_;
  // Cache of the last type signature looked up.
  uint64_t last_type_sig_;
  // Cache of the slot index for the last type signature.
  unsigned int last_tu_slot_;
};

// A specialization of Dwarf_info_reader, for reading dwo_names from
// DWARF CUs.

class Dwo_name_info_reader : public Dwarf_info_reader
{
 public:
  Dwo_name_info_reader(Relobj* object, unsigned int shndx)
    : Dwarf_info_reader(false, object, NULL, 0, shndx, 0, 0),
      files_(NULL)
  { }

  ~Dwo_name_info_reader()
  { }

  // Get the dwo_names from the DWARF compilation unit DIEs.
  void
  get_dwo_names(File_list* files)
  { 
    this->files_ = files;
    this->parse();
  }

 protected:
  // Visit a compilation unit.
  virtual void
  visit_compilation_unit(off_t cu_offset, off_t cu_length, Dwarf_die*);

 private:
  // The list of files to populate.
  File_list* files_;
};

// A specialization of Dwarf_info_reader, for reading DWARF CUs and TUs
// and adding them to the output file.

class Unit_reader : public Dwarf_info_reader
{
 public:
  Unit_reader(bool is_type_unit, Relobj* object, unsigned int shndx)
    : Dwarf_info_reader(is_type_unit, object, NULL, 0, shndx, 0, 0),
      output_file_(NULL), sections_(NULL)
  { }

  ~Unit_reader()
  { }

  // Read the CUs or TUs and add them to the output file.
  void
  add_units(Dwp_output_file*, unsigned int debug_abbrev, Section_bounds*);

 protected:
  // Visit a compilation unit.
  virtual void
  visit_compilation_unit(off_t cu_offset, off_t cu_length, Dwarf_die*);

  // Visit a type unit.
  virtual void
  visit_type_unit(off_t tu_offset, off_t tu_length, off_t type_offset,
		  uint64_t signature, Dwarf_die*);

 private:
  Dwp_output_file* output_file_;
  Section_bounds* sections_;
};

// Return the name of a DWARF .dwo section.

static const char*
get_dwarf_section_name(elfcpp::DW_SECT section_id)
{
  static const char* dwarf_section_names[] = {
    NULL, // unused
    ".debug_info.dwo",         // DW_SECT_INFO = 1
    ".debug_types.dwo",        // DW_SECT_TYPES = 2
    ".debug_abbrev.dwo",       // DW_SECT_ABBREV = 3
    ".debug_line.dwo",         // DW_SECT_LINE = 4
    ".debug_loc.dwo",          // DW_SECT_LOC = 5
    ".debug_str_offsets.dwo",  // DW_SECT_STR_OFFSETS = 6
    ".debug_macinfo.dwo",      // DW_SECT_MACINFO = 7
    ".debug_macro.dwo",        // DW_SECT_MACRO = 8
  };

  gold_assert(section_id > 0 && section_id <= elfcpp::DW_SECT_MAX);
  return dwarf_section_names[section_id];
}

// Class Sized_relobj_dwo.

// Setup the section information.

template <int size, bool big_endian>
void
Sized_relobj_dwo<size, big_endian>::setup()
{
  const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
  const off_t shoff = this->elf_file_.shoff();
  const unsigned int shnum = this->elf_file_.shnum();

  this->set_shnum(shnum);
  this->section_offsets().resize(shnum);

  // Read the section headers.
  const unsigned char* const pshdrs = this->get_view(shoff, shnum * shdr_size,
						     true, false);

  // Read the section names.
  const unsigned char* pshdrnames =
      pshdrs + this->elf_file_.shstrndx() * shdr_size;
  typename elfcpp::Shdr<size, big_endian> shdrnames(pshdrnames);
  if (shdrnames.get_sh_type() != elfcpp::SHT_STRTAB)
    this->error(_("section name section has wrong type: %u"),
		static_cast<unsigned int>(shdrnames.get_sh_type()));
  section_size_type section_names_size =
      convert_to_section_size_type(shdrnames.get_sh_size());
  const unsigned char* namesu = this->get_view(shdrnames.get_sh_offset(),
					       section_names_size, false,
					       false);
  const char* names = reinterpret_cast<const char*>(namesu);

  Compressed_section_map* compressed_sections =
      build_compressed_section_map<size, big_endian>(
	  pshdrs, this->shnum(), names, section_names_size, this, true);
  if (compressed_sections != NULL && !compressed_sections->empty())
    this->set_compressed_sections(compressed_sections);
}

// Return a view of the contents of a section.

template <int size, bool big_endian>
const unsigned char*
Sized_relobj_dwo<size, big_endian>::do_section_contents(
    unsigned int shndx,
    section_size_type* plen,
    bool cache)
{
  Object::Location loc(this->elf_file_.section_contents(shndx));
  *plen = convert_to_section_size_type(loc.data_size);
  if (*plen == 0)
    {
      static const unsigned char empty[1] = { '\0' };
      return empty;
    }
  return this->get_view(loc.file_offset, *plen, true, cache);
}

// Class Dwo_file.

Dwo_file::~Dwo_file()
{
  if (this->obj_ != NULL)
    delete this->obj_;
  if (this->input_file_ != NULL)
    delete this->input_file_;
}

// Read the input executable file and extract the list of .dwo files
// that it references.

void
Dwo_file::read_executable(File_list* files)
{
  this->obj_ = this->make_object(NULL);

  unsigned int shnum = this->shnum();
  this->is_compressed_.resize(shnum);
  this->sect_offsets_.resize(shnum);

  unsigned int debug_info = 0;
  unsigned int debug_abbrev = 0;

  // Scan the section table and collect the debug sections we need.
  // (Section index 0 is a dummy section; skip it.)
  for (unsigned int i = 1; i < shnum; i++)
    {
      if (this->section_type(i) != elfcpp::SHT_PROGBITS)
	continue;
      std::string sect_name = this->section_name(i);
      const char* suffix = sect_name.c_str();
      if (is_prefix_of(".debug_", suffix))
	suffix += 7;
      else if (is_prefix_of(".zdebug_", suffix))
	{
	  this->is_compressed_[i] = true;
	  suffix += 8;
	}
      else
	continue;
      if (strcmp(suffix, "info") == 0)
	debug_info = i;
      else if (strcmp(suffix, "abbrev") == 0)
	debug_abbrev = i;
    }

  if (debug_info > 0)
    {
      Dwo_name_info_reader dwarf_reader(this->obj_, debug_info);
      dwarf_reader.set_abbrev_shndx(debug_abbrev);
      dwarf_reader.get_dwo_names(files);
    }
}

// Read the input file and send its contents to OUTPUT_FILE.

void
Dwo_file::read(Dwp_output_file* output_file)
{
  this->obj_ = this->make_object(output_file);

  unsigned int shnum = this->shnum();
  this->is_compressed_.resize(shnum);
  this->sect_offsets_.resize(shnum);

  typedef std::vector<unsigned int> Types_list;
  Types_list debug_types;
  unsigned int debug_shndx[elfcpp::DW_SECT_MAX + 1];
  for (unsigned int i = 0; i <= elfcpp::DW_SECT_MAX; i++)
    debug_shndx[i] = 0;
  unsigned int debug_str = 0;
  unsigned int debug_cu_index = 0;
  unsigned int debug_tu_index = 0;

  // Scan the section table and collect debug sections.
  // (Section index 0 is a dummy section; skip it.)
  for (unsigned int i = 1; i < shnum; i++)
    {
      if (this->section_type(i) != elfcpp::SHT_PROGBITS)
	continue;
      std::string sect_name = this->section_name(i);
      const char* suffix = sect_name.c_str();
      if (is_prefix_of(".debug_", suffix))
	suffix += 7;
      else if (is_prefix_of(".zdebug_", suffix))
	{
	  this->is_compressed_[i] = true;
	  suffix += 8;
	}
      else
	continue;
      if (strcmp(suffix, "info.dwo") == 0)
	debug_shndx[elfcpp::DW_SECT_INFO] = i;
      else if (strcmp(suffix, "types.dwo") == 0)
	debug_types.push_back(i);
      else if (strcmp(suffix, "abbrev.dwo") == 0)
	debug_shndx[elfcpp::DW_SECT_ABBREV] = i;
      else if (strcmp(suffix, "line.dwo") == 0)
	debug_shndx[elfcpp::DW_SECT_LINE] = i;
      else if (strcmp(suffix, "loc.dwo") == 0)
	debug_shndx[elfcpp::DW_SECT_LOC] = i;
      else if (strcmp(suffix, "str.dwo") == 0)
	debug_str = i;
      else if (strcmp(suffix, "str_offsets.dwo") == 0)
	debug_shndx[elfcpp::DW_SECT_STR_OFFSETS] = i;
      else if (strcmp(suffix, "macinfo.dwo") == 0)
	debug_shndx[elfcpp::DW_SECT_MACINFO] = i;
      else if (strcmp(suffix, "macro.dwo") == 0)
	debug_shndx[elfcpp::DW_SECT_MACRO] = i;
      else if (strcmp(suffix, "cu_index") == 0)
	debug_cu_index = i;
      else if (strcmp(suffix, "tu_index") == 0)
	debug_tu_index = i;
    }

  // Merge the input string table into the output string table.
  this->add_strings(output_file, debug_str);

  // If we found any .dwp index sections, read those and add the section
  // sets to the output file.
  if (debug_cu_index > 0 || debug_tu_index > 0)
    {
      if (debug_cu_index > 0)
	this->read_unit_index(debug_cu_index, debug_shndx, output_file, false);
      if (debug_tu_index > 0)
        {
	  if (debug_types.size() > 1)
	    gold_fatal(_("%s: .dwp file must have no more than one "
			 ".debug_types.dwo section"), this->name_);
          if (debug_types.size() == 1)
            debug_shndx[elfcpp::DW_SECT_TYPES] = debug_types[0];
          else
            debug_shndx[elfcpp::DW_SECT_TYPES] = 0;
	  this->read_unit_index(debug_tu_index, debug_shndx, output_file, true);
	}
      return;
    }

  // If we found no index sections, this is a .dwo file.
  if (debug_shndx[elfcpp::DW_SECT_INFO] > 0)
    this->add_unit_set(output_file, debug_shndx, false);

  debug_shndx[elfcpp::DW_SECT_INFO] = 0;
  for (Types_list::const_iterator tp = debug_types.begin();
       tp != debug_types.end();
       ++tp)
    {
      debug_shndx[elfcpp::DW_SECT_TYPES] = *tp;
      this->add_unit_set(output_file, debug_shndx, true);
    }
}

// Verify a .dwp file given a list of .dwo files referenced by the
// corresponding executable file.  Returns true if no problems
// were found.

bool
Dwo_file::verify(const File_list& files)
{
  this->obj_ = this->make_object(NULL);

  unsigned int shnum = this->shnum();
  this->is_compressed_.resize(shnum);
  this->sect_offsets_.resize(shnum);

  unsigned int debug_cu_index = 0;

  // Scan the section table and collect debug sections.
  // (Section index 0 is a dummy section; skip it.)
  for (unsigned int i = 1; i < shnum; i++)
    {
      if (this->section_type(i) != elfcpp::SHT_PROGBITS)
	continue;
      std::string sect_name = this->section_name(i);
      const char* suffix = sect_name.c_str();
      if (is_prefix_of(".debug_", suffix))
	suffix += 7;
      else if (is_prefix_of(".zdebug_", suffix))
	{
	  this->is_compressed_[i] = true;
	  suffix += 8;
	}
      else
	continue;
      if (strcmp(suffix, "cu_index") == 0)
	debug_cu_index = i;
    }

  if (debug_cu_index == 0)
    gold_fatal(_("%s: no .debug_cu_index section found"), this->name_);

  return this->verify_dwo_list(debug_cu_index, files);
}

// Create a Sized_relobj_dwo of the given size and endianness,
// and record the target info.

Relobj*
Dwo_file::make_object(Dwp_output_file* output_file)
{
  // Open the input file.
  Input_file* input_file = new Input_file(this->name_);
  this->input_file_ = input_file;
  Dirsearch dirpath;
  int index;
  if (!input_file->open(dirpath, NULL, &index))
    gold_fatal(_("%s: can't open"), this->name_);
  
  // Check that it's an ELF file.
  off_t filesize = input_file->file().filesize();
  int hdrsize = elfcpp::Elf_recognizer::max_header_size;
  if (filesize < hdrsize)
    hdrsize = filesize;
  const unsigned char* elf_header =
      input_file->file().get_view(0, 0, hdrsize, true, false);
  if (!elfcpp::Elf_recognizer::is_elf_file(elf_header, hdrsize))
    gold_fatal(_("%s: not an ELF object file"), this->name_);
  
  // Get the size, endianness, machine, etc. info from the header,
  // make an appropriately-sized Relobj, and pass the target info
  // to the output object.
  int size;
  bool big_endian;
  std::string error;
  if (!elfcpp::Elf_recognizer::is_valid_header(elf_header, hdrsize, &size,
					       &big_endian, &error))
    gold_fatal(_("%s: %s"), this->name_, error.c_str());

  if (size == 32)
    {
      if (big_endian)
#ifdef HAVE_TARGET_32_BIG
	return this->sized_make_object<32, true>(elf_header, input_file,
						 output_file);
#else
	gold_unreachable();
#endif
      else
#ifdef HAVE_TARGET_32_LITTLE
	return this->sized_make_object<32, false>(elf_header, input_file,
						  output_file);
#else
	gold_unreachable();
#endif
    }
  else if (size == 64)
    {
      if (big_endian)
#ifdef HAVE_TARGET_64_BIG
	return this->sized_make_object<64, true>(elf_header, input_file,
						 output_file);
#else
	gold_unreachable();
#endif
      else
#ifdef HAVE_TARGET_64_LITTLE
	return this->sized_make_object<64, false>(elf_header, input_file,
						  output_file);
#else
	gold_unreachable();
#endif
    }
  else
    gold_unreachable();
}

// Function template to create a Sized_relobj_dwo and record the target info.
// P is a pointer to the ELF header in memory.

template <int size, bool big_endian>
Relobj*
Dwo_file::sized_make_object(const unsigned char* p, Input_file* input_file,
			    Dwp_output_file* output_file)
{
  elfcpp::Ehdr<size, big_endian> ehdr(p);
  Sized_relobj_dwo<size, big_endian>* obj =
      new Sized_relobj_dwo<size, big_endian>(this->name_, input_file, ehdr);
  obj->setup();
  if (output_file != NULL)
    output_file->record_target_info(
	this->name_, ehdr.get_e_machine(), size, big_endian,
	ehdr.get_ei_osabi(),
	ehdr.get_ei_abiversion());
  return obj;
}

// Read the .debug_cu_index or .debug_tu_index section of a .dwp file,
// and process the CU or TU sets.

void
Dwo_file::read_unit_index(unsigned int shndx, unsigned int *debug_shndx,
			  Dwp_output_file* output_file, bool is_tu_index)
{
  if (this->obj_->is_big_endian())
    this->sized_read_unit_index<true>(shndx, debug_shndx, output_file,
				      is_tu_index);
  else
    this->sized_read_unit_index<false>(shndx, debug_shndx, output_file,
				       is_tu_index);
}

template <bool big_endian>
void
Dwo_file::sized_read_unit_index(unsigned int shndx,
				unsigned int *debug_shndx,
				Dwp_output_file* output_file,
				bool is_tu_index)
{
  elfcpp::DW_SECT info_sect = (is_tu_index
			       ? elfcpp::DW_SECT_TYPES
			       : elfcpp::DW_SECT_INFO);
  unsigned int info_shndx = debug_shndx[info_sect];

  gold_assert(shndx > 0);

  section_size_type index_len;
  bool index_is_new;
  const unsigned char* contents =
      this->section_contents(shndx, &index_len, &index_is_new);

  unsigned int version =
      elfcpp::Swap_unaligned<32, big_endian>::readval(contents);

  // We don't support version 1 anymore because it was experimental
  // and because in normal use, dwp is not expected to read .dwp files
  // produced by an earlier version of the tool.
  if (version != 2)
    gold_fatal(_("%s: section %s has unsupported version number %d"),
	       this->name_, this->section_name(shndx).c_str(), version);

  unsigned int ncols =
      elfcpp::Swap_unaligned<32, big_endian>::readval(contents
						      + sizeof(uint32_t));
  unsigned int nused =
      elfcpp::Swap_unaligned<32, big_endian>::readval(contents
						      + 2 * sizeof(uint32_t));
  if (ncols == 0 || nused == 0)
    return;

  gold_assert(info_shndx > 0);

  unsigned int nslots =
      elfcpp::Swap_unaligned<32, big_endian>::readval(contents
						      + 3 * sizeof(uint32_t));

  const unsigned char* phash = contents + 4 * sizeof(uint32_t);
  const unsigned char* pindex = phash + nslots * sizeof(uint64_t);
  const unsigned char* pcolhdrs = pindex + nslots * sizeof(uint32_t);
  const unsigned char* poffsets = pcolhdrs + ncols * sizeof(uint32_t);
  const unsigned char* psizes = poffsets + nused * ncols * sizeof(uint32_t);
  const unsigned char* pend = psizes + nused * ncols * sizeof(uint32_t);

  if (pend > contents + index_len)
    gold_fatal(_("%s: section %s is corrupt"), this->name_,
	       this->section_name(shndx).c_str());

  // Copy the related sections and track the section offsets and sizes.
  Section_bounds sections[elfcpp::DW_SECT_MAX + 1];
  for (int i = elfcpp::DW_SECT_ABBREV; i <= elfcpp::DW_SECT_MAX; ++i)
    {
      if (debug_shndx[i] > 0)
	sections[i] = this->copy_section(output_file, debug_shndx[i],
					 static_cast<elfcpp::DW_SECT>(i));
    }

  // Get the contents of the .debug_info.dwo or .debug_types.dwo section.
  section_size_type info_len;
  bool info_is_new;
  const unsigned char* info_contents =
      this->section_contents(info_shndx, &info_len, &info_is_new);

  // Loop over the slots of the hash table.
  for (unsigned int i = 0; i < nslots; ++i)
    {
      uint64_t signature =
          elfcpp::Swap_unaligned<64, big_endian>::readval(phash);
      unsigned int index =
	  elfcpp::Swap_unaligned<32, big_endian>::readval(pindex);
      if (index != 0 && (!is_tu_index || !output_file->lookup_tu(signature)))
	{
	  Unit_set* unit_set = new Unit_set();
	  unit_set->signature = signature;
	  const unsigned char* pch = pcolhdrs;
	  const unsigned char* porow =
	      poffsets + (index - 1) * ncols * sizeof(uint32_t);
	  const unsigned char* psrow =
	      psizes + (index - 1) * ncols * sizeof(uint32_t);

	  // Adjust the offset of each contribution within the input section
	  // by the offset of the input section within the output section.
	  for (unsigned int j = 0; j <= ncols; j++)
	    {
	      unsigned int dw_sect =
		  elfcpp::Swap_unaligned<64, big_endian>::readval(pch);
	      unsigned int offset =
		  elfcpp::Swap_unaligned<64, big_endian>::readval(porow);
	      unsigned int size =
		  elfcpp::Swap_unaligned<64, big_endian>::readval(psrow);
	      unit_set->sections[dw_sect].offset = (sections[dw_sect].offset
						    + offset);
	      unit_set->sections[dw_sect].size = size;
	      pch += sizeof(uint32_t);
	      porow += sizeof(uint32_t);
	      psrow += sizeof(uint32_t);
	    }

	  const unsigned char* unit_start =
	      info_contents + unit_set->sections[info_sect].offset;
	  section_size_type unit_length = unit_set->sections[info_sect].size;

	  // Dwp_output_file::add_contribution writes the .debug_info.dwo
	  // section directly to the output file, so we only need to
	  // duplicate contributions for .debug_types.dwo section.
	  if (is_tu_index)
	    {
	      unsigned char *copy = new unsigned char[unit_length];
	      memcpy(copy, unit_start, unit_length);
	      unit_start = copy;
	    }
	  section_offset_type off =
	      output_file->add_contribution(info_sect, unit_start,
					    unit_length, 1);
	  unit_set->sections[info_sect].offset = off;
	  if (is_tu_index)
	    output_file->add_tu_set(unit_set);
	  else
	    output_file->add_cu_set(unit_set);
	}
      phash += sizeof(uint64_t);
      pindex += sizeof(uint32_t);
    }

  if (index_is_new)
    delete[] contents;
  if (info_is_new)
    delete[] info_contents;
}

// Verify the .debug_cu_index section of a .dwp file, comparing it
// against the list of .dwo files referenced by the corresponding
// executable file.

bool
Dwo_file::verify_dwo_list(unsigned int shndx, const File_list& files)
{
  if (this->obj_->is_big_endian())
    return this->sized_verify_dwo_list<true>(shndx, files);
  else
    return this->sized_verify_dwo_list<false>(shndx, files);
}

template <bool big_endian>
bool
Dwo_file::sized_verify_dwo_list(unsigned int shndx, const File_list& files)
{
  gold_assert(shndx > 0);

  section_size_type index_len;
  bool index_is_new;
  const unsigned char* contents =
      this->section_contents(shndx, &index_len, &index_is_new);

  unsigned int version =
      elfcpp::Swap_unaligned<32, big_endian>::readval(contents);

  // We don't support version 1 anymore because it was experimental
  // and because in normal use, dwp is not expected to read .dwp files
  // produced by an earlier version of the tool.
  if (version != 2)
    gold_fatal(_("%s: section %s has unsupported version number %d"),
	       this->name_, this->section_name(shndx).c_str(), version);

  unsigned int ncols =
      elfcpp::Swap_unaligned<32, big_endian>::readval(contents
						      + sizeof(uint32_t));
  unsigned int nused =
      elfcpp::Swap_unaligned<32, big_endian>::readval(contents
						      + 2 * sizeof(uint32_t));
  if (ncols == 0 || nused == 0)
    return true;

  unsigned int nslots =
      elfcpp::Swap_unaligned<32, big_endian>::readval(contents
						      + 3 * sizeof(uint32_t));

  const unsigned char* phash = contents + 4 * sizeof(uint32_t);
  const unsigned char* pindex = phash + nslots * sizeof(uint64_t);
  const unsigned char* pcolhdrs = pindex + nslots * sizeof(uint32_t);
  const unsigned char* poffsets = pcolhdrs + ncols * sizeof(uint32_t);
  const unsigned char* psizes = poffsets + nused * ncols * sizeof(uint32_t);
  const unsigned char* pend = psizes + nused * ncols * sizeof(uint32_t);

  if (pend > contents + index_len)
    gold_fatal(_("%s: section %s is corrupt"), this->name_,
	       this->section_name(shndx).c_str());

  int nmissing = 0;
  for (File_list::const_iterator f = files.begin(); f != files.end(); ++f)
    {
      uint64_t dwo_id = f->dwo_id;
      unsigned int slot = static_cast<unsigned int>(dwo_id) & (nslots - 1);
      const unsigned char* ph = phash + slot * sizeof(uint64_t);
      const unsigned char* pi = pindex + slot * sizeof(uint32_t);
      uint64_t probe = elfcpp::Swap_unaligned<64, big_endian>::readval(ph);
      uint32_t row_index = elfcpp::Swap_unaligned<32, big_endian>::readval(pi);
      if (row_index != 0 && probe != dwo_id)
	{
	  unsigned int h2 = ((static_cast<unsigned int>(dwo_id >> 32)
			      & (nslots - 1)) | 1);
	  do
	    {
	      slot = (slot + h2) & (nslots - 1);
	      ph = phash + slot * sizeof(uint64_t);
	      pi = pindex + slot * sizeof(uint32_t);
	      probe = elfcpp::Swap_unaligned<64, big_endian>::readval(ph);
	      row_index = elfcpp::Swap_unaligned<32, big_endian>::readval(pi);
	    } while (row_index != 0 && probe != dwo_id);
	}
      if (row_index == 0)
	{
	  printf(_("missing .dwo file: %016llx %s\n"),
		 static_cast<long long>(dwo_id), f->dwo_name.c_str());
	  ++nmissing;
	}
    }

  gold_info(_("Found %d missing .dwo files"), nmissing);

  if (index_is_new)
    delete[] contents;

  return nmissing == 0;
}

// Merge the input string table section into the output file.

void
Dwo_file::add_strings(Dwp_output_file* output_file, unsigned int debug_str)
{
  section_size_type len;
  bool is_new;
  const unsigned char* pdata = this->section_contents(debug_str, &len, &is_new);
  const char* p = reinterpret_cast<const char*>(pdata);
  const char* pend = p + len;

  // Check that the last string is null terminated.
  if (pend[-1] != '\0')
    gold_fatal(_("%s: last entry in string section '%s' "
		 "is not null terminated"),
	       this->name_,
	       this->section_name(debug_str).c_str());

  // Count the number of strings in the section, and size the map.
  size_t count = 0;
  for (const char* pt = p; pt < pend; pt += strlen(pt) + 1)
    ++count;
  this->str_offset_map_.reserve(count + 1);

  // Add the strings to the output string table, and record the new offsets
  // in the map.
  section_offset_type i = 0;
  section_offset_type new_offset;
  while (p < pend)
    {
      size_t len = strlen(p);
      new_offset = output_file->add_string(p, len);
      this->str_offset_map_.push_back(std::make_pair(i, new_offset));
      p += len + 1;
      i += len + 1;
    }
  new_offset = 0;
  this->str_offset_map_.push_back(std::make_pair(i, new_offset));
  if (is_new)
    delete[] pdata;
}

// Copy a section from the input file to the output file.
// Return the offset and length of this input section's contribution
// in the output section.  If copying .debug_str_offsets.dwo, remap
// the string offsets for the output string table.

Section_bounds
Dwo_file::copy_section(Dwp_output_file* output_file, unsigned int shndx,
		       elfcpp::DW_SECT section_id)
{
  // Some sections may be referenced from more than one set.
  // Don't copy a section more than once.
  if (this->sect_offsets_[shndx].size > 0)
    return this->sect_offsets_[shndx];

  // Get the section contents. Upon return, if IS_NEW is true, the memory
  // has been allocated via new; if false, the memory is part of the mapped
  // input file, and we will need to duplicate it so that it will persist
  // after we close the input file.
  section_size_type len;
  bool is_new;
  const unsigned char* contents = this->section_contents(shndx, &len, &is_new);

  if (section_id == elfcpp::DW_SECT_STR_OFFSETS)
    {
      const unsigned char* remapped = this->remap_str_offsets(contents, len);
      if (is_new)
	delete[] contents;
      contents = remapped;
    }
  else if (!is_new)
    {
      unsigned char* copy = new unsigned char[len];
      memcpy(copy, contents, len);
      contents = copy;
    }

  // Add the contents of the input section to the output section.
  // The output file takes ownership of the memory pointed to by CONTENTS.
  section_offset_type off = output_file->add_contribution(section_id, contents,
							  len, 1);

  // Store the output section bounds.
  Section_bounds bounds(off, len);
  this->sect_offsets_[shndx] = bounds;

  return bounds;
}

// Remap the 
const unsigned char*
Dwo_file::remap_str_offsets(const unsigned char* contents,
			    section_size_type len)
{
  if ((len & 3) != 0)
    gold_fatal(_("%s: .debug_str_offsets.dwo section size not a multiple of 4"),
	       this->name_);

  if (this->obj_->is_big_endian())
    return this->sized_remap_str_offsets<true>(contents, len);
  else
    return this->sized_remap_str_offsets<false>(contents, len);
}

template <bool big_endian>
const unsigned char*
Dwo_file::sized_remap_str_offsets(const unsigned char* contents,
				  section_size_type len)
{
  unsigned char* remapped = new unsigned char[len];
  const unsigned char* p = contents;
  unsigned char* q = remapped;
  while (len > 0)
    {
      unsigned int val = elfcpp::Swap_unaligned<32, big_endian>::readval(p);
      val = this->remap_str_offset(val);
      elfcpp::Swap_unaligned<32, big_endian>::writeval(q, val);
      len -= 4;
      p += 4;
      q += 4;
    }
  return remapped;
}

unsigned int
Dwo_file::remap_str_offset(section_offset_type val)
{
  Str_offset_map_entry entry;
  entry.first = val;

  Str_offset_map::const_iterator p =
      std::lower_bound(this->str_offset_map_.begin(),
		       this->str_offset_map_.end(),
		       entry, Offset_compare());

  if (p == this->str_offset_map_.end() || p->first > val)
    {
      if (p == this->str_offset_map_.begin())
	return 0;
      --p;
      gold_assert(p->first <= val);
    }

  return p->second + (val - p->first);
}

// Add a set of .debug_info.dwo or .debug_types.dwo and related sections
// to OUTPUT_FILE.

void
Dwo_file::add_unit_set(Dwp_output_file* output_file, unsigned int *debug_shndx,
		       bool is_debug_types)
{
  unsigned int shndx = (is_debug_types
			? debug_shndx[elfcpp::DW_SECT_TYPES]
			: debug_shndx[elfcpp::DW_SECT_INFO]);

  gold_assert(shndx != 0);

  if (debug_shndx[elfcpp::DW_SECT_ABBREV] == 0)
    gold_fatal(_("%s: no .debug_abbrev.dwo section found"), this->name_);

  // Copy the related sections and track the section offsets and sizes.
  Section_bounds sections[elfcpp::DW_SECT_MAX + 1];
  for (int i = elfcpp::DW_SECT_ABBREV; i <= elfcpp::DW_SECT_MAX; ++i)
    {
      if (debug_shndx[i] > 0)
	sections[i] = this->copy_section(output_file, debug_shndx[i],
					 static_cast<elfcpp::DW_SECT>(i));
    }

  // Parse the .debug_info or .debug_types section and add each compilation
  // or type unit to the output file, along with the contributions to the
  // related sections.
  Unit_reader reader(is_debug_types, this->obj_, shndx);
  reader.add_units(output_file, debug_shndx[elfcpp::DW_SECT_ABBREV], sections);
}

// Class Dwp_output_file.

// Record the target info from an input file.  On first call, we
// set the ELF header values for the output file.  On subsequent
// calls, we just verify that the values match.

void
Dwp_output_file::record_target_info(const char*, int machine,
				    int size, bool big_endian,
				    int osabi, int abiversion)
{
  // TODO: Check the values on subsequent calls.
  if (this->size_ > 0)
    return;

  this->machine_ = machine;
  this->size_ = size;
  this->big_endian_ = big_endian;
  this->osabi_ = osabi;
  this->abiversion_ = abiversion;

  if (size == 32)
    this->next_file_offset_ = elfcpp::Elf_sizes<32>::ehdr_size;
  else if (size == 64)
    this->next_file_offset_ = elfcpp::Elf_sizes<64>::ehdr_size;
  else
    gold_unreachable();

  this->fd_ = ::fopen(this->name_, "wb");
  if (this->fd_ == NULL)
    gold_fatal(_("%s: %s"), this->name_, strerror(errno));

  // Write zeroes for the ELF header initially.  We'll write
  // the actual header during finalize().
  static const char buf[elfcpp::Elf_sizes<64>::ehdr_size] = { 0 };
  if (::fwrite(buf, 1, this->next_file_offset_, this->fd_)
      < (size_t) this->next_file_offset_)
    gold_fatal(_("%s: %s"), this->name_, strerror(errno));
}

// Add a string to the debug strings section.

section_offset_type
Dwp_output_file::add_string(const char* str, size_t len)
{
  Stringpool::Key key;
  this->stringpool_.add_with_length(str, len, true, &key);
  this->have_strings_ = true;
  // We aren't supposed to call get_offset() until after
  // calling set_string_offsets(), but the offsets will
  // not change unless optimizing the string pool.
  return this->stringpool_.get_offset_from_key(key);
}

// Align the file offset to the given boundary.

static inline off_t
align_offset(off_t off, int align)
{
  return (off + align - 1) & ~(align - 1);
}

// Add a new output section and return the section index.

unsigned int
Dwp_output_file::add_output_section(const char* section_name, int align)
{
  Section sect(section_name, align);
  this->sections_.push_back(sect);
  return this->shnum_++;
}

// Add a contribution to a section in the output file, and return the offset
// of the contribution within the output section.  The .debug_info.dwo section
// is expected to be the largest one, so we will write the contents of this
// section directly to the output file as we receive contributions, allowing
// us to free that memory as soon as possible. We will save the remaining
// contributions until we finalize the layout of the output file.

section_offset_type
Dwp_output_file::add_contribution(elfcpp::DW_SECT section_id,
				  const unsigned char* contents,
				  section_size_type len,
				  int align)
{
  const char* section_name = get_dwarf_section_name(section_id);
  gold_assert(static_cast<size_t>(section_id) < this->section_id_map_.size());
  unsigned int shndx = this->section_id_map_[section_id];

  // Create the section if necessary.
  if (shndx == 0)
    {
      section_name = this->shstrtab_.add_with_length(section_name,
						     strlen(section_name),
						     false, NULL);
      shndx = this->add_output_section(section_name, align);
      this->section_id_map_[section_id] = shndx;
    }

  Section& section = this->sections_[shndx - 1];

  section_offset_type section_offset;

  if (section_id == elfcpp::DW_SECT_INFO)
    {
      // Write the .debug_info.dwo section directly.
      // We do not need to free the memory in this case.
      off_t file_offset = this->next_file_offset_;
      gold_assert(this->size_ > 0 && file_offset > 0);

      file_offset = align_offset(file_offset, align);
      if (section.offset == 0)
	section.offset = file_offset;

      if (align > section.align)
	{
	  // Since we've already committed to the layout for this
	  // section, an unexpected large alignment boundary may
	  // be impossible to honor.
	  if (align_offset(section.offset, align) != section.offset)
	    gold_fatal(_("%s: alignment (%d) for section '%s' "
			 "cannot be honored"),
		       this->name_, align, section_name);
	  section.align = align;
	}

      section_offset = file_offset - section.offset;
      section.size = file_offset + len - section.offset;

      ::fseek(this->fd_, file_offset, SEEK_SET);
      if (::fwrite(contents, 1, len, this->fd_) < len)
	gold_fatal(_("%s: error writing section '%s'"), this->name_,
		   section_name);
      this->next_file_offset_ = file_offset + len;
    }
  else
    {
      // Collect the contributions and keep track of the total size.
      if (align > section.align)
	section.align = align;
      section_offset = align_offset(section.size, align);
      section.size = section_offset + len;
      Contribution contrib = { section_offset, len, contents };
      section.contributions.push_back(contrib);
    }

  return section_offset;
}

// Add a set of .debug_info and related sections to the output file.

void
Dwp_output_file::add_cu_set(Unit_set* cu_set)
{
  uint64_t dwo_id = cu_set->signature;
  unsigned int slot;
  if (!this->cu_index_.find_or_add(dwo_id, &slot))
    this->cu_index_.enter_set(slot, cu_set);
  else
    gold_warning(_("%s: duplicate entry for CU (dwo_id 0x%llx)"),
		 this->name_, (unsigned long long)dwo_id);
}

// Lookup a type signature and return TRUE if we have already seen it.
bool
Dwp_output_file::lookup_tu(uint64_t type_sig)
{
  this->last_type_sig_ = type_sig;
  return this->tu_index_.find_or_add(type_sig, &this->last_tu_slot_);
}

// Add a set of .debug_types and related sections to the output file.

void
Dwp_output_file::add_tu_set(Unit_set* tu_set)
{
  uint64_t type_sig = tu_set->signature;
  unsigned int slot;
  if (type_sig == this->last_type_sig_)
    slot = this->last_tu_slot_;
  else
    this->tu_index_.find_or_add(type_sig, &slot);
  this->tu_index_.enter_set(slot, tu_set);
}

// Find a slot in the hash table for SIGNATURE.  Return TRUE
// if the entry already exists.

bool
Dwp_output_file::Dwp_index::find_or_add(uint64_t signature,
					unsigned int* slotp)
{
  if (this->capacity_ == 0)
    this->initialize();
  unsigned int slot =
      static_cast<unsigned int>(signature) & (this->capacity_ - 1);
  unsigned int secondary_hash;
  uint64_t probe = this->hash_table_[slot];
  uint32_t row_index = this->index_table_[slot];
  if (row_index != 0 && probe != signature)
    {
      secondary_hash = (static_cast<unsigned int>(signature >> 32)
			& (this->capacity_ - 1)) | 1;
      do
	{
	  slot = (slot + secondary_hash) & (this->capacity_ - 1);
	  probe = this->hash_table_[slot];
	  row_index = this->index_table_[slot];
	} while (row_index != 0 && probe != signature);
    }
  *slotp = slot;
  return (row_index != 0);
}

// Enter a CU or TU set at the given SLOT in the hash table.

void
Dwp_output_file::Dwp_index::enter_set(unsigned int slot,
				      const Unit_set* set)
{
  gold_assert(slot < this->capacity_);

  // Add a row to the offsets and sizes tables.
  this->section_table_.push_back(set);
  uint32_t row_index = this->section_table_rows();

  // Mark the sections used in this set.
  for (unsigned int i = 1; i <= elfcpp::DW_SECT_MAX; i++)
    if (set->sections[i].size > 0)
      this->section_mask_ |= 1 << i;

  // Enter the signature and pool index into the hash table.
  gold_assert(this->hash_table_[slot] == 0);
  this->hash_table_[slot] = set->signature;
  this->index_table_[slot] = row_index;
  ++this->used_;

  // Grow the hash table when we exceed 2/3 capacity.
  if (this->used_ * 3 > this->capacity_ * 2)
    this->grow();
}

// Initialize the hash table.

void
Dwp_output_file::Dwp_index::initialize()
{
  this->capacity_ = 16;
  this->hash_table_ = new uint64_t[this->capacity_];
  memset(this->hash_table_, 0, this->capacity_ * sizeof(uint64_t));
  this->index_table_ = new uint32_t[this->capacity_];
  memset(this->index_table_, 0, this->capacity_ * sizeof(uint32_t));
}

// Grow the hash table when we reach 2/3 capacity.

void
Dwp_output_file::Dwp_index::grow()
{
  unsigned int old_capacity = this->capacity_;
  uint64_t* old_hash_table = this->hash_table_;
  uint32_t* old_index_table = this->index_table_;
  unsigned int old_used = this->used_;

  this->capacity_ = old_capacity * 2;
  this->hash_table_ = new uint64_t[this->capacity_];
  memset(this->hash_table_, 0, this->capacity_ * sizeof(uint64_t));
  this->index_table_ = new uint32_t[this->capacity_];
  memset(this->index_table_, 0, this->capacity_ * sizeof(uint32_t));
  this->used_ = 0;

  for (unsigned int i = 0; i < old_capacity; ++i)
    {
      uint64_t signature = old_hash_table[i];
      uint32_t row_index = old_index_table[i];
      if (row_index != 0)
        {
	  unsigned int slot;
	  bool found = this->find_or_add(signature, &slot);
	  gold_assert(!found);
	  this->hash_table_[slot] = signature;
	  this->index_table_[slot] = row_index;
	  ++this->used_;
        }
    }
  gold_assert(this->used_ == old_used);

  delete[] old_hash_table;
  delete[] old_index_table;
}

// Finalize the file, write the string tables and index sections,
// and close the file.

void
Dwp_output_file::finalize()
{
  unsigned char* buf;

  // Write the accumulated output sections.
  for (unsigned int i = 0; i < this->sections_.size(); i++)
    {
      Section& sect = this->sections_[i];
      // If the offset has already been assigned, the section has been written.
      if (sect.offset > 0 || sect.size == 0)
	continue;
      off_t file_offset = this->next_file_offset_;
      file_offset = align_offset(file_offset, sect.align);
      sect.offset = file_offset;
      this->write_contributions(sect);
      this->next_file_offset_ = file_offset + sect.size;
    }

  // Write the debug string table.
  if (this->have_strings_)
    {
      this->stringpool_.set_string_offsets();
      section_size_type len = this->stringpool_.get_strtab_size();
      buf = new unsigned char[len];
      this->stringpool_.write_to_buffer(buf, len);
      this->write_new_section(".debug_str.dwo", buf, len, 1);
      delete[] buf;
    }

  // Write the CU and TU indexes.
  if (this->big_endian_)
    {
      this->write_index<true>(".debug_cu_index", this->cu_index_);
      this->write_index<true>(".debug_tu_index", this->tu_index_);
    }
  else
    {
      this->write_index<false>(".debug_cu_index", this->cu_index_);
      this->write_index<false>(".debug_tu_index", this->tu_index_);
    }

  off_t file_offset = this->next_file_offset_;

  // Write the section string table.
  this->shstrndx_ = this->shnum_++;
  const char* shstrtab_name =
      this->shstrtab_.add_with_length(".shstrtab", sizeof(".shstrtab") - 1,
				      false, NULL);
  this->shstrtab_.set_string_offsets();
  section_size_type shstrtab_len = this->shstrtab_.get_strtab_size();
  buf = new unsigned char[shstrtab_len];
  this->shstrtab_.write_to_buffer(buf, shstrtab_len);
  off_t shstrtab_off = file_offset;
  ::fseek(this->fd_, file_offset, 0);
  if (::fwrite(buf, 1, shstrtab_len, this->fd_) < shstrtab_len)
    gold_fatal(_("%s: error writing section '.shstrtab'"), this->name_);
  delete[] buf;
  file_offset += shstrtab_len;

  // Write the section header table.  The first entry is a NULL entry.
  // This is followed by the debug sections, and finally we write the
  // .shstrtab section header.
  file_offset = align_offset(file_offset, this->size_ == 32 ? 4 : 8);
  this->shoff_ = file_offset;
  ::fseek(this->fd_, file_offset, 0);
  section_size_type sh0_size = 0;
  unsigned int sh0_link = 0;
  if (this->shnum_ >= elfcpp::SHN_LORESERVE)
    sh0_size = this->shnum_;
  if (this->shstrndx_ >= elfcpp::SHN_LORESERVE)
    sh0_link = this->shstrndx_;
  this->write_shdr(NULL, 0, 0, 0, 0, sh0_size, sh0_link, 0, 0, 0);
  for (unsigned int i = 0; i < this->sections_.size(); ++i)
    {
      Section& sect = this->sections_[i];
      this->write_shdr(sect.name, elfcpp::SHT_PROGBITS, 0, 0, sect.offset,
		       sect.size, 0, 0, sect.align, 0);
    }
  this->write_shdr(shstrtab_name, elfcpp::SHT_STRTAB, 0, 0,
		   shstrtab_off, shstrtab_len, 0, 0, 1, 0);

  // Write the ELF header.
  this->write_ehdr();

  // Close the file.
  if (this->fd_ != NULL)
    {
      if (::fclose(this->fd_) != 0)
	gold_fatal(_("%s: %s"), this->name_, strerror(errno));
    }
  this->fd_ = NULL;
}

// Write the contributions to an output section.

void
Dwp_output_file::write_contributions(const Section& sect)
{
  for (unsigned int i = 0; i < sect.contributions.size(); ++i)
    {
      const Contribution& c = sect.contributions[i];
      ::fseek(this->fd_, sect.offset + c.output_offset, SEEK_SET);
      if (::fwrite(c.contents, 1, c.size, this->fd_) < c.size)
	gold_fatal(_("%s: error writing section '%s'"), this->name_, sect.name);
      delete[] c.contents;
    }
}

// Write a new section to the output file.

void
Dwp_output_file::write_new_section(const char* section_name,
				   const unsigned char* contents,
				   section_size_type len, int align)
{
  section_name = this->shstrtab_.add_with_length(section_name,
						 strlen(section_name),
						 false, NULL);
  unsigned int shndx = this->add_output_section(section_name, align);
  Section& section = this->sections_[shndx - 1];
  off_t file_offset = this->next_file_offset_;
  file_offset = align_offset(file_offset, align);
  section.offset = file_offset;
  section.size = len;
  ::fseek(this->fd_, file_offset, SEEK_SET);
  if (::fwrite(contents, 1, len, this->fd_) < len)
    gold_fatal(_("%s: error writing section '%s'"), this->name_, section_name);
  this->next_file_offset_ = file_offset + len;
}

// Write a CU or TU index section.

template<bool big_endian>
void
Dwp_output_file::write_index(const char* sect_name, const Dwp_index& index)
{
  const unsigned int nslots = index.hash_table_total_slots();
  const unsigned int nused = index.hash_table_used_slots();
  const unsigned int nrows = index.section_table_rows();

  int column_mask = index.section_table_cols();
  unsigned int ncols = 0;
  for (unsigned int c = 1; c <= elfcpp::DW_SECT_MAX; ++c)
    if (column_mask & (1 << c))
      ncols++;
  const unsigned int ntable = (nrows * 2 + 1) * ncols;

  const section_size_type index_size = (4 * sizeof(uint32_t)
					+ nslots * sizeof(uint64_t)
					+ nslots * sizeof(uint32_t)
					+ ntable * sizeof(uint32_t));

  // Allocate a buffer for the section contents.
  unsigned char* buf = new unsigned char[index_size];
  unsigned char* p = buf;

  // Write the section header: version number, padding,
  // number of used slots and total number of slots.
  elfcpp::Swap_unaligned<32, big_endian>::writeval(p, 2);
  p += sizeof(uint32_t);
  elfcpp::Swap_unaligned<32, big_endian>::writeval(p, ncols);
  p += sizeof(uint32_t);
  elfcpp::Swap_unaligned<32, big_endian>::writeval(p, nused);
  p += sizeof(uint32_t);
  elfcpp::Swap_unaligned<32, big_endian>::writeval(p, nslots);
  p += sizeof(uint32_t);

  // Write the hash table.
  for (unsigned int i = 0; i < nslots; ++i)
    {
      elfcpp::Swap_unaligned<64, big_endian>::writeval(p, index.hash_table(i));
      p += sizeof(uint64_t);
    }

  // Write the parallel index table.
  for (unsigned int i = 0; i < nslots; ++i)
    {
      elfcpp::Swap_unaligned<32, big_endian>::writeval(p, index.index_table(i));
      p += sizeof(uint32_t);
    }

  // Write the first row of the table of section offsets.
  for (unsigned int c = 1; c <= elfcpp::DW_SECT_MAX; ++c)
    {
      if (column_mask & (1 << c))
	{
	  elfcpp::Swap_unaligned<32, big_endian>::writeval(p, c);
	  p += sizeof(uint32_t);
	}
    }

  // Write the table of section offsets.
  Dwp_index::Section_table::const_iterator tbl = index.section_table();
  for (unsigned int r = 0; r < nrows; ++r)
    {
      gold_assert(tbl != index.section_table_end());
      const Section_bounds* sects = (*tbl)->sections;
      for (unsigned int c = 1; c <= elfcpp::DW_SECT_MAX; ++c)
	{
	  if (column_mask & (1 << c))
	    {
	      section_offset_type offset = sects[c].offset;
	      elfcpp::Swap_unaligned<32, big_endian>::writeval(p, offset);
	      p += sizeof(uint32_t);
	    }
	  else
	    gold_assert(sects[c].size == 0);
	}
      ++tbl;
    }

  // Write the table of section sizes.
  tbl = index.section_table();
  for (unsigned int r = 0; r < nrows; ++r)
    {
      gold_assert(tbl != index.section_table_end());
      const Section_bounds* sects = (*tbl)->sections;
      for (unsigned int c = 1; c <= elfcpp::DW_SECT_MAX; ++c)
	{
	  if (column_mask & (1 << c))
	    {
	      section_size_type size = sects[c].size;
	      elfcpp::Swap_unaligned<32, big_endian>::writeval(p, size);
	      p += sizeof(uint32_t);
	    }
	  else
	    gold_assert(sects[c].size == 0);
	}
      ++tbl;
    }

  gold_assert(p == buf + index_size);

  this->write_new_section(sect_name, buf, index_size, sizeof(uint64_t));

  delete[] buf;
}

// Write the ELF header.

void
Dwp_output_file::write_ehdr()
{
  if (this->size_ == 32)
    {
      if (this->big_endian_)
	return this->sized_write_ehdr<32, true>();
      else
	return this->sized_write_ehdr<32, false>();
    }
  else if (this->size_ == 64)
    {
      if (this->big_endian_)
	return this->sized_write_ehdr<64, true>();
      else
	return this->sized_write_ehdr<64, false>();
    }
  else
    gold_unreachable();
}

template<unsigned int size, bool big_endian>
void
Dwp_output_file::sized_write_ehdr()
{
  const unsigned int ehdr_size = elfcpp::Elf_sizes<size>::ehdr_size;
  unsigned char buf[ehdr_size];
  elfcpp::Ehdr_write<size, big_endian> ehdr(buf);

  unsigned char e_ident[elfcpp::EI_NIDENT];
  memset(e_ident, 0, elfcpp::EI_NIDENT);
  e_ident[elfcpp::EI_MAG0] = elfcpp::ELFMAG0;
  e_ident[elfcpp::EI_MAG1] = elfcpp::ELFMAG1;
  e_ident[elfcpp::EI_MAG2] = elfcpp::ELFMAG2;
  e_ident[elfcpp::EI_MAG3] = elfcpp::ELFMAG3;
  if (size == 32)
    e_ident[elfcpp::EI_CLASS] = elfcpp::ELFCLASS32;
  else if (size == 64)
    e_ident[elfcpp::EI_CLASS] = elfcpp::ELFCLASS64;
  else
    gold_unreachable();
  e_ident[elfcpp::EI_DATA] = (big_endian
			      ? elfcpp::ELFDATA2MSB
			      : elfcpp::ELFDATA2LSB);
  e_ident[elfcpp::EI_VERSION] = elfcpp::EV_CURRENT;
  ehdr.put_e_ident(e_ident);

  ehdr.put_e_type(elfcpp::ET_REL);
  ehdr.put_e_machine(this->machine_);
  ehdr.put_e_version(elfcpp::EV_CURRENT);
  ehdr.put_e_entry(0);
  ehdr.put_e_phoff(0);
  ehdr.put_e_shoff(this->shoff_);
  ehdr.put_e_flags(0);
  ehdr.put_e_ehsize(elfcpp::Elf_sizes<size>::ehdr_size);
  ehdr.put_e_phentsize(0);
  ehdr.put_e_phnum(0);
  ehdr.put_e_shentsize(elfcpp::Elf_sizes<size>::shdr_size);
  ehdr.put_e_shnum(this->shnum_ < elfcpp::SHN_LORESERVE ? this->shnum_ : 0);
  ehdr.put_e_shstrndx(this->shstrndx_ < elfcpp::SHN_LORESERVE
		      ? this->shstrndx_
		      : static_cast<unsigned int>(elfcpp::SHN_XINDEX));

  ::fseek(this->fd_, 0, 0);
  if (::fwrite(buf, 1, ehdr_size, this->fd_) < ehdr_size)
    gold_fatal(_("%s: error writing ELF header"), this->name_);
}

// Write a section header.

void
Dwp_output_file::write_shdr(const char* name, unsigned int type,
			    unsigned int flags, uint64_t addr, off_t offset,
			    section_size_type sect_size, unsigned int link,
			    unsigned int info, unsigned int align,
			    unsigned int ent_size)
{
  if (this->size_ == 32)
    {
      if (this->big_endian_)
	return this->sized_write_shdr<32, true>(name, type, flags, addr,
						offset, sect_size, link, info,
						align, ent_size);
      else
	return this->sized_write_shdr<32, false>(name, type, flags, addr,
						 offset, sect_size, link, info,
						 align, ent_size);
    }
  else if (this->size_ == 64)
    {
      if (this->big_endian_)
	return this->sized_write_shdr<64, true>(name, type, flags, addr,
						offset, sect_size, link, info,
						align, ent_size);
      else
	return this->sized_write_shdr<64, false>(name, type, flags, addr,
						 offset, sect_size, link, info,
						 align, ent_size);
    }
  else
    gold_unreachable();
}

template<unsigned int size, bool big_endian>
void
Dwp_output_file::sized_write_shdr(const char* name, unsigned int type,
				  unsigned int flags, uint64_t addr,
				  off_t offset, section_size_type sect_size,
				  unsigned int link, unsigned int info,
				  unsigned int align, unsigned int ent_size)
{
  const unsigned int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
  unsigned char buf[shdr_size];
  elfcpp::Shdr_write<size, big_endian> shdr(buf);

  shdr.put_sh_name(name == NULL ? 0 : this->shstrtab_.get_offset(name));
  shdr.put_sh_type(type);
  shdr.put_sh_flags(flags);
  shdr.put_sh_addr(addr);
  shdr.put_sh_offset(offset);
  shdr.put_sh_size(sect_size);
  shdr.put_sh_link(link);
  shdr.put_sh_info(info);
  shdr.put_sh_addralign(align);
  shdr.put_sh_entsize(ent_size);
  if (::fwrite(buf, 1, shdr_size, this->fd_) < shdr_size)
    gold_fatal(_("%s: error writing section header table"), this->name_);
}

// Class Dwo_name_info_reader.

// Visit a compilation unit.

void
Dwo_name_info_reader::visit_compilation_unit(off_t, off_t, Dwarf_die* die)
{
  const char* dwo_name = die->string_attribute(elfcpp::DW_AT_GNU_dwo_name);
  if (dwo_name != NULL)
    {
      uint64_t dwo_id = die->uint_attribute(elfcpp::DW_AT_GNU_dwo_id);
      this->files_->push_back(Dwo_file_entry(dwo_id, dwo_name));
    }
}

// Class Unit_reader.

// Read the CUs or TUs and add them to the output file.

void
Unit_reader::add_units(Dwp_output_file* output_file,
		       unsigned int debug_abbrev,
		       Section_bounds* sections)
{
  this->output_file_ = output_file;
  this->sections_ = sections;
  this->set_abbrev_shndx(debug_abbrev);
  this->parse();
}

// Visit a compilation unit.

void
Unit_reader::visit_compilation_unit(off_t, off_t cu_length, Dwarf_die* die)
{
  if (cu_length == 0)
    return;

  Unit_set* unit_set = new Unit_set();
  unit_set->signature = die->uint_attribute(elfcpp::DW_AT_GNU_dwo_id);
  for (unsigned int i = elfcpp::DW_SECT_ABBREV; i <= elfcpp::DW_SECT_MAX; ++i)
    unit_set->sections[i] = this->sections_[i];

  // Dwp_output_file::add_contribution writes the .debug_info.dwo section
  // directly to the output file, so we do not need to duplicate the
  // section contents, and add_contribution does not need to free the memory.
  section_offset_type off =
      this->output_file_->add_contribution(elfcpp::DW_SECT_INFO,
					   this->buffer_at_offset(0),
					   cu_length, 1);
  Section_bounds bounds(off, cu_length);
  unit_set->sections[elfcpp::DW_SECT_INFO] = bounds;
  this->output_file_->add_cu_set(unit_set);
}

// Visit a type unit.

void
Unit_reader::visit_type_unit(off_t, off_t tu_length, off_t,
			     uint64_t signature, Dwarf_die*)
{
  if (tu_length == 0)
    return;
  if (this->output_file_->lookup_tu(signature))
    return;

  Unit_set* unit_set = new Unit_set();
  unit_set->signature = signature;
  for (unsigned int i = elfcpp::DW_SECT_ABBREV; i <= elfcpp::DW_SECT_MAX; ++i)
    unit_set->sections[i] = this->sections_[i];

  unsigned char* contents = new unsigned char[tu_length];
  memcpy(contents, this->buffer_at_offset(0), tu_length);
  section_offset_type off =
      this->output_file_->add_contribution(elfcpp::DW_SECT_TYPES, contents,
					   tu_length, 1);
  Section_bounds bounds(off, tu_length);
  unit_set->sections[elfcpp::DW_SECT_TYPES] = bounds;
  this->output_file_->add_tu_set(unit_set);
}

}; // End namespace gold

using namespace gold;

// Options.

enum Dwp_options {
  VERIFY_ONLY = 0x101,
};

struct option dwp_options[] =
  {
    { "exec", required_argument, NULL, 'e' },
    { "help", no_argument, NULL, 'h' },
    { "output", required_argument, NULL, 'o' },
    { "verbose", no_argument, NULL, 'v' },
    { "verify-only", no_argument, NULL, VERIFY_ONLY },
    { "version", no_argument, NULL, 'V' },
    { NULL, 0, NULL, 0 }
  };

// Print usage message and exit.

static void
usage(FILE* fd, int exit_status)
{
  fprintf(fd, _("Usage: %s [options] [file...]\n"), program_name);
  fprintf(fd, _("  -h, --help               Print this help message\n"));
  fprintf(fd, _("  -e EXE, --exec EXE       Get list of dwo files from EXE"
					   " (defaults output to EXE.dwp)\n"));
  fprintf(fd, _("  -o FILE, --output FILE   Set output dwp file name\n"));
  fprintf(fd, _("  -v, --verbose            Verbose output\n"));
  fprintf(fd, _("  --verify-only            Verify output file against"
					   " exec file\n"));
  fprintf(fd, _("  -V, --version            Print version number\n"));

  // REPORT_BUGS_TO is defined in bfd/bfdver.h.
  const char* report = REPORT_BUGS_TO;
  if (*report != '\0')
    fprintf(fd, _("\nReport bugs to %s\n"), report);
  exit(exit_status);
}

// Report version information.

static void
print_version()
{
  // This output is intended to follow the GNU standards.
  printf("GNU dwp %s\n", BFD_VERSION_STRING);
  printf(_("Copyright (C) 2021 Free Software Foundation, Inc.\n"));
  printf(_("\
This program is free software; you may redistribute it under the terms of\n\
the GNU General Public License version 3 or (at your option) any later version.\n\
This program has absolutely no warranty.\n"));
  exit(EXIT_SUCCESS);
}

// Main program.

int
main(int argc, char** argv)
{
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
  setlocale(LC_MESSAGES, "");
#endif
#if defined (HAVE_SETLOCALE)
  setlocale(LC_CTYPE, "");
#endif
  bindtextdomain(PACKAGE, LOCALEDIR);
  textdomain(PACKAGE);

  program_name = argv[0];

  // Initialize the global parameters, to let random code get to the
  // errors object.
  Errors errors(program_name);
  set_parameters_errors(&errors);

  // Initialize gold's global options.  We don't use these in
  // this program, but they need to be initialized so that
  // functions we call from libgold work properly.
  General_options options;
  set_parameters_options(&options);

  // In libiberty; expands @filename to the args in "filename".
  expandargv(&argc, &argv);

  // Collect file names and options.
  File_list files;
  std::string output_filename;
  const char* exe_filename = NULL;
  bool verbose = false;
  bool verify_only = false;
  int c;
  while ((c = getopt_long(argc, argv, "e:ho:vV", dwp_options, NULL)) != -1)
    {
      switch (c)
        {
	  case 'h':
	    usage(stdout, EXIT_SUCCESS);
	  case 'e':
	    exe_filename = optarg;
	    break;
	  case 'o':
	    output_filename.assign(optarg);
	    break;
	  case 'v':
	    verbose = true;
	    break;
	  case VERIFY_ONLY:
	    verify_only = true;
	    break;
	  case 'V':
	    print_version();
	  case '?':
	  default:
	    usage(stderr, EXIT_FAILURE);
	}
    }

  if (output_filename.empty())
    {
      if (exe_filename == NULL)
	gold_fatal(_("no output file specified"));
      output_filename.assign(exe_filename);
      output_filename.append(".dwp");
    }

  // Get list of .dwo files from the executable.
  if (exe_filename != NULL)
    {
      Dwo_file exe_file(exe_filename);
      exe_file.read_executable(&files);
    }

  // Add any additional files listed on command line.
  for (int i = optind; i < argc; ++i)
    files.push_back(Dwo_file_entry(0, argv[i]));

  if (exe_filename == NULL && files.empty())
    gold_fatal(_("no input files and no executable specified"));

  if (verify_only)
    {
      // Get list of DWO files in the DWP file and compare with
      // references found in the EXE file.
      Dwo_file dwp_file(output_filename.c_str());
      bool ok = dwp_file.verify(files);
      return ok ? EXIT_SUCCESS : EXIT_FAILURE;
    }

  // Process each file, adding its contents to the output file.
  Dwp_output_file output_file(output_filename.c_str());
  for (File_list::const_iterator f = files.begin(); f != files.end(); ++f)
    {
      if (verbose)
	fprintf(stderr, "%s\n", f->dwo_name.c_str());
      Dwo_file dwo_file(f->dwo_name.c_str());
      dwo_file.read(&output_file);
    }
  output_file.finalize();

  return EXIT_SUCCESS;
}
