/* DWARF 2 abbreviations

   Copyright (C) 1994-2020 Free Software Foundation, Inc.

   Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
   Inc.  with support from Florida State University (under contract
   with the Ada Joint Program Office), and Silicon Graphics, Inc.
   Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
   based on Fred Fish's (Cygnus Support) implementation of DWARF 1
   support.

   This file is part of GDB.

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

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

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

#include "defs.h"
#include "dwarf2/read.h"
#include "dwarf2/abbrev.h"
#include "dwarf2/leb.h"
#include "bfd.h"

/* Hash function for an abbrev.  */

static hashval_t
hash_abbrev (const void *item)
{
  const struct abbrev_info *info = (const struct abbrev_info *) item;
  /* Warning: if you change this next line, you must also update the
     other code in this class using the _with_hash functions.  */
  return info->number;
}

/* Comparison function for abbrevs.  */

static int
eq_abbrev (const void *lhs, const void *rhs)
{
  const struct abbrev_info *l_info = (const struct abbrev_info *) lhs;
  const struct abbrev_info *r_info = (const struct abbrev_info *) rhs;
  return l_info->number == r_info->number;
}

/* Abbreviation tables.

   In DWARF version 2, the description of the debugging information is
   stored in a separate .debug_abbrev section.  Before we read any
   dies from a section we read in all abbreviations and install them
   in a hash table.  */

abbrev_table::abbrev_table (sect_offset off)
  : sect_off (off),
    m_abbrevs (htab_create_alloc (20, hash_abbrev, eq_abbrev,
				  nullptr, xcalloc, xfree))
{
}

/* Allocate space for a struct abbrev_info object in ABBREV_TABLE.  */

struct abbrev_info *
abbrev_table::alloc_abbrev ()
{
  struct abbrev_info *abbrev;

  abbrev = XOBNEW (&m_abbrev_obstack, struct abbrev_info);
  memset (abbrev, 0, sizeof (struct abbrev_info));

  return abbrev;
}

/* Add an abbreviation to the table.  */

void
abbrev_table::add_abbrev (struct abbrev_info *abbrev)
{
  void **slot = htab_find_slot_with_hash (m_abbrevs.get (), abbrev,
					  abbrev->number, INSERT);
  *slot = abbrev;
}

/* Read in an abbrev table.  */

abbrev_table_up
abbrev_table::read (struct objfile *objfile,
		    struct dwarf2_section_info *section,
		    sect_offset sect_off)
{
  bfd *abfd = section->get_bfd_owner ();
  const gdb_byte *abbrev_ptr;
  struct abbrev_info *cur_abbrev;
  unsigned int abbrev_number, bytes_read, abbrev_name;
  unsigned int abbrev_form;
  std::vector<struct attr_abbrev> cur_attrs;

  abbrev_table_up abbrev_table (new struct abbrev_table (sect_off));

  section->read (objfile);
  abbrev_ptr = section->buffer + to_underlying (sect_off);
  abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
  abbrev_ptr += bytes_read;

  /* Loop until we reach an abbrev number of 0.  */
  while (abbrev_number)
    {
      cur_attrs.clear ();
      cur_abbrev = abbrev_table->alloc_abbrev ();

      /* read in abbrev header */
      cur_abbrev->number = abbrev_number;
      cur_abbrev->tag
	= (enum dwarf_tag) read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
      abbrev_ptr += bytes_read;
      cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr);
      abbrev_ptr += 1;

      /* now read in declarations */
      for (;;)
	{
	  LONGEST implicit_const;

	  abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
	  abbrev_ptr += bytes_read;
	  abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
	  abbrev_ptr += bytes_read;
	  if (abbrev_form == DW_FORM_implicit_const)
	    {
	      implicit_const = read_signed_leb128 (abfd, abbrev_ptr,
						   &bytes_read);
	      abbrev_ptr += bytes_read;
	    }
	  else
	    {
	      /* Initialize it due to a false compiler warning.  */
	      implicit_const = -1;
	    }

	  if (abbrev_name == 0)
	    break;

	  cur_attrs.emplace_back ();
	  struct attr_abbrev &cur_attr = cur_attrs.back ();
	  cur_attr.name = (enum dwarf_attribute) abbrev_name;
	  cur_attr.form = (enum dwarf_form) abbrev_form;
	  cur_attr.implicit_const = implicit_const;
	}

      cur_abbrev->num_attrs = cur_attrs.size ();
      cur_abbrev->attrs =
	XOBNEWVEC (&abbrev_table->m_abbrev_obstack, struct attr_abbrev,
		   cur_abbrev->num_attrs);
      if (!cur_attrs.empty ())
	memcpy (cur_abbrev->attrs, cur_attrs.data (),
		cur_abbrev->num_attrs * sizeof (struct attr_abbrev));

      abbrev_table->add_abbrev (cur_abbrev);

      /* Get next abbreviation.
	 Under Irix6 the abbreviations for a compilation unit are not
	 always properly terminated with an abbrev number of 0.
	 Exit loop if we encounter an abbreviation which we have
	 already read (which means we are about to read the abbreviations
	 for the next compile unit) or if the end of the abbreviation
	 table is reached.  */
      if ((unsigned int) (abbrev_ptr - section->buffer) >= section->size)
	break;
      abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
      abbrev_ptr += bytes_read;
      if (abbrev_table->lookup_abbrev (abbrev_number) != NULL)
	break;
    }

  return abbrev_table;
}
