/* Definitions for BFD wrappers used by GDB.

   Copyright (C) 2011-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 GDB_BFD_H
#define GDB_BFD_H

#include "registry.h"
#include "gdbsupport/byte-vector.h"
#include "gdbsupport/gdb_ref_ptr.h"
#include "gdbsupport/iterator-range.h"
#include "gdbsupport/next-iterator.h"

DECLARE_REGISTRY (bfd);

/* If supplied a path starting with this sequence, gdb_bfd_open will
   open BFDs using target fileio operations.  */

#define TARGET_SYSROOT_PREFIX "target:"

/* Returns nonzero if NAME starts with TARGET_SYSROOT_PREFIX, zero
   otherwise.  */

int is_target_filename (const char *name);

/* Returns nonzero if the filename associated with ABFD starts with
   TARGET_SYSROOT_PREFIX, zero otherwise.  */

int gdb_bfd_has_target_filename (struct bfd *abfd);

/* Increment the reference count of ABFD.  It is fine for ABFD to be
   NULL; in this case the function does nothing.  */

void gdb_bfd_ref (struct bfd *abfd);

/* Decrement the reference count of ABFD.  If this is the last
   reference, ABFD will be freed.  If ABFD is NULL, this function does
   nothing.  */

void gdb_bfd_unref (struct bfd *abfd);

/* A policy class for gdb::ref_ptr for BFD reference counting.  */
struct gdb_bfd_ref_policy
{
  static void incref (struct bfd *abfd)
  {
    gdb_bfd_ref (abfd);
  }

  static void decref (struct bfd *abfd)
  {
    gdb_bfd_unref (abfd);
  }
};

/* A gdb::ref_ptr that has been specialized for BFD objects.  */
typedef gdb::ref_ptr<struct bfd, gdb_bfd_ref_policy> gdb_bfd_ref_ptr;

/* Open a read-only (FOPEN_RB) BFD given arguments like bfd_fopen.
   If NAME starts with TARGET_SYSROOT_PREFIX then the BFD will be
   opened using target fileio operations if necessary.  Returns NULL
   on error.  On success, returns a new reference to the BFD.  BFDs
   returned by this call are shared among all callers opening the same
   file.  If FD is not -1, then after this call it is owned by BFD.
   If the BFD was not accessed using target fileio operations then the
   filename associated with the BFD and accessible with
   bfd_get_filename will not be exactly NAME but rather NAME with
   TARGET_SYSROOT_PREFIX stripped.  If WARN_IF_SLOW is true, print a
   warning message if the file is being accessed over a link that may
   be slow.  */

gdb_bfd_ref_ptr gdb_bfd_open (const char *name, const char *target,
			      int fd = -1, bool warn_if_slow = true);

/* Mark the CHILD BFD as being a member of PARENT.  Also, increment
   the reference count of CHILD.  Calling this function ensures that
   as along as CHILD remains alive, PARENT will as well.  Both CHILD
   and PARENT must be non-NULL.  This can be called more than once
   with the same arguments; but it is not allowed to call it for a
   single CHILD with different values for PARENT.  */

void gdb_bfd_mark_parent (bfd *child, bfd *parent);

/* Mark INCLUDEE as being included by INCLUDER.
   This is used to associate the life time of INCLUDEE with INCLUDER.
   For example, with Fission, one file can refer to debug info in another
   file, and internal tables we build for the main file (INCLUDER) may refer
   to data contained in INCLUDEE.  Therefore we want to keep INCLUDEE around
   at least as long as INCLUDER exists.

   Note that this is different than gdb_bfd_mark_parent because in our case
   lifetime tracking is based on the "parent" whereas in gdb_bfd_mark_parent
   lifetime tracking is based on the "child".  Plus in our case INCLUDEE could
   have multiple different "parents".  */

void gdb_bfd_record_inclusion (bfd *includer, bfd *includee);

