/* Definitions for BFD wrappers used by GDB.

   Copyright (C) 2011, 2012
   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"

DECLARE_REGISTRY (bfd);

/* Make a copy ABFD's filename using bfd_alloc, and reassign it to the
   BFD.  This ensures that the BFD's filename has the same lifetime as
   the BFD itself.  */

void gdb_bfd_stash_filename (struct bfd *abfd);

/* Open a read-only (FOPEN_RB) BFD given arguments like bfd_fopen.
   Returns NULL on error.  On success, returns a new reference to the
   BFD, which must be freed with gdb_bfd_unref.  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.  */

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

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

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

/* 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.  This
   function will throw on error.  */

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



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

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

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

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

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

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

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

bfd *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 and calls gdb_bfd_stash_filename.  */

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

/* A wrapper for bfd_fdopenr that initializes the gdb-specific
   reference count and calls gdb_bfd_stash_filename.  */

bfd *gdb_bfd_fdopenr (const char *filename, const char *target, int fd);

#endif /* GDB_BFD_H */
