/* Definitions for BFD wrappers used by GDB.

   Copyright (C) 2011-2019 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/gdb_ref_ptr.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.  */

gdb_bfd_ref_ptr gdb_bfd_open (const char *name, const char *target, int fd);

/* 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_get_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);

#endif /* GDB_BFD_H */
