/* DWARF 2 debugging format support for GDB.

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

   This file is part of GDB.

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

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

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

#ifndef DWARF2_LINE_HEADER_H
#define DWARF2_LINE_HEADER_H

#include "gdbtypes.h"

/* dir_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5 and
   later.  */
typedef int dir_index;

/* file_name_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5
   and later.  */
typedef int file_name_index;

struct line_header;

struct file_entry
{
  file_entry () = default;

  file_entry (const char *name_, dir_index d_index_,
	      unsigned int mod_time_, unsigned int length_)
    : name (name_),
      d_index (d_index_),
      mod_time (mod_time_),
      length (length_)
  {}

  /* Return the include directory at D_INDEX stored in LH.  Returns
     NULL if D_INDEX is out of bounds.  */
  const char *include_dir (const line_header *lh) const;

  /* The file name.  Note this is an observing pointer.  The memory is
     owned by debug_line_buffer.  */
  const char *name {};

  /* The directory index (1-based).  */
  dir_index d_index {};

  unsigned int mod_time {};

  unsigned int length {};

  /* True if referenced by the Line Number Program.  */
  bool included_p {};

  /* The associated symbol table, if any.  */
  struct symtab *symtab {};
};

/* The line number information for a compilation unit (found in the
   .debug_line section) begins with a "statement program header",
   which contains the following information.  */
struct line_header
{
  line_header ()
    : offset_in_dwz {}
  {}

  /* Add an entry to the include directory table.  */
  void add_include_dir (const char *include_dir);

  /* Add an entry to the file name table.  */
  void add_file_name (const char *name, dir_index d_index,
		      unsigned int mod_time, unsigned int length);

  /* Return the include dir at INDEX (0-based in DWARF 5 and 1-based before).
     Returns NULL if INDEX is out of bounds.  */
  const char *include_dir_at (dir_index index) const
  {
    int vec_index;
    if (version >= 5)
      vec_index = index;
    else
      vec_index = index - 1;
    if (vec_index < 0 || vec_index >= m_include_dirs.size ())
      return NULL;
    return m_include_dirs[vec_index];
  }

  bool is_valid_file_index (int file_index) const
  {
    if (version >= 5)
      return 0 <= file_index && file_index < file_names_size ();
    return 1 <= file_index && file_index <= file_names_size ();
  }

  /* Return the file name at INDEX (0-based in DWARF 5 and 1-based before).
     Returns NULL if INDEX is out of bounds.  */
  file_entry *file_name_at (file_name_index index)
  {
    int vec_index;
    if (version >= 5)
      vec_index = index;
    else
      vec_index = index - 1;
    if (vec_index < 0 || vec_index >= m_file_names.size ())
      return NULL;
    return &m_file_names[vec_index];
  }

  /* A const overload of the same.  */
  const file_entry *file_name_at (file_name_index index) const
  {
    line_header *lh = const_cast<line_header *> (this);
    return lh->file_name_at (index);
  }

  /* The indexes are 0-based in DWARF 5 and 1-based in DWARF 4. Therefore,
     this method should only be used to iterate through all file entries in an
     index-agnostic manner.  */
  std::vector<file_entry> &file_names ()
  { return m_file_names; }
  /* A const overload of the same.  */
  const std::vector<file_entry> &file_names () const
  { return m_file_names; }

  /* Offset of line number information in .debug_line section.  */
  sect_offset sect_off {};

  /* OFFSET is for struct dwz_file associated with dwarf2_per_objfile.  */
  unsigned offset_in_dwz : 1; /* Can't initialize bitfields in-class.  */

  unsigned int total_length {};
  unsigned short version {};
  unsigned int header_length {};
  unsigned char minimum_instruction_length {};
  unsigned char maximum_ops_per_instruction {};
  unsigned char default_is_stmt {};
  int line_base {};
  unsigned char line_range {};
  unsigned char opcode_base {};

  /* standard_opcode_lengths[i] is the number of operands for the
     standard opcode whose value is i.  This means that
     standard_opcode_lengths[0] is unused, and the last meaningful
     element is standard_opcode_lengths[opcode_base - 1].  */
  std::unique_ptr<unsigned char[]> standard_opcode_lengths;

  int file_names_size () const
  { return m_file_names.size(); }

  /* The start and end of the statement program following this
     header.  These point into dwarf2_per_objfile->line_buffer.  */
  const gdb_byte *statement_program_start {}, *statement_program_end {};

  /* Return file name relative to the compilation directory of file
     number I in this object's file name table.  The result is
     allocated using xmalloc; the caller is responsible for freeing
     it.  */
  gdb::unique_xmalloc_ptr<char> file_file_name (int file) const;

 private:
  /* The include_directories table.  Note these are observing
     pointers.  The memory is owned by debug_line_buffer.  */
  std::vector<const char *> m_include_dirs;

  /* The file_names table. This is private because the meaning of indexes
     differs among DWARF versions (The first valid index is 1 in DWARF 4 and
     before, and is 0 in DWARF 5 and later).  So the client should use
     file_name_at method for access.  */
  std::vector<file_entry> m_file_names;
};

typedef std::unique_ptr<line_header> line_header_up;

inline const char *
file_entry::include_dir (const line_header *lh) const
{
  return lh->include_dir_at (d_index);
}

/* Read the statement program header starting at SECT_OFF in SECTION.
   Return line_header.  Returns nullptr if there is a problem reading
   the header, e.g., if it has a version we don't understand.

   NOTE: the strings in the include directory and file name tables of
   the returned object point into the dwarf line section buffer,
   and must not be freed.  */

extern line_header_up dwarf_decode_line_header
  (sect_offset sect_off, bool is_dwz, dwarf2_per_objfile *per_objfile,
   struct dwarf2_section_info *section, const struct comp_unit_head *cu_header);

#endif /* DWARF2_LINE_HEADER_H */
