// 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 <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(static_cast<off_t>((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")
	    {
	      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")
	    {
	      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);
  this->reloc_type_ = 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->lookup_reloc(offset, &start);
	  shndx2 = this->lookup_reloc(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;
}

// Look for a relocation at offset OFF in the range table,
// and return the section index and offset of the target.

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

// class Dwarf_pubnames_table

// Read the pubnames section from the object file.

bool
Dwarf_pubnames_table::read_section(Relobj* object, const unsigned char* symtab,
                                   off_t symtab_size)
{
  section_size_type buffer_size;
  unsigned int shndx = 0;

  // Find the .debug_pubnames/pubtypes section.
  const char* name = (this->is_pubtypes_
                      ? ".debug_pubtypes"
                      : ".debug_pubnames");
  for (unsigned int i = 1; i < object->shnum(); ++i)
    {
      if (object->section_name(i) == name)
        {
          shndx = i;
          this->output_section_offset_ = object->output_section_offset(i);
          break;
        }
    }
  if (shndx == 0)
    return false;


  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;

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

  // Find the relocation section
  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) == shndx)
	{
	  reloc_shndx = i;
	  break;
	}
    }

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

  return true;
}

// Read the header for the set at OFFSET.

bool
Dwarf_pubnames_table::read_header(off_t offset)
{
  // Make sure we have actually read the section.
  gold_assert(this->buffer_ != 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_;

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

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

  // Read the unit_length field.
  uint64_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);
      this->unit_length_ = unit_length + 12;
      pinfo += 8;
      this->offset_size_ = 8;
    }
  else
    {
      this->unit_length_ = unit_length + 4;
      this->offset_size_ = 4;
    }

  // Check the version.
  unsigned int version = this->dwinfo_->read_from_pointer<16>(pinfo);
  pinfo += 2;
  if (version != 2)
    return false;

  this->reloc_mapper_->get_reloc_target(pinfo - this->buffer_,
                                        &this->cu_offset_);

  // 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()
{
  const unsigned char* pinfo = this->pinfo_;

  // Read the offset within the CU.  If this is zero, we have reached
  // the end of the list.
  uint32_t offset;
  if (this->offset_size_ == 4)
    offset = this->dwinfo_->read_from_pointer<32>(&pinfo);
  else
    offset = this->dwinfo_->read_from_pointer<64>(&pinfo);
  if (offset == 0)
    return NULL;

  // 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_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:
	  case elfcpp::DW_FORM_GNU_addr_index:
	  case elfcpp::DW_FORM_GNU_str_index:
	    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()
{
  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_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:
	  case elfcpp::DW_FORM_GNU_addr_index:
	  case elfcpp::DW_FORM_GNU_str_index:
	    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_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_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

// 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")
	    {
	      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*)
{
}

// Print a warning about a corrupt debug section.

void
Dwarf_info_reader::warn_corrupt_debug_section() const
{
  gold_warning(_("%s: corrupt debug info in %s"),
	       this->object_->name().c_str(),
	       this->object_->section_name(this->shndx_).c_str());
}

// 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.
