/* DWARF 2 low-level section code

   Copyright (C) 1994-2021 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/section.h"
#include "gdb_bfd.h"
#include "objfiles.h"
#include "complaints.h"

void
dwarf2_section_info::overflow_complaint () const
{
  complaint (_("debug info runs off end of %s section"
	       " [in module %s]"),
	     get_name (), get_file_name ());
}

struct dwarf2_section_info *
dwarf2_section_info::get_containing_section () const
{
  gdb_assert (is_virtual);
  return s.containing_section;
}

struct bfd *
dwarf2_section_info::get_bfd_owner () const
{
  const dwarf2_section_info *section = this;
  if (is_virtual)
    {
      section = get_containing_section ();
      gdb_assert (!section->is_virtual);
    }
  gdb_assert (section->s.section != nullptr);
  return section->s.section->owner;
}

asection *
dwarf2_section_info::get_bfd_section () const
{
  const dwarf2_section_info *section = this;
  if (section->is_virtual)
    {
      section = get_containing_section ();
      gdb_assert (!section->is_virtual);
    }
  return section->s.section;
}

const char *
dwarf2_section_info::get_name () const
{
  asection *sectp = get_bfd_section ();

  gdb_assert (sectp != NULL);
  return bfd_section_name (sectp);
}

const char *
dwarf2_section_info::get_file_name () const
{
  bfd *abfd = get_bfd_owner ();

  gdb_assert (abfd != nullptr);
  return bfd_get_filename (abfd);
}

int
dwarf2_section_info::get_id () const
{
  asection *sectp = get_bfd_section ();

  if (sectp == NULL)
    return 0;
  return sectp->id;
}

int
dwarf2_section_info::get_flags () const
{
  asection *sectp = get_bfd_section ();

  gdb_assert (sectp != NULL);
  return bfd_section_flags (sectp);
}

bool
dwarf2_section_info::empty () const
{
  if (is_virtual)
    return size == 0;
  return s.section == NULL || size == 0;
}

void
dwarf2_section_info::read (struct objfile *objfile)
{
  asection *sectp;
  bfd *abfd;
  gdb_byte *buf, *retbuf;

  if (readin)
    return;
  buffer = NULL;
  readin = true;

  if (empty ())
    return;

  sectp = get_bfd_section ();

  /* If this is a virtual section we need to read in the real one first.  */
  if (is_virtual)
    {
      struct dwarf2_section_info *containing_section =
	get_containing_section ();

      gdb_assert (sectp != NULL);
      if ((sectp->flags & SEC_RELOC) != 0)
	{
	  error (_("Dwarf Error: DWP format V2 with relocations is not"
		   " supported in section %s [in module %s]"),
		 get_name (), get_file_name ());
	}
      containing_section->read (objfile);
      /* Other code should have already caught virtual sections that don't
	 fit.  */
      gdb_assert (virtual_offset + size <= containing_section->size);
      /* If the real section is empty or there was a problem reading the
	 section we shouldn't get here.  */
      gdb_assert (containing_section->buffer != NULL);
      buffer = containing_section->buffer + virtual_offset;
      return;
    }

  /* If the section has relocations, we must read it ourselves.
     Otherwise we attach it to the BFD.  */
  if ((sectp->flags & SEC_RELOC) == 0)
    {
      buffer = gdb_bfd_map_section (sectp, &size);
      return;
    }

  buf = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack, size);
  buffer = buf;

  /* When debugging .o files, we may need to apply relocations; see
     http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
     We never compress sections in .o files, so we only need to
     try this when the section is not compressed.  */
  retbuf = symfile_relocate_debug_section (objfile, sectp, buf);
  if (retbuf != NULL)
    {
      buffer = retbuf;
      return;
    }

  abfd = get_bfd_owner ();
  gdb_assert (abfd != NULL);

  if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
      || bfd_bread (buf, size, abfd) != size)
    {
      error (_("Dwarf Error: Can't read DWARF data"
	       " in section %s [in module %s]"),
	     bfd_section_name (sectp), bfd_get_filename (abfd));
    }
}

const char *
dwarf2_section_info::read_string (struct objfile *objfile, LONGEST str_offset,
				  const char *form_name)
{
  read (objfile);
  if (buffer == NULL)
    {
      if (get_bfd_section () == nullptr)
	error (_("Dwarf Error: %s used without required section"),
	       form_name);
      else
	error (_("Dwarf Error: %s used without %s section [in module %s]"),
	       form_name, get_name (), get_file_name ());
    }
  if (str_offset >= size)
    error (_("%s pointing outside of %s section [in module %s]"),
	   form_name, get_name (), get_file_name ());
  gdb_assert (HOST_CHAR_BIT == 8);
  if (buffer[str_offset] == '\0')
    return NULL;
  return (const char *) (buffer + str_offset);
}
