op_bfd.h revision cc2ee177dbb3befca43e36cfc56778b006c3d050
1/** 2 * @file op_bfd.h 3 * Encapsulation of bfd objects 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author Philippe Elie 9 * @author John Levon 10 */ 11 12#ifndef OP_BFD_H 13#define OP_BFD_H 14 15#include "config.h" 16 17#include <vector> 18#include <string> 19#include <list> 20#include <map> 21 22#include "bfd_support.h" 23#include "utility.h" 24#include "cached_value.h" 25#include "op_types.h" 26 27class op_bfd; 28class string_filter; 29 30/// all symbol vector indexing uses this type 31typedef size_t symbol_index_t; 32 33/** 34 * A symbol description from a bfd point of view. This duplicate 35 * information pointed by an asymbol, we need this duplication in case 36 * the symbol is an artificial symbol 37 */ 38class op_bfd_symbol { 39public: 40 41 /// ctor for real symbols 42 op_bfd_symbol(asymbol const * a); 43 44 /// ctor for artificial symbols 45 op_bfd_symbol(bfd_vma vma, size_t size, std::string const & name); 46 47 bfd_vma vma() const { return symb_value + section_vma; } 48 unsigned long value() const { return symb_value; } 49 unsigned long filepos() const { return symb_value + section_filepos; } 50 std::string const & name() const { return symb_name; } 51 asymbol const * symbol() const { return bfd_symbol; } 52 size_t size() const { return symb_size; } 53 void size(size_t s) { symb_size = s; } 54 bool hidden() const { return symb_hidden; } 55 bool weak() const { return symb_weak; } 56 57 /// compare two symbols by their filepos() 58 bool operator<(op_bfd_symbol const & lhs) const; 59 60private: 61 /// the original bfd symbol, this can be null if the symbol is an 62 /// artificial symbol 63 asymbol const * bfd_symbol; 64 /// the offset of this symbol relative to the begin of the section's 65 /// symbol 66 unsigned long symb_value; 67 /// the section filepos for this symbol 68 unsigned long section_filepos; 69 /// the section vma for this symbol 70 bfd_vma section_vma; 71 /// the size of this symbol 72 size_t symb_size; 73 /// the name of the symbol 74 std::string symb_name; 75 /// normally not externally visible symbol 76 bool symb_hidden; 77 /// whether other symbols can override it 78 bool symb_weak; 79}; 80 81/** 82 * Encapsulation of a bfd object. Simplifies open/close of bfd, enumerating 83 * symbols and retrieving informations for symbols or vma. 84 * 85 * Use of this class relies on a std::ostream cverb 86 */ 87class op_bfd { 88public: 89 /** 90 * @param archive_path oparchive prefix path 91 * @param filename the name of the image file 92 * @param symbol_filter filter to apply to symbols 93 * @param ok in-out parameter: on in, if not set, don't 94 * open the bfd (because it's not there or whatever). On out, 95 * it's set to false if the bfd couldn't be loaded. 96 */ 97 op_bfd(std::string const & archive_path, 98 std::string const & filename, 99 string_filter const & symbol_filter, 100 bool & ok); 101 102 /// close an opened bfd image and free all related resources 103 ~op_bfd(); 104 105 /** 106 * @param sym_idx index of the symbol 107 * @param offset fentry number 108 * @param filename output parameter to store filename 109 * @param linenr output parameter to store linenr. 110 * 111 * Retrieve the relevant finename:linenr information for the sym_idx 112 * at offset. If the lookup fails, return false. In some cases this 113 * function can retrieve the filename and return true but fail to 114 * retrieve the linenr and so can return zero in linenr 115 */ 116 bool get_linenr(symbol_index_t sym_idx, unsigned int offset, 117 std::string & filename, unsigned int & linenr) const; 118 119 /** 120 * @param sym_idx symbol index 121 * @param start reference to start var 122 * @param end reference to end var 123 * 124 * Calculates the range of sample file entries covered by sym. start 125 * and end will be filled in appropriately. If index is the last entry 126 * in symbol table, all entries up to the end of the sample file will 127 * be used. After calculating start and end they are sanitized 128 * 129 * All errors are fatal. 130 */ 131 void get_symbol_range(symbol_index_t sym_idx, 132 unsigned long & start, unsigned long & end) const; 133 134 /** 135 * sym_offset - return offset from a symbol's start 136 * @param num_symbols symbol number 137 * @param num number of fentry 138 * 139 * Returns the offset of a sample at position num 140 * in the samples file from the start of symbol sym_idx. 141 */ 142 unsigned long sym_offset(symbol_index_t num_symbols, u32 num) const; 143 144 /** 145 * @param start reference to the start vma 146 * @param end reference to the end vma 147 * 148 * return in start, end the vma range for this binary object. 149 */ 150 void get_vma_range(bfd_vma & start, bfd_vma & end) const; 151 152 /** return the relocated PC value for the given file offset */ 153 bfd_vma offset_to_pc(bfd_vma offset) const; 154 155 /** 156 * If passed 0, return the file position of the .text section. 157 * Otherwise, return the filepos of a section with a matching 158 * vma. 159 */ 160 unsigned long const get_start_offset(bfd_vma vma = 0) const; 161 162 /** 163 * Return the image name of the underlying binary image. For an 164 * archive, this returns the path *within* the archive, not the 165 * full path of the file. 166 */ 167 std::string get_filename() const; 168 169 /// sorted vector by vma of interesting symbol. 170 std::vector<op_bfd_symbol> syms; 171 172 /// return in bits the bfd_vma size for this binary. This is needed 173 /// because gprof output depend on the bfd_vma for *this* binary 174 /// and do not depend on sizeof(bfd_vma) 175 size_t bfd_arch_bits_per_address() const; 176 177 /// return true if binary contain some debug information 178 bool has_debug_info() const; 179 180private: 181 /// temporary container type for getting symbols 182 typedef std::list<op_bfd_symbol> symbols_found_t; 183 184 /** 185 * Parse and sort in ascending order all symbols 186 * in the file pointed to by abfd that reside in 187 * a %SEC_CODE section. 188 * 189 * The symbols are filtered through 190 * the interesting_symbol() predicate and sorted 191 * with op_bfd_symbol::operator<() comparator. 192 */ 193 void get_symbols(symbols_found_t & symbols); 194 195 /** 196 * Helper function for get_symbols. 197 * Populates bfd_syms and extracts the "interesting_symbol"s. 198 */ 199 void get_symbols_from_file(bfd_info & bfd, size_t start, 200 op_bfd::symbols_found_t & symbols, 201 bool debug_file); 202 203 /** 204 * Add the symbols in the binary, applying filtering, 205 * and handling artificial symbols. 206 */ 207 void add_symbols(symbols_found_t & symbols, 208 string_filter const & symbol_filter); 209 210 /** 211 * symbol_size - return the size of a symbol 212 * @param sym symbol to get size 213 * @param next next symbol in vma order if any 214 */ 215 size_t symbol_size(op_bfd_symbol const & sym, 216 op_bfd_symbol const * next) const; 217 218 /// create an artificial symbol for a symbolless binary 219 op_bfd_symbol const create_artificial_symbol(); 220 221 /* Generate symbols using bfd functions for 222 * the image file associated with the ibfd arg. 223 */ 224 uint process_symtab(bfd_info * bfd, uint start); 225 226 /// filename we open (not including archive path) 227 std::string filename; 228 229 /// path to archive 230 std::string archive_path; 231 232 /// file size in bytes 233 off_t file_size; 234 235 /// corresponding debug file name 236 mutable std::string debug_filename; 237 238 /// true if at least one section has (flags & SEC_DEBUGGING) != 0 239 mutable cached_value<bool> debug_info; 240 241 /// our main bfd object: .bfd may be NULL 242 bfd_info ibfd; 243 244 // corresponding debug bfd object, if one is found 245 mutable bfd_info dbfd; 246 247 typedef std::map<std::string, u32> filepos_map_t; 248 // mapping of section names to filepos in the original binary 249 filepos_map_t filepos_map; 250}; 251 252 253#endif /* !OP_BFD_H */ 254