Home | History | Annotate | Download | only in libutil++
      1 /**
      2  * @file bfd_support.h
      3  * BFD muck we have to deal with.
      4  *
      5  * @remark Copyright 2005 OProfile authors
      6  * @remark Read the file COPYING
      7  *
      8  * @author John Levon
      9  */
     10 
     11 #ifndef BFD_SUPPORT_H
     12 #define BFD_SUPPORT_H
     13 
     14 #include "utility.h"
     15 #include "op_types.h"
     16 #include "locate_images.h"
     17 
     18 #include <bfd.h>
     19 #include <stdint.h>
     20 
     21 #include <string>
     22 
     23 class op_bfd_symbol;
     24 
     25 /// holder for BFD state we must keep
     26 struct bfd_info {
     27 	bfd_info() : abfd(0), nr_syms(0), synth_syms(0), image_bfd_info(0) {}
     28 
     29 	~bfd_info();
     30 
     31 	/// close the BFD, setting abfd to NULL
     32 	void close();
     33 
     34 	/// return true if BFD is readable
     35 	bool valid() const { return abfd; }
     36 
     37 	/// return true if BFD has debug info
     38 	bool has_debug_info() const;
     39 
     40 	/// pick out the symbols from the bfd, if we can
     41 	void get_symbols();
     42 
     43 	/// the actual BFD
     44 	bfd * abfd;
     45 	/// normal symbols (includes synthesized symbols)
     46 	scoped_array<asymbol *> syms;
     47 	/// nr. symbols
     48 	size_t nr_syms;
     49 
     50 	void set_image_bfd_info(bfd_info * ibfd) { image_bfd_info = ibfd; }
     51 
     52 private:
     53 	/**
     54 	 * Acquire the synthetic symbols if we need to.
     55 	 */
     56 	bool get_synth_symbols();
     57 
     58 	/**
     59 	 * On PPC64, synth_syms points to an array of synthetic asymbol
     60 	 * structs returned from bfd_get_synthetic_symtab.  The syms
     61 	 * member points into this array, so we have to keep it around
     62 	 * until ~bfd_info time.
     63 	 */
     64 	asymbol * synth_syms;
     65 
     66 	/**
     67 	 * Under certain circumstances, correct handling of the bfd for a
     68 	 * debuginfo file is not possible without access to the bfd for
     69 	 * the actual image file.  The image_bfd_info field provides access to
     70 	 * that bfd when this bfd_info is for a debuginfo file; otherwise
     71 	 * image_bfd_info is NULL.
     72 	 */
     73 	bfd_info * image_bfd_info;
     74 
     75 	/* To address a different issue, we discard symbols whose section
     76 	 * flag does not contain SEC_LOAD.  But since this is true for symbols
     77 	 * found in debuginfo files, we must run those debuginfo symbols
     78 	 * through the function below to prevent them from being inadvertently
     79 	 * discarded.  This function maps the sections from the symbols in
     80 	 * the debuginfo bfd to those of the real image bfd.  Then, when
     81 	 * we later do symbol filtering, we see the sections from the real
     82 	 * bfd, which do contain SEC_LOAD in the section flag.
     83 	 */
     84 	void translate_debuginfo_syms(asymbol ** dbg_syms, long nr_dbg_syms);
     85 
     86 };
     87 
     88 
     89 /*
     90  * find_separate_debug_file - return true if a valid separate debug file found
     91  * @param ibfd binary file
     92  * @param dir_in directory holding the binary file
     93  * @param global_in
     94  * @param filename path to valid debug file
     95  *
     96  * Search order for debug file and use first one found:
     97  * 1) dir_in directory
     98  * 2) dir_in/.debug directory
     99  * 3) global_in/dir_in directory
    100  *
    101  * Newer binutils and Linux distributions (e.g. Fedora) allow the
    102  * creation of debug files that are separate from the binary. The
    103  * debugging information is stripped out of the binary file, placed in
    104  * this separate file, and a link to the new file is placed in the
    105  * binary. The debug files hold the information needed by the debugger
    106  * (and OProfile) to map machine instructions back to source code.
    107  */
    108 extern bool
    109 find_separate_debug_file(bfd * ibfd,
    110                          std::string const & filepath_in,
    111                          std::string & debug_filename,
    112                          extra_images const & extra);
    113 
    114 /// open the given BFD
    115 bfd * open_bfd(std::string const & file);
    116 
    117 /// open the given BFD from the fd
    118 bfd * fdopen_bfd(std::string const & file, int fd);
    119 
    120 /// Return a BFD for an SPU ELF embedded in PPE binary file
    121 bfd * spu_open_bfd(std::string const name, int fd, uint64_t offset_to_spu_elf);
    122 
    123 /// Return true if the symbol is worth looking at
    124 bool interesting_symbol(asymbol * sym);
    125 
    126 /**
    127  * return true if the first symbol is less interesting than the second symbol
    128  * boring symbol are eliminated when multiple symbol exist at the same vma
    129  */
    130 bool boring_symbol(op_bfd_symbol const & first, op_bfd_symbol const & second);
    131 
    132 /// debug info for a given pc
    133 struct linenr_info {
    134 	/// did we find something?
    135 	bool found;
    136 	/// filename
    137 	std::string filename;
    138 	/// line number
    139 	unsigned int line;
    140 };
    141 
    142 /**
    143  * Attempt to locate a filename + line number for the given symbol and
    144  * offset.
    145  *
    146  * The bfd object is either the object associated with the binary or the
    147  * once associated with the separated debug info file so find_nearest_line()
    148  * can't lookup the section contents of code section etc. The filepos of
    149  * debuginfo symbols are different from the original file but we fixed symbol
    150  * filepos earlier.
    151  */
    152 linenr_info const
    153 find_nearest_line(bfd_info const & ibfd, op_bfd_symbol const & sym,
    154                   bfd_vma offset, bool anon_obj);
    155 
    156 #endif /* !BFD_SUPPORT_H */
    157