// dwarf_reader.cc -- parse dwarf2/3 debug information

// Copyright 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.

// This file is part of gold.

// 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 "gold.h"

#include <algorithm>
#include <utility>
#include <vector>

#include "elfcpp_swap.h"
#include "dwarf.h"
#include "object.h"
#include "reloc.h"
#include "dwarf_reader.h"
#include "int_encoding.h"
#include "compressed_output.h"

namespace gold {

// Class Sized_elf_reloc_mapper

// Initialize the relocation tracker for section RELOC_SHNDX.

template<int size, bool big_endian>
bool
Sized_elf_reloc_mapper<size, big_endian>::do_initialize(
    unsigned int reloc_shndx, unsigned int reloc_type)
{
  this->reloc_type_ = reloc_type;
  return this->track_relocs_.initialize(this->object_, reloc_shndx,
					reloc_type);
}

// Looks in the symtab to see what section a symbol is in.

template<int size, bool big_endian>
unsigned int
Sized_elf_reloc_mapper<size, big_endian>::symbol_section(
    unsigned int symndx, Address* value, bool* is_ordinary)
{
  const int symsize = elfcpp::Elf_sizes<size>::sym_size;
  gold_assert((symndx + 1) * symsize <= this->symtab_size_);
  elfcpp::Sym<size, big_endian> elfsym(this->symtab_ + symndx * symsize);
  *value = elfsym.get_st_value();
  return this->object_->adjust_sym_shndx(symndx, elfsym.get_st_shndx(),
					 is_ordinary);
}

// Return the section index and offset within the section of
// the target of the relocation for RELOC_OFFSET.

template<int size, bool big_endian>
unsigned int
Sized_elf_reloc_mapper<size, big_endian>::do_get_reloc_target(
    off_t reloc_offset, off_t* target_offset)
{
  this->track_relocs_.advance(reloc_offset);
  if (reloc_offset != this->track_relocs_.next_offset())
    return 0;
  unsigned int symndx = this->track_relocs_.next_symndx();
  typename elfcpp::Elf_types<size>::Elf_Addr value;
  bool is_ordinary;
  unsigned int target_shndx = this->symbol_section(symndx, &value,
						   &is_ordinary);
  if (!is_ordinary)
    return 0;
  if (this->reloc_type_ == elfcpp::SHT_RELA)
    value += this->track_relocs_.next_addend();
  *target_offset = value;
  return target_shndx;
}

static inline Elf_reloc_mapper*
make_elf_reloc_mapper(Relobj* object, const unsigned char* symtab,
		      off_t symtab_size)
{
  if (object->elfsize() == 32)
    {
      if (object->is_big_endian())
        {
#ifdef HAVE_TARGET_32_BIG
	  return new Sized_elf_reloc_mapper<32, true>(object, symtab,
						      symtab_size);
#else
	  gold_unreachable();
#endif
        }
      else
        {
#ifdef HAVE_TARGET_32_LITTLE
	  return new Sized_elf_reloc_mapper<32, false>(object, symtab,
						       symtab_size);
#else
	  gold_unreachable();
#endif
        }
    }
  else if (object->elfsize() == 64)
    {
      if (object->is_big_endian())
        {
#ifdef HAVE_TARGET_64_BIG
	  return new Sized_elf_reloc_mapper<64, true>(object, symtab,
						      symtab_size);
#else
	  gold_unreachable();
#endif
        }
      else
        {
#ifdef HAVE_TARGET_64_LITTLE
	  return new Sized_elf_reloc_mapper<64, false>(object, symtab,
						       symtab_size);
#else
	  gold_unreachable();
#endif
        }
    }
  else
    gold_unreachable();
}

// class Dwarf_abbrev_table

void
Dwarf_abbrev_table::clear_abbrev_codes()
{
  for (unsigned int code = 0; code < this->low_abbrev_code_max_; ++code)
    {
      if (this->low_abbrev_codes_[code] != NULL)
	{
	  delete this->low_abbrev_codes_[code];
	  this->low_abbrev_codes_[code] = NULL;
	}
    }
  for (Abbrev_code_table::iterator it = this->high_abbrev_codes_.begin();
       it != this->high_abbrev_codes_.end();
       ++it)
    {
      if (it->second != NULL)
	delete it->second;
    }
  this->high_abbrev_codes_.clear();
}

// Read the abbrev table from an object file.

bool
Dwarf_abbrev_table::do_read_abbrevs(
    Relobj* object,
    unsigned int abbrev_shndx,
    off_t abbrev_offset)
{
  this->clear_abbrev_codes();

  // If we don't have relocations, abbrev_shndx will be 0, and
  // we'll have to hunt for the .debug_abbrev section.
  if (abbrev_shndx == 0 && this->abbrev_shndx_ > 0)
    abbrev_shndx = this->abbrev_shndx_;
  else if (abbrev_shndx == 0)
    {
      for (unsigned int i = 1; i < object->shnum(); ++i)
	{
	  std::string name = object->section_name(i);
	  if (name == ".debug_abbrev" || name == ".zdebug_abbrev")
	    {
	      abbrev_shndx = i;
	      // Correct the offset.  For incremental update links, we have a
	      // relocated offset that is relative to the output section, but
	      // here we need an offset relative to the input section.
	      abbrev_offset -= object->output_section_offset(i);
	      break;
	    }
	}
      if (abbrev_shndx == 0)
	return false;
    }

  // Get the section contents and decompress if necessary.
  if (abbrev_shndx != this->abbrev_shndx_)
    {
      if (this->owns_buffer_ && this->buffer_ != NULL)
        {
	  delete[] this->buffer_;
	  this->owns_buffer_ = false;
        }

      section_size_type buffer_size;
      this->buffer_ =
	  object->decompressed_section_contents(abbrev_shndx,
						&buffer_size,
						&this->owns_buffer_);
      this->buffer_end_ = this->buffer_ + buffer_size;
      this->abbrev_shndx_ = abbrev_shndx;
    }

  this->buffer_pos_ = this->buffer_ + abbrev_offset;
  return true;
}

// Lookup the abbrev code entry for CODE.  This function is called
// only when the abbrev code is not in the direct lookup table.
// It may be in the hash table, it may not have been read yet,
// or it may not exist in the abbrev table.

const Dwarf_abbrev_table::Abbrev_code*
Dwarf_abbrev_table::do_get_abbrev(unsigned int code)
{
  // See if the abbrev code is already in the hash table.
  Abbrev_code_table::const_iterator it = this->high_abbrev_codes_.find(code);
  if (it != this->high_abbrev_codes_.end())
    return it->second;

  // Read and store abbrev code definitions until we find the
  // one we're looking for.
  for (;;)
    {
      // Read the abbrev code.  A zero here indicates the end of the
      // abbrev table.
      size_t len;
      if (this->buffer_pos_ >= this->buffer_end_)
	return NULL;
      uint64_t nextcode = read_unsigned_LEB_128(this->buffer_pos_, &len);
      if (nextcode == 0)
	{
	  this->buffer_pos_ = this->buffer_end_;
	  return NULL;
	}
      this->buffer_pos_ += len;

      // Read the tag.
      if (this->buffer_pos_ >= this->buffer_end_)
	return NULL;
      uint64_t tag = read_unsigned_LEB_128(this->buffer_pos_, &len);
      this->buffer_pos_ += len;

      // Read the has_children flag.
      if (this->buffer_pos_ >= this->buffer_end_)
	return NULL;
      bool has_children = *this->buffer_pos_ == elfcpp::DW_CHILDREN_yes;
      this->buffer_pos_ += 1;

      // Read the list of (attribute, form) pairs.
      Abbrev_code* entry = new Abbrev_code(tag, has_children);
      for (;;)
	{
	  // Read the attribute.
	  if (this->buffer_pos_ >= this->buffer_end_)
	    return NULL;
	  uint64_t attr = read_unsigned_LEB_128(this->buffer_pos_, &len);
	  this->buffer_pos_ += len;

	  // Read the form.
	  if (this->buffer_pos_ >= this->buffer_end_)
	    return NULL;
	  uint64_t form = read_unsigned_LEB_128(this->buffer_pos_, &len);
	  this->buffer_pos_ += len;

	  // A (0,0) pair terminates the list.
	  if (attr == 0 && form == 0)
	    break;

	  if (attr == elfcpp::DW_AT_sibling)
	    entry->has_sibling_attribute = true;

	  entry->add_attribute(attr, form);
	}

      this->store_abbrev(nextcode, entry);
      if (nextcode == code)
	return entry;
    }

  return NULL;
}

// class Dwarf_ranges_table

// Read the ranges table from an object file.

bool
Dwarf_ranges_table::read_ranges_table(
    Relobj* object,
    const unsigned char* symtab,
    off_t symtab_size,
    unsigned int ranges_shndx)
{
  // If we've already read this abbrev table, return immediately.
  if (this->ranges_shndx_ > 0
      && this->ranges_shndx_ == ranges_shndx)
    return true;

  // If we don't have relocations, ranges_shndx will be 0, and
  // we'll have to hunt for the .debug_ranges section.
  if (ranges_shndx == 0 && this->ranges_shndx_ > 0)
    ranges_shndx = this->ranges_shndx_;
  else if (ranges_shndx == 0)
    {
      for (unsigned int i = 1; i < object->shnum(); ++i)
	{
	  std::string name = object->section_name(i);
	  if (name == ".debug_ranges" || name == ".zdebug_ranges")
	    {
	      ranges_shndx = i;
	      this->output_section_offset_ = object->output_section_offset(i);
	      break;
	    }
	}
      if (ranges_shndx == 0)
	return false;
    }

  // Get the section contents and decompress if necessary.
  if (ranges_shndx != this->ranges_shndx_)
    {
      if (this->owns_ranges_buffer_ && this->ranges_buffer_ != NULL)
        {
	  delete[] this->ranges_buffer_;
	  this->owns_ranges_buffer_ = false;
        }

      section_size_type buffer_size;
      this->ranges_buffer_ =
	  object->decompressed_section_contents(ranges_shndx,
						&buffer_size,
						&this->owns_ranges_buffer_);
      this->ranges_buffer_end_ = this->ranges_buffer_ + buffer_size;
      this->ranges_shndx_ = ranges_shndx;
    }

  if (this->ranges_reloc_mapper_ != NULL)
    {
      delete this->ranges_reloc_mapper_;
      this->ranges_reloc_mapper_ = NULL;
    }

  // For incremental objects, we have no relocations.
  if (object->is_incremental())
    return true;

  // Find the relocation section for ".debug_ranges".
  unsigned int reloc_shndx = 0;
  unsigned int reloc_type = 0;
  for (unsigned int i = 0; i < object->shnum(); ++i)
    {
      reloc_type = object->section_type(i);
      if ((reloc_type == elfcpp::SHT_REL
	   || reloc_type == elfcpp::SHT_RELA)
	  && object->section_info(i) == ranges_shndx)
	{
	  reloc_shndx = i;
	  break;
	}
    }

  this->ranges_reloc_mapper_ = make_elf_reloc_mapper(object, symtab,
						     symtab_size);
  this->ranges_reloc_mapper_->initialize(reloc_shndx, reloc_type);

  return true;
}

// Read a range list from section RANGES_SHNDX at offset RANGES_OFFSET.

Dwarf_range_list*
Dwarf_ranges_table::read_range_list(
    Relobj* object,
    const unsigned char* symtab,
    off_t symtab_size,
    unsigned int addr_size,
    unsigned int ranges_shndx,
    off_t offset)
{
  Dwarf_range_list* ranges;

  if (!this->read_ranges_table(object, symtab, symtab_size, ranges_shndx))
    return NULL;

  // Correct the offset.  For incremental update links, we have a
  // relocated offset that is relative to the output section, but
  // here we need an offset relative to the input section.
  offset -= this->output_section_offset_;

  // Read the range list at OFFSET.
  ranges = new Dwarf_range_list();
  off_t base = 0;
  for (;
       this->ranges_buffer_ + offset < this->ranges_buffer_end_;
       offset += 2 * addr_size)
    {
      off_t start;
      off_t end;

      // Read the raw contents of the section.
      if (addr_size == 4)
	{
	  start = this->dwinfo_->read_from_pointer<32>(this->ranges_buffer_
						       + offset);
	  end = this->dwinfo_->read_from_pointer<32>(this->ranges_buffer_
						     + offset + 4);
	}
      else
	{
	  start = this->dwinfo_->read_from_pointer<64>(this->ranges_buffer_
						       + offset);
	  end = this->dwinfo_->read_from_pointer<64>(this->ranges_buffer_
						     + offset + 8);
	}

      // Check for relocations and adjust the values.
      unsigned int shndx1 = 0;
      unsigned int shndx2 = 0;
      if (this->ranges_reloc_mapper_ != NULL)
        {
	  shndx1 =
	      this->ranges_reloc_mapper_->get_reloc_target(offset, &start);
	  shndx2 =
	      this->ranges_reloc_mapper_->get_reloc_target(offset + addr_size,
							   &end);
        }

      // End of list is marked by a pair of zeroes.
      if (shndx1 == 0 && start == 0 && end == 0)
        break;

      // A "base address selection entry" is identified by
      // 0xffffffff for the first value of the pair.  The second
      // value is used as a base for subsequent range list entries.
      if (shndx1 == 0 && start == -1)
	base = end;
      else if (shndx1 == shndx2)
	{
	  if (shndx1 == 0 || object->is_section_included(shndx1))
	    ranges->add(shndx1, base + start, base + end);
	}
      else
	gold_warning(_("%s: DWARF info may be corrupt; offsets in a "
		       "range list entry are in different sections"),
		     object->name().c_str());
    }

  return ranges;
}

// class Dwarf_pubnames_table

// Read the pubnames section SHNDX from the object file.

bool
Dwarf_pubnames_table::read_section(Relobj* object, unsigned int shndx)
{
  section_size_type buffer_size;

  // If we don't have relocations, shndx will be 0, and
  // we'll have to hunt for the .debug_pubnames/pubtypes section.
  if (shndx == 0)
    {
      const char* name = (this->is_pubtypes_ ? "pubtypes" : "pubnames");
      const char* gnu_name = (this->is_pubtypes_
                              ? "gnu_pubtypes"
                              : "gnu_pubnames");
      for (unsigned int i = 1; i < object->shnum(); ++i)
	{
	  std::string section_name = object->section_name(i);
	  const char* section_name_suffix = section_name.c_str();
	  if (is_prefix_of(".debug_", section_name_suffix))
	    section_name_suffix += 7;
	  else if (is_prefix_of(".zdebug_", section_name_suffix))
	    section_name_suffix += 8;
	  else
	    continue;
	  if (strcmp(section_name_suffix, name) == 0)
	    {
	      shndx = i;
	      this->output_section_offset_ = object->output_section_offset(i);
	      break;
	    }
	  else if (strcmp(section_name_suffix, gnu_name) == 0)
	    {
	      shndx = i;
	      this->output_section_offset_ = object->output_section_offset(i);
	      this->is_gnu_style_ = true;
	      break;
	    }
	}
      if (shndx == 0)
	return false;
    }
  else
    {
      std::string section_name = object->section_name(shndx);
      if (is_prefix_of(".debug_gnu", section_name.c_str())
	  || is_prefix_of(".zdebug_gnu_", section_name.c_str()))
	this->is_gnu_style_ = true;
    }

  this->buffer_ = object->decompressed_section_contents(shndx,
							&buffer_size,
							&this->owns_buffer_);
  if (this->buffer_ == NULL)
    return false;
  this->buffer_end_ = this->buffer_ + buffer_size;
  return true;
}

// Read the header for the set at OFFSET.

bool
Dwarf_pubnames_table::read_header(off_t offset)
{
  // Correct the offset.  For incremental update links, we have a
  // relocated offset that is relative to the output section, but
  // here we need an offset relative to the input section.
  offset -= this->output_section_offset_;

  if (offset < 0 || offset + 14 >= this->buffer_end_ - this->buffer_)
    return false;

  const unsigned char* pinfo = this->buffer_ + offset;

  // Read the unit_length field.
  uint32_t unit_length = this->dwinfo_->read_from_pointer<32>(pinfo);
  pinfo += 4;
  if (unit_length == 0xffffffff)
    {
      unit_length = this->dwinfo_->read_from_pointer<64>(pinfo);
      pinfo += 8;
      this->offset_size_ = 8;
    }
  else
    this->offset_size_ = 4;
  this->end_of_table_ = pinfo + unit_length;

  // Check the version.
  unsigned int version = this->dwinfo_->read_from_pointer<16>(pinfo);
  pinfo += 2;
  if (version != 2)
    return false;
  
  // Skip the debug_info_offset and debug_info_size fields.
  pinfo += 2 * this->offset_size_;

  if (pinfo >= this->buffer_end_)
    return false;

  this->pinfo_ = pinfo;
  return true;
}

// Read the next name from the set.

const char*
Dwarf_pubnames_table::next_name(uint8_t* flag_byte)
{
  const unsigned char* pinfo = this->pinfo_;

  // Check for end of list.  The table should be terminated by an
  // entry containing nothing but a DIE offset of 0.
  if (pinfo + this->offset_size_ >= this->end_of_table_)
    return NULL;

  // Skip the offset within the CU.  If this is zero, but we're not
  // at the end of the table, then we have a real pubnames entry
  // whose DIE offset is 0 (likely to be a GCC bug).  Since we
  // don't actually use the DIE offset in building .gdb_index,
  // it's harmless.
  pinfo += this->offset_size_;

  if (this->is_gnu_style_)
    *flag_byte = read_from_pointer<8>(&pinfo);
  else
    *flag_byte = 0;

  // Return a pointer to the string at the current location,
  // and advance the pointer to the next entry.
  const char* ret = reinterpret_cast<const char*>(pinfo);
  while (pinfo < this->buffer_end_ && *pinfo != '\0')
    ++pinfo;
  if (pinfo < this->buffer_end_)
    ++pinfo;

  this->pinfo_ = pinfo;
  return ret;
}

// class Dwarf_die

Dwarf_die::Dwarf_die(
    Dwarf_info_reader* dwinfo,
    off_t die_offset,
    Dwarf_die* parent)
  : dwinfo_(dwinfo), parent_(parent), die_offset_(die_offset),
    child_offset_(0), sibling_offset_(0), abbrev_code_(NULL), attributes_(),
    attributes_read_(false), name_(NULL), name_off_(-1), linkage_name_(NULL),
    linkage_name_off_(-1), string_shndx_(0), specification_(0),
    abstract_origin_(0)
{
  size_t len;
  const unsigned char* pdie = dwinfo->buffer_at_offset(die_offset);
  if (pdie == NULL)
    return;
  unsigned int code = read_unsigned_LEB_128(pdie, &len);
  if (code == 0)
    {
      if (parent != NULL)
	parent->set_sibling_offset(die_offset + len);
      return;
    }
  this->attr_offset_ = len;

  // Lookup the abbrev code in the abbrev table.
  this->abbrev_code_ = dwinfo->get_abbrev(code);
}

// Read all the attributes of the DIE.

bool
Dwarf_die::read_attributes()
{
  if (this->attributes_read_)
    return true;

  gold_assert(this->abbrev_code_ != NULL);

  const unsigned char* pdie =
      this->dwinfo_->buffer_at_offset(this->die_offset_);
  if (pdie == NULL)
    return false;
  const unsigned char* pattr = pdie + this->attr_offset_;

  unsigned int nattr = this->abbrev_code_->attributes.size();
  this->attributes_.reserve(nattr);
  for (unsigned int i = 0; i < nattr; ++i)
    {
      size_t len;
      unsigned int attr = this->abbrev_code_->attributes[i].attr;
      unsigned int form = this->abbrev_code_->attributes[i].form;
      if (form == elfcpp::DW_FORM_indirect)
        {
          form = read_unsigned_LEB_128(pattr, &len);
          pattr += len;
        }
      off_t attr_off = this->die_offset_ + (pattr - pdie);
      bool ref_form = false;
      Attribute_value attr_value;
      attr_value.attr = attr;
      attr_value.form = form;
      attr_value.aux.shndx = 0;
      switch(form)
	{
	  case elfcpp::DW_FORM_null:
	    attr_value.val.intval = 0;
	    break;
	  case elfcpp::DW_FORM_flag_present:
	    attr_value.val.intval = 1;
	    break;
	  case elfcpp::DW_FORM_strp:
	    {
	      off_t str_off;
	      if (this->dwinfo_->offset_size() == 4)
		str_off = this->dwinfo_->read_from_pointer<32>(&pattr);
	      else
		str_off = this->dwinfo_->read_from_pointer<64>(&pattr);
	      unsigned int shndx =
		  this->dwinfo_->lookup_reloc(attr_off, &str_off);
	      attr_value.aux.shndx = shndx;
	      attr_value.val.refval = str_off;
	      break;
	    }
	  case elfcpp::DW_FORM_sec_offset:
	    {
	      off_t sec_off;
	      if (this->dwinfo_->offset_size() == 4)
		sec_off = this->dwinfo_->read_from_pointer<32>(&pattr);
	      else
		sec_off = this->dwinfo_->read_from_pointer<64>(&pattr);
	      unsigned int shndx =
		  this->dwinfo_->lookup_reloc(attr_off, &sec_off);
	      attr_value.aux.shndx = shndx;
	      attr_value.val.refval = sec_off;
	      ref_form = true;
	      break;
	    }
	  case elfcpp::DW_FORM_addr:
	  case elfcpp::DW_FORM_ref_addr:
	    {
	      off_t sec_off;
	      if (this->dwinfo_->address_size() == 4)
		sec_off = this->dwinfo_->read_from_pointer<32>(&pattr);
	      else
		sec_off = this->dwinfo_->read_from_pointer<64>(&pattr);
	      unsigned int shndx =
		  this->dwinfo_->lookup_reloc(attr_off, &sec_off);
	      attr_value.aux.shndx = shndx;
	      attr_value.val.refval = sec_off;
	      ref_form = true;
	      break;
	    }
	  case elfcpp::DW_FORM_block1:
	    attr_value.aux.blocklen = *pattr++;
	    attr_value.val.blockval = pattr;
	    pattr += attr_value.aux.blocklen;
	    break;
	  case elfcpp::DW_FORM_block2:
	    attr_value.aux.blocklen =
		this->dwinfo_->read_from_pointer<16>(&pattr);
	    attr_value.val.blockval = pattr;
	    pattr += attr_value.aux.blocklen;
	    break;
	  case elfcpp::DW_FORM_block4:
	    attr_value.aux.blocklen =
		this->dwinfo_->read_from_pointer<32>(&pattr);
	    attr_value.val.blockval = pattr;
	    pattr += attr_value.aux.blocklen;
	    break;
	  case elfcpp::DW_FORM_block:
	  case elfcpp::DW_FORM_exprloc:
	    attr_value.aux.blocklen = read_unsigned_LEB_128(pattr, &len);
	    attr_value.val.blockval = pattr + len;
	    pattr += len + attr_value.aux.blocklen;
	    break;
	  case elfcpp::DW_FORM_data1:
	  case elfcpp::DW_FORM_flag:
	    attr_value.val.intval = *pattr++;
	    break;
	  case elfcpp::DW_FORM_ref1:
	    attr_value.val.refval = *pattr++;
	    ref_form = true;
	    break;
	  case elfcpp::DW_FORM_data2:
	    attr_value.val.intval =
		this->dwinfo_->read_from_pointer<16>(&pattr);
	    break;
	  case elfcpp::DW_FORM_ref2:
	    attr_value.val.refval =
		this->dwinfo_->read_from_pointer<16>(&pattr);
	    ref_form = true;
	    break;
	  case elfcpp::DW_FORM_data4:
	    {
	      off_t sec_off;
	      sec_off = this->dwinfo_->read_from_pointer<32>(&pattr);
	      unsigned int shndx =
		  this->dwinfo_->lookup_reloc(attr_off, &sec_off);
	      attr_value.aux.shndx = shndx;
	      attr_value.val.intval = sec_off;
	      break;
	    }
	  case elfcpp::DW_FORM_ref4:
	    {
	      off_t sec_off;
	      sec_off = this->dwinfo_->read_from_pointer<32>(&pattr);
	      unsigned int shndx =
		  this->dwinfo_->lookup_reloc(attr_off, &sec_off);
	      attr_value.aux.shndx = shndx;
	      attr_value.val.refval = sec_off;
	      ref_form = true;
	      break;
	    }
	  case elfcpp::DW_FORM_data8:
	    {
	      off_t sec_off;
	      sec_off = this->dwinfo_->read_from_pointer<64>(&pattr);
	      unsigned int shndx =
		  this->dwinfo_->lookup_reloc(attr_off, &sec_off);
	      attr_value.aux.shndx = shndx;
	      attr_value.val.intval = sec_off;
	      break;
	    }
	  case elfcpp::DW_FORM_ref_sig8:
	    attr_value.val.uintval =
		this->dwinfo_->read_from_pointer<64>(&pattr);
	    break;
	  case elfcpp::DW_FORM_ref8:
	    {
	      off_t sec_off;
	      sec_off = this->dwinfo_->read_from_pointer<64>(&pattr);
	      unsigned int shndx =
		  this->dwinfo_->lookup_reloc(attr_off, &sec_off);
	      attr_value.aux.shndx = shndx;
	      attr_value.val.refval = sec_off;
	      ref_form = true;
	      break;
	    }
	  case elfcpp::DW_FORM_ref_udata:
	    attr_value.val.refval = read_unsigned_LEB_128(pattr, &len);
	    ref_form = true;
	    pattr += len;
	    break;
	  case elfcpp::DW_FORM_udata:
	    attr_value.val.uintval = read_unsigned_LEB_128(pattr, &len);
	    pattr += len;
	    break;
	  case elfcpp::DW_FORM_sdata:
	    attr_value.val.intval = read_signed_LEB_128(pattr, &len);
	    pattr += len;
	    break;
	  case elfcpp::DW_FORM_string:
	    attr_value.val.stringval = reinterpret_cast<const char*>(pattr);
	    len = strlen(attr_value.val.stringval);
	    pattr += len + 1;
	    break;
	  default:
	    return false;
	}

      // Cache the most frequently-requested attributes.
      switch (attr)
	{
	  case elfcpp::DW_AT_name:
	    if (form == elfcpp::DW_FORM_string)
	      this->name_ = attr_value.val.stringval;
	    else if (form == elfcpp::DW_FORM_strp)
	      {
		// All indirect strings should refer to the same
		// string section, so we just save the last one seen.
		this->string_shndx_ = attr_value.aux.shndx;
		this->name_off_ = attr_value.val.refval;
	      }
	    break;
	  case elfcpp::DW_AT_linkage_name:
	  case elfcpp::DW_AT_MIPS_linkage_name:
	    if (form == elfcpp::DW_FORM_string)
	      this->linkage_name_ = attr_value.val.stringval;
	    else if (form == elfcpp::DW_FORM_strp)
	      {
		// All indirect strings should refer to the same
		// string section, so we just save the last one seen.
		this->string_shndx_ = attr_value.aux.shndx;
		this->linkage_name_off_ = attr_value.val.refval;
	      }
	    break;
	  case elfcpp::DW_AT_specification:
	    if (ref_form)
	      this->specification_ = attr_value.val.refval;
	    break;
	  case elfcpp::DW_AT_abstract_origin:
	    if (ref_form)
	      this->abstract_origin_ = attr_value.val.refval;
	    break;
	  case elfcpp::DW_AT_sibling:
	    if (ref_form && attr_value.aux.shndx == 0)
	      this->sibling_offset_ = attr_value.val.refval;
	  default:
	    break;
	}

      this->attributes_.push_back(attr_value);
    }

  // Now that we know where the next DIE begins, record the offset
  // to avoid later recalculation.
  if (this->has_children())
    this->child_offset_ = this->die_offset_ + (pattr - pdie);
  else
    this->sibling_offset_ = this->die_offset_ + (pattr - pdie);

  this->attributes_read_ = true;
  return true;
}

// Skip all the attributes of the DIE and return the offset of the next DIE.

off_t
Dwarf_die::skip_attributes()
{
  typedef Dwarf_abbrev_table::Attribute Attribute;

  gold_assert(this->abbrev_code_ != NULL);

  const unsigned char* pdie =
      this->dwinfo_->buffer_at_offset(this->die_offset_);
  if (pdie == NULL)
    return 0;
  const unsigned char* pattr = pdie + this->attr_offset_;

  for (unsigned int i = 0; i < this->abbrev_code_->attributes.size(); ++i)
    {
      size_t len;
      unsigned int form = this->abbrev_code_->attributes[i].form;
      if (form == elfcpp::DW_FORM_indirect)
        {
          form = read_unsigned_LEB_128(pattr, &len);
          pattr += len;
        }
      switch(form)
	{
	  case elfcpp::DW_FORM_null:
	  case elfcpp::DW_FORM_flag_present:
	    break;
	  case elfcpp::DW_FORM_strp:
	  case elfcpp::DW_FORM_sec_offset:
	    pattr += this->dwinfo_->offset_size();
	    break;
	  case elfcpp::DW_FORM_addr:
	  case elfcpp::DW_FORM_ref_addr:
	    pattr += this->dwinfo_->address_size();
	    break;
	  case elfcpp::DW_FORM_block1:
	    pattr += 1 + *pattr;
	    break;
	  case elfcpp::DW_FORM_block2:
	    {
	      uint16_t block_size;
	      block_size = this->dwinfo_->read_from_pointer<16>(&pattr);
	      pattr += block_size;
	      break;
	    }
	  case elfcpp::DW_FORM_block4:
	    {
	      uint32_t block_size;
	      block_size = this->dwinfo_->read_from_pointer<32>(&pattr);
	      pattr += block_size;
	      break;
	    }
	  case elfcpp::DW_FORM_block:
	  case elfcpp::DW_FORM_exprloc:
	    {
	      uint64_t block_size;
	      block_size = read_unsigned_LEB_128(pattr, &len);
	      pattr += len + block_size;
	      break;
	    }
	  case elfcpp::DW_FORM_data1:
	  case elfcpp::DW_FORM_ref1:
	  case elfcpp::DW_FORM_flag:
	    pattr += 1;
	    break;
	  case elfcpp::DW_FORM_data2:
	  case elfcpp::DW_FORM_ref2:
	    pattr += 2;
	    break;
	  case elfcpp::DW_FORM_data4:
	  case elfcpp::DW_FORM_ref4:
	    pattr += 4;
	    break;
	  case elfcpp::DW_FORM_data8:
	  case elfcpp::DW_FORM_ref8:
	  case elfcpp::DW_FORM_ref_sig8:
	    pattr += 8;
	    break;
	  case elfcpp::DW_FORM_ref_udata:
	  case elfcpp::DW_FORM_udata:
	    read_unsigned_LEB_128(pattr, &len);
	    pattr += len;
	    break;
	  case elfcpp::DW_FORM_sdata:
	    read_signed_LEB_128(pattr, &len);
	    pattr += len;
	    break;
	  case elfcpp::DW_FORM_string:
	    len = strlen(reinterpret_cast<const char*>(pattr));
	    pattr += len + 1;
	    break;
	  default:
	    return 0;
	}
    }

  return this->die_offset_ + (pattr - pdie);
}

// Get the name of the DIE and cache it.

void
Dwarf_die::set_name()
{
  if (this->name_ != NULL || !this->read_attributes())
    return;
  if (this->name_off_ != -1)
    this->name_ = this->dwinfo_->get_string(this->name_off_,
					    this->string_shndx_);
}

// Get the linkage name of the DIE and cache it.

void
Dwarf_die::set_linkage_name()
{
  if (this->linkage_name_ != NULL || !this->read_attributes())
    return;
  if (this->linkage_name_off_ != -1)
    this->linkage_name_ = this->dwinfo_->get_string(this->linkage_name_off_,
						    this->string_shndx_);
}

// Return the value of attribute ATTR.

const Dwarf_die::Attribute_value*
Dwarf_die::attribute(unsigned int attr)
{
  if (!this->read_attributes())
    return NULL;
  for (unsigned int i = 0; i < this->attributes_.size(); ++i)
    {
      if (this->attributes_[i].attr == attr)
        return &this->attributes_[i];
    }
  return NULL;
}

const char*
Dwarf_die::string_attribute(unsigned int attr)
{
  const Attribute_value* attr_val = this->attribute(attr);
  if (attr_val == NULL)
    return NULL;
  switch (attr_val->form)
    {
      case elfcpp::DW_FORM_string:
        return attr_val->val.stringval;
      case elfcpp::DW_FORM_strp:
	return this->dwinfo_->get_string(attr_val->val.refval,
					 attr_val->aux.shndx);
      default:
        return NULL;
    }
}

int64_t
Dwarf_die::int_attribute(unsigned int attr)
{
  const Attribute_value* attr_val = this->attribute(attr);
  if (attr_val == NULL)
    return 0;
  switch (attr_val->form)
    {
      case elfcpp::DW_FORM_null:
      case elfcpp::DW_FORM_flag_present:
      case elfcpp::DW_FORM_data1:
      case elfcpp::DW_FORM_flag:
      case elfcpp::DW_FORM_data2:
      case elfcpp::DW_FORM_data4:
      case elfcpp::DW_FORM_data8:
      case elfcpp::DW_FORM_sdata:
        return attr_val->val.intval;
      default:
        return 0;
    }
}

uint64_t
Dwarf_die::uint_attribute(unsigned int attr)
{
  const Attribute_value* attr_val = this->attribute(attr);
  if (attr_val == NULL)
    return 0;
  switch (attr_val->form)
    {
      case elfcpp::DW_FORM_null:
      case elfcpp::DW_FORM_flag_present:
      case elfcpp::DW_FORM_data1:
      case elfcpp::DW_FORM_flag:
      case elfcpp::DW_FORM_data4:
      case elfcpp::DW_FORM_data8:
      case elfcpp::DW_FORM_ref_sig8:
      case elfcpp::DW_FORM_udata:
        return attr_val->val.uintval;
      default:
        return 0;
    }
}

off_t
Dwarf_die::ref_attribute(unsigned int attr, unsigned int* shndx)
{
  const Attribute_value* attr_val = this->attribute(attr);
  if (attr_val == NULL)
    return -1;
  switch (attr_val->form)
    {
      case elfcpp::DW_FORM_sec_offset:
      case elfcpp::DW_FORM_addr:
      case elfcpp::DW_FORM_ref_addr:
      case elfcpp::DW_FORM_ref1:
      case elfcpp::DW_FORM_ref2:
      case elfcpp::DW_FORM_ref4:
      case elfcpp::DW_FORM_ref8:
      case elfcpp::DW_FORM_ref_udata:
        *shndx = attr_val->aux.shndx;
        return attr_val->val.refval;
      case elfcpp::DW_FORM_ref_sig8:
        *shndx = attr_val->aux.shndx;
        return attr_val->val.uintval;
      case elfcpp::DW_FORM_data4:
      case elfcpp::DW_FORM_data8:
        *shndx = attr_val->aux.shndx;
        return attr_val->val.intval;
      default:
        return -1;
    }
}

off_t
Dwarf_die::address_attribute(unsigned int attr, unsigned int* shndx)
{
  const Attribute_value* attr_val = this->attribute(attr);
  if (attr_val == NULL || attr_val->form != elfcpp::DW_FORM_addr)
    return -1;

  *shndx = attr_val->aux.shndx;
  return attr_val->val.refval;
}

// Return the offset of this DIE's first child.

off_t
Dwarf_die::child_offset()
{
  gold_assert(this->abbrev_code_ != NULL);
  if (!this->has_children())
    return 0;
  if (this->child_offset_ == 0)
    this->child_offset_ = this->skip_attributes();
  return this->child_offset_;
}

// Return the offset of this DIE's next sibling.

off_t
Dwarf_die::sibling_offset()
{
  gold_assert(this->abbrev_code_ != NULL);

  if (this->sibling_offset_ != 0)
    return this->sibling_offset_;

  if (!this->has_children())
    {
      this->sibling_offset_ = this->skip_attributes();
      return this->sibling_offset_;
    }

  if (this->has_sibling_attribute())
    {
      if (!this->read_attributes())
	return 0;
      if (this->sibling_offset_ != 0)
	return this->sibling_offset_;
    }

  // Skip over the children.
  off_t child_offset = this->child_offset();
  while (child_offset > 0)
    {
      Dwarf_die die(this->dwinfo_, child_offset, this);
      // The Dwarf_die ctor will set this DIE's sibling offset
      // when it reads a zero abbrev code.
      if (die.tag() == 0)
	break;
      child_offset = die.sibling_offset();
    }

  // This should be set by now.  If not, there was a problem reading
  // the DWARF info, and we return 0.
  return this->sibling_offset_;
}

// class Dwarf_info_reader

// Check that the pointer P is within the current compilation unit.

inline bool
Dwarf_info_reader::check_buffer(const unsigned char* p) const
{
  if (p > this->buffer_ + this->cu_offset_ + this->cu_length_)
    {
      gold_warning(_("%s: corrupt debug info in %s"),
		   this->object_->name().c_str(),
		   this->object_->section_name(this->shndx_).c_str());
      return false;
    }
  return true;
}

// Begin parsing the debug info.  This calls visit_compilation_unit()
// or visit_type_unit() for each compilation or type unit found in the
// section, and visit_die() for each top-level DIE.

void
Dwarf_info_reader::parse()
{
  if (this->object_->is_big_endian())
    {
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
      this->do_parse<true>();
#else
      gold_unreachable();
#endif
    }
  else
    {
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
      this->do_parse<false>();
#else
      gold_unreachable();
#endif
    }
}

template<bool big_endian>
void
Dwarf_info_reader::do_parse()
{
  // Get the section contents and decompress if necessary.
  section_size_type buffer_size;
  bool buffer_is_new;
  this->buffer_ = this->object_->decompressed_section_contents(this->shndx_,
							       &buffer_size,
							       &buffer_is_new);
  if (this->buffer_ == NULL || buffer_size == 0)
    return;
  this->buffer_end_ = this->buffer_ + buffer_size;

  // The offset of this input section in the output section.
  off_t section_offset = this->object_->output_section_offset(this->shndx_);

  // Start tracking relocations for this section.
  this->reloc_mapper_ = make_elf_reloc_mapper(this->object_, this->symtab_,
					      this->symtab_size_);
  this->reloc_mapper_->initialize(this->reloc_shndx_, this->reloc_type_);

  // Loop over compilation units (or type units).
  unsigned int abbrev_shndx = this->abbrev_shndx_;
  off_t abbrev_offset = 0;
  const unsigned char* pinfo = this->buffer_;
  while (pinfo < this->buffer_end_)
    {
      // Read the compilation (or type) unit header.
      const unsigned char* cu_start = pinfo;
      this->cu_offset_ = cu_start - this->buffer_;
      this->cu_length_ = this->buffer_end_ - cu_start;

      // Read unit_length (4 or 12 bytes).
      if (!this->check_buffer(pinfo + 4))
	break;
      uint32_t unit_length =
          elfcpp::Swap_unaligned<32, big_endian>::readval(pinfo);
      pinfo += 4;
      if (unit_length == 0xffffffff)
	{
	  if (!this->check_buffer(pinfo + 8))
	    break;
	  unit_length = elfcpp::Swap_unaligned<64, big_endian>::readval(pinfo);
	  pinfo += 8;
	  this->offset_size_ = 8;
	}
      else
	this->offset_size_ = 4;
      if (!this->check_buffer(pinfo + unit_length))
	break;
      const unsigned char* cu_end = pinfo + unit_length;
      this->cu_length_ = cu_end - cu_start;
      if (!this->check_buffer(pinfo + 2 + this->offset_size_ + 1))
	break;

      // Read version (2 bytes).
      this->cu_version_ =
	  elfcpp::Swap_unaligned<16, big_endian>::readval(pinfo);
      pinfo += 2;

      // Read debug_abbrev_offset (4 or 8 bytes).
      if (this->offset_size_ == 4)
	abbrev_offset = elfcpp::Swap_unaligned<32, big_endian>::readval(pinfo);
      else
	abbrev_offset = elfcpp::Swap_unaligned<64, big_endian>::readval(pinfo);
      if (this->reloc_shndx_ > 0)
	{
	  off_t reloc_offset = pinfo - this->buffer_;
	  off_t value;
	  abbrev_shndx =
	      this->reloc_mapper_->get_reloc_target(reloc_offset, &value);
	  if (abbrev_shndx == 0)
	    return;
	  if (this->reloc_type_ == elfcpp::SHT_REL)
	    abbrev_offset += value;
	  else
	    abbrev_offset = value;
	}
      pinfo += this->offset_size_;

      // Read address_size (1 byte).
      this->address_size_ = *pinfo++;

      // For type units, read the two extra fields.
      uint64_t signature = 0;
      off_t type_offset = 0;
      if (this->is_type_unit_)
        {
	  if (!this->check_buffer(pinfo + 8 + this->offset_size_))
	    break;

	  // Read type_signature (8 bytes).
	  signature = elfcpp::Swap_unaligned<64, big_endian>::readval(pinfo);
	  pinfo += 8;

	  // Read type_offset (4 or 8 bytes).
	  if (this->offset_size_ == 4)
	    type_offset =
		elfcpp::Swap_unaligned<32, big_endian>::readval(pinfo);
	  else
	    type_offset =
		elfcpp::Swap_unaligned<64, big_endian>::readval(pinfo);
	  pinfo += this->offset_size_;
	}

      // Read the .debug_abbrev table.
      this->abbrev_table_.read_abbrevs(this->object_, abbrev_shndx,
				       abbrev_offset);

      // Visit the root DIE.
      Dwarf_die root_die(this,
			 pinfo - (this->buffer_ + this->cu_offset_),
			 NULL);
      if (root_die.tag() != 0)
	{
	  // Visit the CU or TU.
	  if (this->is_type_unit_)
	    this->visit_type_unit(section_offset + this->cu_offset_,
				  type_offset, signature, &root_die);
	  else
	    this->visit_compilation_unit(section_offset + this->cu_offset_,
					 cu_end - cu_start, &root_die);
	}

      // Advance to the next CU.
      pinfo = cu_end;
    }

  if (buffer_is_new)
    {
      delete[] this->buffer_;
      this->buffer_ = NULL;
    }
}

// Read the DWARF string table.

bool
Dwarf_info_reader::do_read_string_table(unsigned int string_shndx)
{
  Relobj* object = this->object_;

  // If we don't have relocations, string_shndx will be 0, and
  // we'll have to hunt for the .debug_str section.
  if (string_shndx == 0)
    {
      for (unsigned int i = 1; i < this->object_->shnum(); ++i)
	{
	  std::string name = object->section_name(i);
	  if (name == ".debug_str" || name == ".zdebug_str")
	    {
	      string_shndx = i;
	      this->string_output_section_offset_ =
		  object->output_section_offset(i);
	      break;
	    }
	}
      if (string_shndx == 0)
	return false;
    }

  if (this->owns_string_buffer_ && this->string_buffer_ != NULL)
    {
      delete[] this->string_buffer_;
      this->owns_string_buffer_ = false;
    }

  // Get the secton contents and decompress if necessary.
  section_size_type buffer_size;
  const unsigned char* buffer =
      object->decompressed_section_contents(string_shndx,
					    &buffer_size,
					    &this->owns_string_buffer_);
  this->string_buffer_ = reinterpret_cast<const char*>(buffer);
  this->string_buffer_end_ = this->string_buffer_ + buffer_size;
  this->string_shndx_ = string_shndx;
  return true;
}

// Read a possibly unaligned integer of SIZE.
template <int valsize>
inline typename elfcpp::Valtype_base<valsize>::Valtype
Dwarf_info_reader::read_from_pointer(const unsigned char* source)
{
  typename elfcpp::Valtype_base<valsize>::Valtype return_value;
  if (this->object_->is_big_endian())
    return_value = elfcpp::Swap_unaligned<valsize, true>::readval(source);
  else
    return_value = elfcpp::Swap_unaligned<valsize, false>::readval(source);
  return return_value;
}

// Read a possibly unaligned integer of SIZE.  Update SOURCE after read.
template <int valsize>
inline typename elfcpp::Valtype_base<valsize>::Valtype
Dwarf_info_reader::read_from_pointer(const unsigned char** source)
{
  typename elfcpp::Valtype_base<valsize>::Valtype return_value;
  if (this->object_->is_big_endian())
    return_value = elfcpp::Swap_unaligned<valsize, true>::readval(*source);
  else
    return_value = elfcpp::Swap_unaligned<valsize, false>::readval(*source);
  *source += valsize / 8;
  return return_value;
}

// Look for a relocation at offset ATTR_OFF in the dwarf info,
// and return the section index and offset of the target.

unsigned int
Dwarf_info_reader::lookup_reloc(off_t attr_off, off_t* target_off)
{
  off_t value;
  attr_off += this->cu_offset_;
  unsigned int shndx = this->reloc_mapper_->get_reloc_target(attr_off, &value);
  if (shndx == 0)
    return 0;
  if (this->reloc_type_ == elfcpp::SHT_REL)
    *target_off += value;
  else
    *target_off = value;
  return shndx;
}

// Return a string from the DWARF string table.

const char*
Dwarf_info_reader::get_string(off_t str_off, unsigned int string_shndx)
{
  if (!this->read_string_table(string_shndx))
    return NULL;

  // Correct the offset.  For incremental update links, we have a
  // relocated offset that is relative to the output section, but
  // here we need an offset relative to the input section.
  str_off -= this->string_output_section_offset_;

  const char* p = this->string_buffer_ + str_off;

  if (p < this->string_buffer_ || p >= this->string_buffer_end_)
    return NULL;

  return p;
}

// The following are default, do-nothing, implementations of the
// hook methods normally provided by a derived class.  We provide
// default implementations rather than no implementation so that
// a derived class needs to implement only the hooks that it needs
// to use.

// Process a compilation unit and parse its child DIE.

void
Dwarf_info_reader::visit_compilation_unit(off_t, off_t, Dwarf_die*)
{
}

// Process a type unit and parse its child DIE.

void
Dwarf_info_reader::visit_type_unit(off_t, off_t, uint64_t, Dwarf_die*)
{
}

// class Sized_dwarf_line_info

struct LineStateMachine
{
  int file_num;
  uint64_t address;
  int line_num;
  int column_num;
  unsigned int shndx;    // the section address refers to
  bool is_stmt;          // stmt means statement.
  bool basic_block;
  bool end_sequence;
};

static void
ResetLineStateMachine(struct LineStateMachine* lsm, bool default_is_stmt)
{
  lsm->file_num = 1;
  lsm->address = 0;
  lsm->line_num = 1;
  lsm->column_num = 0;
  lsm->shndx = -1U;
  lsm->is_stmt = default_is_stmt;
  lsm->basic_block = false;
  lsm->end_sequence = false;
}

template<int size, bool big_endian>
Sized_dwarf_line_info<size, big_endian>::Sized_dwarf_line_info(
    Object* object,
    unsigned int read_shndx)
  : data_valid_(false), buffer_(NULL), buffer_start_(NULL),
    reloc_mapper_(NULL), symtab_buffer_(NULL), directories_(), files_(),
    current_header_index_(-1)
{
  unsigned int debug_shndx;

  for (debug_shndx = 1; debug_shndx < object->shnum(); ++debug_shndx)
    {
      // FIXME: do this more efficiently: section_name() isn't super-fast
      std::string name = object->section_name(debug_shndx);
      if (name == ".debug_line" || name == ".zdebug_line")
	{
	  section_size_type buffer_size;
	  bool is_new = false;
	  this->buffer_ = object->decompressed_section_contents(debug_shndx,
								&buffer_size,
								&is_new);
	  if (is_new)
	    this->buffer_start_ = this->buffer_;
	  this->buffer_end_ = this->buffer_ + buffer_size;
	  break;
	}
    }
  if (this->buffer_ == NULL)
    return;

  // Find the relocation section for ".debug_line".
  // We expect these for relobjs (.o's) but not dynobjs (.so's).
  unsigned int reloc_shndx = 0;
  for (unsigned int i = 0; i < object->shnum(); ++i)
    {
      unsigned int reloc_sh_type = object->section_type(i);
      if ((reloc_sh_type == elfcpp::SHT_REL
	   || reloc_sh_type == elfcpp::SHT_RELA)
	  && object->section_info(i) == debug_shndx)
	{
	  reloc_shndx = i;
	  this->track_relocs_type_ = reloc_sh_type;
	  break;
	}
    }

  // Finally, we need the symtab section to interpret the relocs.
  if (reloc_shndx != 0)
    {
      unsigned int symtab_shndx;
      for (symtab_shndx = 0; symtab_shndx < object->shnum(); ++symtab_shndx)
        if (object->section_type(symtab_shndx) == elfcpp::SHT_SYMTAB)
          {
	    this->symtab_buffer_ = object->section_contents(
		symtab_shndx, &this->symtab_buffer_size_, false);
            break;
          }
      if (this->symtab_buffer_ == NULL)
        return;
    }

  this->reloc_mapper_ =
      new Sized_elf_reloc_mapper<size, big_endian>(object,
						   this->symtab_buffer_,
						   this->symtab_buffer_size_);
  if (!this->reloc_mapper_->initialize(reloc_shndx, this->track_relocs_type_))
    return;

  // Now that we have successfully read all the data, parse the debug
  // info.
  this->data_valid_ = true;
  this->read_line_mappings(read_shndx);
}

// Read the DWARF header.

template<int size, bool big_endian>
const unsigned char*
Sized_dwarf_line_info<size, big_endian>::read_header_prolog(
    const unsigned char* lineptr)
{
  uint32_t initial_length = elfcpp::Swap_unaligned<32, big_endian>::readval(lineptr);
  lineptr += 4;

  // In DWARF2/3, if the initial length is all 1 bits, then the offset
  // size is 8 and we need to read the next 8 bytes for the real length.
  if (initial_length == 0xffffffff)
    {
      header_.offset_size = 8;
      initial_length = elfcpp::Swap_unaligned<64, big_endian>::readval(lineptr);
      lineptr += 8;
    }
  else
    header_.offset_size = 4;

  header_.total_length = initial_length;

  gold_assert(lineptr + header_.total_length <= buffer_end_);

  header_.version = elfcpp::Swap_unaligned<16, big_endian>::readval(lineptr);
  lineptr += 2;

  if (header_.offset_size == 4)
    header_.prologue_length = elfcpp::Swap_unaligned<32, big_endian>::readval(lineptr);
  else
    header_.prologue_length = elfcpp::Swap_unaligned<64, big_endian>::readval(lineptr);
  lineptr += header_.offset_size;

  header_.min_insn_length = *lineptr;
  lineptr += 1;

  header_.default_is_stmt = *lineptr;
  lineptr += 1;

  header_.line_base = *reinterpret_cast<const signed char*>(lineptr);
  lineptr += 1;

  header_.line_range = *lineptr;
  lineptr += 1;

  header_.opcode_base = *lineptr;
  lineptr += 1;

  header_.std_opcode_lengths.resize(header_.opcode_base + 1);
  header_.std_opcode_lengths[0] = 0;
  for (int i = 1; i < header_.opcode_base; i++)
    {
      header_.std_opcode_lengths[i] = *lineptr;
      lineptr += 1;
    }

  return lineptr;
}

// The header for a debug_line section is mildly complicated, because
// the line info is very tightly encoded.

template<int size, bool big_endian>
const unsigned char*
Sized_dwarf_line_info<size, big_endian>::read_header_tables(
    const unsigned char* lineptr)
{
  ++this->current_header_index_;

  // Create a new directories_ entry and a new files_ entry for our new
  // header.  We initialize each with a single empty element, because
  // dwarf indexes directory and filenames starting at 1.
  gold_assert(static_cast<int>(this->directories_.size())
	      == this->current_header_index_);
  gold_assert(static_cast<int>(this->files_.size())
	      == this->current_header_index_);
  this->directories_.push_back(std::vector<std::string>(1));
  this->files_.push_back(std::vector<std::pair<int, std::string> >(1));

  // It is legal for the directory entry table to be empty.
  if (*lineptr)
    {
      int dirindex = 1;
      while (*lineptr)
        {
	  const char* dirname = reinterpret_cast<const char*>(lineptr);
          gold_assert(dirindex
		      == static_cast<int>(this->directories_.back().size()));
          this->directories_.back().push_back(dirname);
          lineptr += this->directories_.back().back().size() + 1;
          dirindex++;
        }
    }
  lineptr++;

  // It is also legal for the file entry table to be empty.
  if (*lineptr)
    {
      int fileindex = 1;
      size_t len;
      while (*lineptr)
        {
          const char* filename = reinterpret_cast<const char*>(lineptr);
          lineptr += strlen(filename) + 1;

          uint64_t dirindex = read_unsigned_LEB_128(lineptr, &len);
          lineptr += len;

          if (dirindex >= this->directories_.back().size())
            dirindex = 0;
	  int dirindexi = static_cast<int>(dirindex);

          read_unsigned_LEB_128(lineptr, &len);   // mod_time
          lineptr += len;

          read_unsigned_LEB_128(lineptr, &len);   // filelength
          lineptr += len;

          gold_assert(fileindex
		      == static_cast<int>(this->files_.back().size()));
          this->files_.back().push_back(std::make_pair(dirindexi, filename));
          fileindex++;
        }
    }
  lineptr++;

  return lineptr;
}

// Process a single opcode in the .debug.line structure.

template<int size, bool big_endian>
bool
Sized_dwarf_line_info<size, big_endian>::process_one_opcode(
    const unsigned char* start, struct LineStateMachine* lsm, size_t* len)
{
  size_t oplen = 0;
  size_t templen;
  unsigned char opcode = *start;
  oplen++;
  start++;

  // If the opcode is great than the opcode_base, it is a special
  // opcode. Most line programs consist mainly of special opcodes.
  if (opcode >= header_.opcode_base)
    {
      opcode -= header_.opcode_base;
      const int advance_address = ((opcode / header_.line_range)
                                   * header_.min_insn_length);
      lsm->address += advance_address;

      const int advance_line = ((opcode % header_.line_range)
                                + header_.line_base);
      lsm->line_num += advance_line;
      lsm->basic_block = true;
      *len = oplen;
      return true;
    }

  // Otherwise, we have the regular opcodes
  switch (opcode)
    {
    case elfcpp::DW_LNS_copy:
      lsm->basic_block = false;
      *len = oplen;
      return true;

    case elfcpp::DW_LNS_advance_pc:
      {
        const uint64_t advance_address
            = read_unsigned_LEB_128(start, &templen);
        oplen += templen;
        lsm->address += header_.min_insn_length * advance_address;
      }
      break;

    case elfcpp::DW_LNS_advance_line:
      {
        const uint64_t advance_line = read_signed_LEB_128(start, &templen);
        oplen += templen;
        lsm->line_num += advance_line;
      }
      break;

    case elfcpp::DW_LNS_set_file:
      {
        const uint64_t fileno = read_unsigned_LEB_128(start, &templen);
        oplen += templen;
        lsm->file_num = fileno;
      }
      break;

    case elfcpp::DW_LNS_set_column:
      {
        const uint64_t colno = read_unsigned_LEB_128(start, &templen);
        oplen += templen;
        lsm->column_num = colno;
      }
      break;

    case elfcpp::DW_LNS_negate_stmt:
      lsm->is_stmt = !lsm->is_stmt;
      break;

    case elfcpp::DW_LNS_set_basic_block:
      lsm->basic_block = true;
      break;

    case elfcpp::DW_LNS_fixed_advance_pc:
      {
        int advance_address;
        advance_address = elfcpp::Swap_unaligned<16, big_endian>::readval(start);
        oplen += 2;
        lsm->address += advance_address;
      }
      break;

    case elfcpp::DW_LNS_const_add_pc:
      {
        const int advance_address = (header_.min_insn_length
                                     * ((255 - header_.opcode_base)
                                        / header_.line_range));
        lsm->address += advance_address;
      }
      break;

    case elfcpp::DW_LNS_extended_op:
      {
        const uint64_t extended_op_len
            = read_unsigned_LEB_128(start, &templen);
        start += templen;
        oplen += templen + extended_op_len;

        const unsigned char extended_op = *start;
        start++;

        switch (extended_op)
          {
          case elfcpp::DW_LNE_end_sequence:
            // This means that the current byte is the one immediately
            // after a set of instructions.  Record the current line
            // for up to one less than the current address.
            lsm->line_num = -1;
            lsm->end_sequence = true;
            *len = oplen;
            return true;

          case elfcpp::DW_LNE_set_address:
            {
              lsm->address =
		elfcpp::Swap_unaligned<size, big_endian>::readval(start);
              typename Reloc_map::const_iterator it
                  = this->reloc_map_.find(start - this->buffer_);
              if (it != reloc_map_.end())
                {
		  // If this is a SHT_RELA section, then ignore the
		  // section contents.  This assumes that this is a
		  // straight reloc which just uses the reloc addend.
		  // The reloc addend has already been included in the
		  // symbol value.
		  if (this->track_relocs_type_ == elfcpp::SHT_RELA)
		    lsm->address = 0;
		  // Add in the symbol value.
		  lsm->address += it->second.second;
                  lsm->shndx = it->second.first;
                }
              else
                {
                  // If we're a normal .o file, with relocs, every
                  // set_address should have an associated relocation.
		  if (this->input_is_relobj())
                    this->data_valid_ = false;
                }
              break;
            }
          case elfcpp::DW_LNE_define_file:
            {
              const char* filename  = reinterpret_cast<const char*>(start);
              templen = strlen(filename) + 1;
              start += templen;

              uint64_t dirindex = read_unsigned_LEB_128(start, &templen);

              if (dirindex >= this->directories_.back().size())
                dirindex = 0;
	      int dirindexi = static_cast<int>(dirindex);

              // This opcode takes two additional ULEB128 parameters
              // (mod_time and filelength), but we don't use those
              // values.  Because OPLEN already tells us how far to
              // skip to the next opcode, we don't need to read
              // them at all.

              this->files_.back().push_back(std::make_pair(dirindexi,
							   filename));
            }
            break;
          }
      }
      break;

    default:
      {
        // Ignore unknown opcode  silently
        for (int i = 0; i < header_.std_opcode_lengths[opcode]; i++)
          {
            size_t templen;
            read_unsigned_LEB_128(start, &templen);
            start += templen;
            oplen += templen;
          }
      }
      break;
  }
  *len = oplen;
  return false;
}

// Read the debug information at LINEPTR and store it in the line
// number map.

template<int size, bool big_endian>
unsigned const char*
Sized_dwarf_line_info<size, big_endian>::read_lines(unsigned const char* lineptr,
                                                    unsigned int shndx)
{
  struct LineStateMachine lsm;

  // LENGTHSTART is the place the length field is based on.  It is the
  // point in the header after the initial length field.
  const unsigned char* lengthstart = buffer_;

  // In 64 bit dwarf, the initial length is 12 bytes, because of the
  // 0xffffffff at the start.
  if (header_.offset_size == 8)
    lengthstart += 12;
  else
    lengthstart += 4;

  while (lineptr < lengthstart + header_.total_length)
    {
      ResetLineStateMachine(&lsm, header_.default_is_stmt);
      while (!lsm.end_sequence)
        {
          size_t oplength;
          bool add_line = this->process_one_opcode(lineptr, &lsm, &oplength);
          if (add_line
              && (shndx == -1U || lsm.shndx == -1U || shndx == lsm.shndx))
            {
              Offset_to_lineno_entry entry
                  = { static_cast<off_t>(lsm.address),
		      this->current_header_index_,
		      static_cast<unsigned int>(lsm.file_num),
		      true, lsm.line_num };
	      std::vector<Offset_to_lineno_entry>&
		map(this->line_number_map_[lsm.shndx]);
	      // If we see two consecutive entries with the same
	      // offset and a real line number, then mark the first
	      // one as non-canonical.
	      if (!map.empty()
		  && (map.back().offset == static_cast<off_t>(lsm.address))
		  && lsm.line_num != -1
		  && map.back().line_num != -1)
		map.back().last_line_for_offset = false;
	      map.push_back(entry);
            }
          lineptr += oplength;
        }
    }

  return lengthstart + header_.total_length;
}

// Read the relocations into a Reloc_map.

template<int size, bool big_endian>
void
Sized_dwarf_line_info<size, big_endian>::read_relocs()
{
  if (this->symtab_buffer_ == NULL)
    return;

  off_t value;
  off_t reloc_offset;
  while ((reloc_offset = this->reloc_mapper_->next_offset()) != -1)
    {
      const unsigned int shndx =
          this->reloc_mapper_->get_reloc_target(reloc_offset, &value);

      // There is no reason to record non-ordinary section indexes, or
      // SHN_UNDEF, because they will never match the real section.
      if (shndx != 0)
	this->reloc_map_[reloc_offset] = std::make_pair(shndx, value);

      this->reloc_mapper_->advance(reloc_offset + 1);
    }
}

// Read the line number info.

template<int size, bool big_endian>
void
Sized_dwarf_line_info<size, big_endian>::read_line_mappings(unsigned int shndx)
{
  gold_assert(this->data_valid_ == true);

  this->read_relocs();
  while (this->buffer_ < this->buffer_end_)
    {
      const unsigned char* lineptr = this->buffer_;
      lineptr = this->read_header_prolog(lineptr);
      lineptr = this->read_header_tables(lineptr);
      lineptr = this->read_lines(lineptr, shndx);
      this->buffer_ = lineptr;
    }

  // Sort the lines numbers, so addr2line can use binary search.
  for (typename Lineno_map::iterator it = line_number_map_.begin();
       it != line_number_map_.end();
       ++it)
    // Each vector needs to be sorted by offset.
    std::sort(it->second.begin(), it->second.end());
}

// Some processing depends on whether the input is a .o file or not.
// For instance, .o files have relocs, and have .debug_lines
// information on a per section basis.  .so files, on the other hand,
// lack relocs, and offsets are unique, so we can ignore the section
// information.

template<int size, bool big_endian>
bool
Sized_dwarf_line_info<size, big_endian>::input_is_relobj()
{
  // Only .o files have relocs and the symtab buffer that goes with them.
  return this->symtab_buffer_ != NULL;
}

// Given an Offset_to_lineno_entry vector, and an offset, figure out
// if the offset points into a function according to the vector (see
// comments below for the algorithm).  If it does, return an iterator
// into the vector that points to the line-number that contains that
// offset.  If not, it returns vector::end().

static std::vector<Offset_to_lineno_entry>::const_iterator
offset_to_iterator(const std::vector<Offset_to_lineno_entry>* offsets,
                   off_t offset)
{
  const Offset_to_lineno_entry lookup_key = { offset, 0, 0, true, 0 };

  // lower_bound() returns the smallest offset which is >= lookup_key.
  // If no offset in offsets is >= lookup_key, returns end().
  std::vector<Offset_to_lineno_entry>::const_iterator it
      = std::lower_bound(offsets->begin(), offsets->end(), lookup_key);

  // This code is easiest to understand with a concrete example.
  // Here's a possible offsets array:
  // {{offset = 3211, header_num = 0, file_num = 1, last, line_num = 16},  // 0
  //  {offset = 3224, header_num = 0, file_num = 1, last, line_num = 20},  // 1
  //  {offset = 3226, header_num = 0, file_num = 1, last, line_num = 22},  // 2
  //  {offset = 3231, header_num = 0, file_num = 1, last, line_num = 25},  // 3
  //  {offset = 3232, header_num = 0, file_num = 1, last, line_num = -1},  // 4
  //  {offset = 3232, header_num = 0, file_num = 1, last, line_num = 65},  // 5
  //  {offset = 3235, header_num = 0, file_num = 1, last, line_num = 66},  // 6
  //  {offset = 3236, header_num = 0, file_num = 1, last, line_num = -1},  // 7
  //  {offset = 5764, header_num = 0, file_num = 1, last, line_num = 48},  // 8
  //  {offset = 5764, header_num = 0, file_num = 1,!last, line_num = 47},  // 9
  //  {offset = 5765, header_num = 0, file_num = 1, last, line_num = 49},  // 10
  //  {offset = 5767, header_num = 0, file_num = 1, last, line_num = 50},  // 11
  //  {offset = 5768, header_num = 0, file_num = 1, last, line_num = 51},  // 12
  //  {offset = 5773, header_num = 0, file_num = 1, last, line_num = -1},  // 13
  //  {offset = 5787, header_num = 1, file_num = 1, last, line_num = 19},  // 14
  //  {offset = 5790, header_num = 1, file_num = 1, last, line_num = 20},  // 15
  //  {offset = 5793, header_num = 1, file_num = 1, last, line_num = 67},  // 16
  //  {offset = 5793, header_num = 1, file_num = 1, last, line_num = -1},  // 17
  //  {offset = 5793, header_num = 1, file_num = 1,!last, line_num = 66},  // 18
  //  {offset = 5795, header_num = 1, file_num = 1, last, line_num = 68},  // 19
  //  {offset = 5798, header_num = 1, file_num = 1, last, line_num = -1},  // 20
  // The entries with line_num == -1 mark the end of a function: the
  // associated offset is one past the last instruction in the
  // function.  This can correspond to the beginning of the next
  // function (as is true for offset 3232); alternately, there can be
  // a gap between the end of one function and the start of the next
  // (as is true for some others, most obviously from 3236->5764).
  //
  // Case 1: lookup_key has offset == 10.  lower_bound returns
  //         offsets[0].  Since it's not an exact match and we're
  //         at the beginning of offsets, we return end() (invalid).
  // Case 2: lookup_key has offset 10000.  lower_bound returns
  //         offset[21] (end()).  We return end() (invalid).
  // Case 3: lookup_key has offset == 3211.  lower_bound matches
  //         offsets[0] exactly, and that's the entry we return.
  // Case 4: lookup_key has offset == 3232.  lower_bound returns
  //         offsets[4].  That's an exact match, but indicates
  //         end-of-function.  We check if offsets[5] is also an
  //         exact match but not end-of-function.  It is, so we
  //         return offsets[5].
  // Case 5: lookup_key has offset == 3214.  lower_bound returns
  //         offsets[1].  Since it's not an exact match, we back
  //         up to the offset that's < lookup_key, offsets[0].
  //         We note offsets[0] is a valid entry (not end-of-function),
  //         so that's the entry we return.
  // Case 6: lookup_key has offset == 4000.  lower_bound returns
  //         offsets[8].  Since it's not an exact match, we back
  //         up to offsets[7].  Since offsets[7] indicates
  //         end-of-function, we know lookup_key is between
  //         functions, so we return end() (not a valid offset).
  // Case 7: lookup_key has offset == 5794.  lower_bound returns
  //         offsets[19].  Since it's not an exact match, we back
  //         up to offsets[16].  Note we back up to the *first*
  //         entry with offset 5793, not just offsets[19-1].
  //         We note offsets[16] is a valid entry, so we return it.
  //         If offsets[16] had had line_num == -1, we would have
  //         checked offsets[17].  The reason for this is that
  //         16 and 17 can be in an arbitrary order, since we sort
  //         only by offset and last_line_for_offset.  (Note it
  //         doesn't help to use line_number as a tertiary sort key,
  //         since sometimes we want the -1 to be first and sometimes
  //         we want it to be last.)

  // This deals with cases (1) and (2).
  if ((it == offsets->begin() && offset < it->offset)
      || it == offsets->end())
    return offsets->end();

  // This deals with cases (3) and (4).
  if (offset == it->offset)
    {
      while (it != offsets->end()
             && it->offset == offset
             && it->line_num == -1)
        ++it;
      if (it == offsets->end() || it->offset != offset)
        return offsets->end();
      else
        return it;
    }

  // This handles the first part of case (7) -- we back up to the
  // *first* entry that has the offset that's behind us.
  gold_assert(it != offsets->begin());
  std::vector<Offset_to_lineno_entry>::const_iterator range_end = it;
  --it;
  const off_t range_value = it->offset;
  while (it != offsets->begin() && (it-1)->offset == range_value)
    --it;

  // This handles cases (5), (6), and (7): if any entry in the
  // equal_range [it, range_end) has a line_num != -1, it's a valid
  // match.  If not, we're not in a function.  The line number we saw
  // last for an offset will be sorted first, so it'll get returned if
  // it's present.
  for (; it != range_end; ++it)
    if (it->line_num != -1)
      return it;
  return offsets->end();
}

// Returns the canonical filename:lineno for the address passed in.
// If other_lines is not NULL, appends the non-canonical lines
// assigned to the same address.

template<int size, bool big_endian>
std::string
Sized_dwarf_line_info<size, big_endian>::do_addr2line(
    unsigned int shndx,
    off_t offset,
    std::vector<std::string>* other_lines)
{
  if (this->data_valid_ == false)
    return "";

  const std::vector<Offset_to_lineno_entry>* offsets;
  // If we do not have reloc information, then our input is a .so or
  // some similar data structure where all the information is held in
  // the offset.  In that case, we ignore the input shndx.
  if (this->input_is_relobj())
    offsets = &this->line_number_map_[shndx];
  else
    offsets = &this->line_number_map_[-1U];
  if (offsets->empty())
    return "";

  typename std::vector<Offset_to_lineno_entry>::const_iterator it
      = offset_to_iterator(offsets, offset);
  if (it == offsets->end())
    return "";

  std::string result = this->format_file_lineno(*it);
  if (other_lines != NULL)
    for (++it; it != offsets->end() && it->offset == offset; ++it)
      {
        if (it->line_num == -1)
          continue;  // The end of a previous function.
        other_lines->push_back(this->format_file_lineno(*it));
      }
  return result;
}

// Convert the file_num + line_num into a string.

template<int size, bool big_endian>
std::string
Sized_dwarf_line_info<size, big_endian>::format_file_lineno(
    const Offset_to_lineno_entry& loc) const
{
  std::string ret;

  gold_assert(loc.header_num < static_cast<int>(this->files_.size()));
  gold_assert(loc.file_num
	      < static_cast<unsigned int>(this->files_[loc.header_num].size()));
  const std::pair<int, std::string>& filename_pair
      = this->files_[loc.header_num][loc.file_num];
  const std::string& filename = filename_pair.second;

  gold_assert(loc.header_num < static_cast<int>(this->directories_.size()));
  gold_assert(filename_pair.first
              < static_cast<int>(this->directories_[loc.header_num].size()));
  const std::string& dirname
      = this->directories_[loc.header_num][filename_pair.first];

  if (!dirname.empty())
    {
      ret += dirname;
      ret += "/";
    }
  ret += filename;
  if (ret.empty())
    ret = "(unknown)";

  char buffer[64];   // enough to hold a line number
  snprintf(buffer, sizeof(buffer), "%d", loc.line_num);
  ret += ":";
  ret += buffer;

  return ret;
}

// Dwarf_line_info routines.

static unsigned int next_generation_count = 0;

struct Addr2line_cache_entry
{
  Object* object;
  unsigned int shndx;
  Dwarf_line_info* dwarf_line_info;
  unsigned int generation_count;
  unsigned int access_count;

