/**
* @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 "utility.h"
#include "op_types.h"
#include "locate_images.h"
#include <bfd.h>
#include <stdint.h>
#include <string>
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; }
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;
/* To address a different issue, we discard symbols whose section
* flag does not contain SEC_LOAD. But since this is true for symbols
* found in debuginfo files, we must run those debuginfo symbols
* through the function below to prevent them from being inadvertently
* discarded. This function maps the sections from the symbols in
* the debuginfo bfd to those of the real image bfd. Then, when
* we later do symbol filtering, we see the sections from the real
* bfd, which do contain SEC_LOAD in the section flag.
*/
void translate_debuginfo_syms(asymbol ** dbg_syms, long nr_dbg_syms);
};
/*
* 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 */