/** * @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 */