/* Try to read or map the contents of the section SECT.  If successful, the
   section data is returned and *SIZE is set to the size of the section data;
   this may not be the same as the size according to bfd_section_size if the
   section was compressed.  The returned section data is associated with the BFD
   and will be destroyed when the BFD is destroyed.  There is no other way to
   free it; for temporary uses of section data, see bfd_malloc_and_get_section.
   SECT may not have relocations.  If there is an error reading the section,
   this issues a warning, sets *SIZE to 0, and returns NULL.  */

const gdb_byte *gdb_bfd_map_section (asection *section, bfd_size_type *size);

/* Compute the CRC for ABFD.  The CRC is used to find and verify
   separate debug files.  When successful, this fills in *CRC_OUT and
   returns 1.  Otherwise, this issues a warning and returns 0.  */

int gdb_bfd_crc (struct bfd *abfd, unsigned long *crc_out);



/* A wrapper for bfd_fopen that initializes the gdb-specific reference
   count.  */

gdb_bfd_ref_ptr gdb_bfd_fopen (const char *, const char *, const char *, int);

/* A wrapper for bfd_openr that initializes the gdb-specific reference
   count.  */

gdb_bfd_ref_ptr gdb_bfd_openr (const char *, const char *);

/* A wrapper for bfd_openw that initializes the gdb-specific reference
   count.  */

gdb_bfd_ref_ptr gdb_bfd_openw (const char *, const char *);

/* A wrapper for bfd_openr_iovec that initializes the gdb-specific
   reference count.  */

gdb_bfd_ref_ptr gdb_bfd_openr_iovec (const char *filename, const char *target,
				     void *(*open_func) (struct bfd *nbfd,
							 void *open_closure),
				     void *open_closure,
				     file_ptr (*pread_func) (struct bfd *nbfd,
							     void *stream,
							     void *buf,
							     file_ptr nbytes,
							     file_ptr offset),
				     int (*close_func) (struct bfd *nbfd,
							void *stream),
				     int (*stat_func) (struct bfd *abfd,
						       void *stream,
						       struct stat *sb));

/* A wrapper for bfd_openr_next_archived_file that initializes the
   gdb-specific reference count.  */

gdb_bfd_ref_ptr gdb_bfd_openr_next_archived_file (bfd *archive, bfd *previous);




/* Return the index of the BFD section SECTION.  Ordinarily this is
   just the section's index, but for some special sections, like
   bfd_com_section_ptr, it will be a synthesized value.  */

int gdb_bfd_section_index (bfd *abfd, asection *section);


/* Like bfd_count_sections, but include any possible global sections,
   like bfd_com_section_ptr.  */

int gdb_bfd_count_sections (bfd *abfd);

/* Return true if any section requires relocations, false
   otherwise.  */

int gdb_bfd_requires_relocations (bfd *abfd);

/* Alternative to bfd_get_full_section_contents that returns the section
   contents in *CONTENTS, instead of an allocated buffer.

   Return true on success, false otherwise.  */

bool gdb_bfd_get_full_section_contents (bfd *abfd, asection *section,
					gdb::byte_vector *contents);

/* Create and initialize a BFD handle from a target in-memory range.  */

gdb_bfd_ref_ptr gdb_bfd_open_from_target_memory (CORE_ADDR addr, ULONGEST size,
						 const char *target,
						 const char *filename = nullptr);

/* Range adapter for a BFD's sections.

   To be used as:

     for (asection *sect : gdb_bfd_all_sections (bfd))
       ... use SECT ...
 */

using gdb_bfd_section_range = next_range<asection>;

static inline gdb_bfd_section_range
gdb_bfd_sections (bfd *abfd)
{
  return gdb_bfd_section_range (abfd->sections);
}

static inline gdb_bfd_section_range
gdb_bfd_sections (const gdb_bfd_ref_ptr &abfd)
{
  return gdb_bfd_section_range (abfd->sections);
};

#endif /* GDB_BFD_H */
