/**
 * @file bfd_support.h
 * BFD muck we have to deal with.
 *
 * @remark Copyright 2005 OProfile authors
 * @remark Read the file COPYING
 *
 * @author John Levon
 */

#ifndef BFD_SUPPORT_H
#define BFD_SUPPORT_H

#include "config.h"
#include "utility.h"
#include "op_types.h"
#include "locate_images.h"

#include <bfd.h>
#include <stdint.h>

#include <string>
#include <map>

class op_bfd_symbol;

/// holder for BFD state we must keep
struct bfd_info {
	bfd_info() : abfd(0), nr_syms(0), synth_syms(0), image_bfd_info(0) {}

	~bfd_info();

	/// close the BFD, setting abfd to NULL
	void close();

	/// return true if BFD is readable
	bool valid() const { return abfd; }

	/// return true if BFD has debug info
	bool has_debug_info() const;

	/// pick out the symbols from the bfd, if we can
	void get_symbols();

	/// the actual BFD
	bfd * abfd;
	/// normal symbols (includes synthesized symbols)
	scoped_array<asymbol *> syms;
	/// nr. symbols
	size_t nr_syms;

	void set_image_bfd_info(bfd_info * ibfd) { image_bfd_info = ibfd; }
	bfd_info * get_image_bfd_info(void) const { return image_bfd_info; }

private:
	/**
	 * Acquire the synthetic symbols if we need to.
	 */
	bool get_synth_symbols();

	/**
	 * On PPC64, synth_syms points to an array of synthetic asymbol
	 * structs returned from bfd_get_synthetic_symtab.  The syms
	 * member points into this array, so we have to keep it around
	 * until ~bfd_info time.
	 */
	asymbol * synth_syms;

	/**
	 * Under certain circumstances, correct handling of the bfd for a
	 * debuginfo file is not possible without access to the bfd for
	 * the actual image file.  The image_bfd_info field provides access to
	 * that bfd when this bfd_info is for a debuginfo file; otherwise
	 * image_bfd_info is NULL.
	 */ 
	bfd_info * image_bfd_info;

#if SYNTHESIZE_SYMBOLS
	/**
	 * This function is used only for ppc64 binaries. It uses the runtime
	 * image BFD (accessed through image_bfd_info) as needed when processing
	 * debuginfo files.
	 */
	void translate_debuginfo_syms(asymbol ** dbg_syms, long nr_dbg_syms);

	/**
	 * This map is used to cache section VMAs during translate_debuginfo_syms
	 * so they can be restored later.
	 */
	std::map<bfd_vma, bfd_vma> section_vma_maps;

#endif

};


/*
 * find_separate_debug_file - return true if a valid separate debug file found
 * @param ibfd binary file
 * @param dir_in directory holding the binary file
 * @param global_in
 * @param filename path to valid debug file
 *
 * Search order for debug file and use first one found:
 * 1) dir_in directory
 * 2) dir_in/.debug directory
 * 3) global_in/dir_in directory
 *
 * Newer binutils and Linux distributions (e.g. Fedora) allow the
 * creation of debug files that are separate from the binary. The
 * debugging information is stripped out of the binary file, placed in
 * this separate file, and a link to the new file is placed in the
 * binary. The debug files hold the information needed by the debugger
 * (and OProfile) to map machine instructions back to source code.
 */
extern bool
find_separate_debug_file(bfd * ibfd, 
                         std::string const & filepath_in,
                         std::string & debug_filename,
                         extra_images const & extra);

/// open the given BFD
bfd * open_bfd(std::string const & file);

/// open the given BFD from the fd
bfd * fdopen_bfd(std::string const & file, int fd);

/// Return a BFD for an SPU ELF embedded in PPE binary file
bfd * spu_open_bfd(std::string const name, int fd, uint64_t offset_to_spu_elf);

/// Return true if the symbol is worth looking at
bool interesting_symbol(asymbol * sym);

/**
 * return true if the first symbol is less interesting than the second symbol
 * boring symbol are eliminated when multiple symbol exist at the same vma
 */
bool boring_symbol(op_bfd_symbol const & first, op_bfd_symbol const & second);

/// debug info for a given pc
struct linenr_info {
	/// did we find something?
	bool found;
	/// filename
	std::string filename;
	/// line number
	unsigned int line;
};

/**
 * Attempt to locate a filename + line number for the given symbol and
 * offset.
 *
 * The bfd object is either the object associated with the binary or the
 * once associated with the separated debug info file so find_nearest_line()
 * can't lookup the section contents of code section etc. The filepos of
 * debuginfo symbols are different from the original file but we fixed symbol
 * filepos earlier.
 */
linenr_info const
find_nearest_line(bfd_info const & ibfd, op_bfd_symbol const & sym,
                  bfd_vma offset, bool anon_obj);

#endif /* !BFD_SUPPORT_H */
