/* DWARF 2 low-level section code

   Copyright (C) 1994-2023 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_read (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);
}