  Addr2line_cache_entry(Object* o, unsigned int s, Dwarf_line_info* d)
      : object(o), shndx(s), dwarf_line_info(d),
        generation_count(next_generation_count), access_count(0)
  {
    if (next_generation_count < (1U << 31))
      ++next_generation_count;
  }
};
// We expect this cache to be small, so don't bother with a hashtable
// or priority queue or anything: just use a simple vector.
static std::vector<Addr2line_cache_entry> addr2line_cache;

std::string
Dwarf_line_info::one_addr2line(Object* object,
                               unsigned int shndx, off_t offset,
                               size_t cache_size,
                               std::vector<std::string>* other_lines)
{
  Dwarf_line_info* lineinfo = NULL;
  std::vector<Addr2line_cache_entry>::iterator it;

  // First, check the cache.  If we hit, update the counts.
  for (it = addr2line_cache.begin(); it != addr2line_cache.end(); ++it)
    {
      if (it->object == object && it->shndx == shndx)
        {
          lineinfo = it->dwarf_line_info;
          it->generation_count = next_generation_count;
          // We cap generation_count at 2^31 -1 to avoid overflow.
          if (next_generation_count < (1U << 31))
            ++next_generation_count;
          // We cap access_count at 31 so 2^access_count doesn't overflow
          if (it->access_count < 31)
            ++it->access_count;
          break;
        }
    }

  // If we don't hit the cache, create a new object and insert into the
  // cache.
  if (lineinfo == NULL)
  {
    switch (parameters->size_and_endianness())
      {
#ifdef HAVE_TARGET_32_LITTLE
        case Parameters::TARGET_32_LITTLE:
          lineinfo = new Sized_dwarf_line_info<32, false>(object, shndx); break;
#endif
#ifdef HAVE_TARGET_32_BIG
        case Parameters::TARGET_32_BIG:
          lineinfo = new Sized_dwarf_line_info<32, true>(object, shndx); break;
#endif
#ifdef HAVE_TARGET_64_LITTLE
        case Parameters::TARGET_64_LITTLE:
          lineinfo = new Sized_dwarf_line_info<64, false>(object, shndx); break;
#endif
#ifdef HAVE_TARGET_64_BIG
        case Parameters::TARGET_64_BIG:
          lineinfo = new Sized_dwarf_line_info<64, true>(object, shndx); break;
#endif
        default:
          gold_unreachable();
      }
    addr2line_cache.push_back(Addr2line_cache_entry(object, shndx, lineinfo));
  }

  // Now that we have our object, figure out the answer
  std::string retval = lineinfo->addr2line(shndx, offset, other_lines);

  // Finally, if our cache has grown too big, delete old objects.  We
  // assume the common (probably only) case is deleting only one object.
  // We use a pretty simple scheme to evict: function of LRU and MFU.
  while (addr2line_cache.size() > cache_size)
    {
      unsigned int lowest_score = ~0U;
      std::vector<Addr2line_cache_entry>::iterator lowest
          = addr2line_cache.end();
      for (it = addr2line_cache.begin(); it != addr2line_cache.end(); ++it)
        {
          const unsigned int score = (it->generation_count
                                      + (1U << it->access_count));
          if (score < lowest_score)
            {
              lowest_score = score;
              lowest = it;
            }
        }
      if (lowest != addr2line_cache.end())
        {
          delete lowest->dwarf_line_info;
          addr2line_cache.erase(lowest);
        }
    }

  return retval;
}

void
Dwarf_line_info::clear_addr2line_cache()
{
  for (std::vector<Addr2line_cache_entry>::iterator it = addr2line_cache.begin();
       it != addr2line_cache.end();
       ++it)
    delete it->dwarf_line_info;
  addr2line_cache.clear();
}

#ifdef HAVE_TARGET_32_LITTLE
template
class Sized_dwarf_line_info<32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Sized_dwarf_line_info<32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Sized_dwarf_line_info<64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Sized_dwarf_line_info<64, true>;
#endif

} // End namespace gold.
