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 #include <set> 22 23 #include "bfd_support.h" 24 #include "locate_images.h" 25 #include "utility.h" 26 #include "cached_value.h" 27 #include "op_types.h" 28 29 class op_bfd; 30 class string_filter; 31 class extra_images; 32 33 /// all symbol vector indexing uses this type 34 typedef size_t symbol_index_t; 35 36 /** 37 * A symbol description from a bfd point of view. This duplicate 38 * information pointed by an asymbol, we need this duplication in case 39 * the symbol is an artificial symbol 40 */ 41 class op_bfd_symbol { 42 public: 43 44 /// ctor for real symbols 45 op_bfd_symbol(asymbol const * a); 46 47 /// ctor for artificial symbols 48 op_bfd_symbol(bfd_vma vma, size_t size, std::string const & name); 49 50 bfd_vma vma() const { return symb_value + section_vma; } 51 unsigned long value() const { return symb_value; } 52 unsigned long filepos() const { return symb_value + section_filepos; } 53 unsigned long symbol_endpos(void) const; 54 asection const * section(void) const { return bfd_symbol->section; } 55 std::string const & name() const { return symb_name; } 56 asymbol const * symbol() const { return bfd_symbol; } 57 size_t size() const { return symb_size; } 58 void size(size_t s) { symb_size = s; } 59 bool hidden() const { return symb_hidden; } 60 bool weak() const { return symb_weak; } 61 bool artificial() const { return symb_artificial; } 62 63 /// compare two symbols by their filepos() 64 bool operator<(op_bfd_symbol const & lhs) const; 65 66 private: 67 /// the original bfd symbol, this can be null if the symbol is an 68 /// artificial symbol 69 asymbol const * bfd_symbol; 70 /// the offset of this symbol relative to the begin of the section's 71 /// symbol 72 unsigned long symb_value; 73 /// the section filepos for this symbol 74 unsigned long section_filepos; 75 /// the section vma for this symbol 76 bfd_vma section_vma; 77 /// the size of this symbol 78 size_t symb_size; 79 /// the name of the symbol 80 std::string symb_name; 81 /// normally not externally visible symbol 82 bool symb_hidden; 83 /// whether other symbols can override it 84 bool symb_weak; 85 /// symbol is artificially created 86 bool symb_artificial; 87 /// code bytes corresponding to symbol -- used for XML generation 88 std::string symb_bytes; 89 }; 90 91 /** 92 * Encapsulation of a bfd object. Simplifies open/close of bfd, enumerating 93 * symbols and retrieving informations for symbols or vma. 94 * 95 * Use of this class relies on a std::ostream cverb 96 */ 97 class op_bfd { 98 public: 99 /** 100 * @param filename the name of the image file 101 * @param symbol_filter filter to apply to symbols 102 * @param extra_images container where all extra candidate filenames 103 * are stored 104 * @param ok in-out parameter: on in, if not set, don't 105 * open the bfd (because it's not there or whatever). On out, 106 * it's set to false if the bfd couldn't be loaded. 107 */ 108 op_bfd(std::string const & filename, 109 string_filter const & symbol_filter, 110 extra_images const & extra_images, 111 bool & ok); 112 113 /** 114 * This constructor is used when processing an SPU profile 115 * where the SPU ELF is embedded within the PPE binary. 116 */ 117 op_bfd(uint64_t spu_offset, 118 std::string const & filename, 119 string_filter const & symbol_filter, 120 extra_images const & extra_images, 121 bool & ok); 122 123 std::string get_embedding_filename() const { return embedding_filename; } 124 125 /// close an opened bfd image and free all related resources 126 ~op_bfd(); 127 128 /** 129 * @param sym_idx index of the symbol 130 * @param offset fentry number 131 * @param filename output parameter to store filename 132 * @param linenr output parameter to store linenr. 133 * 134 * Retrieve the relevant finename:linenr information for the sym_idx 135 * at offset. If the lookup fails, return false. In some cases this 136 * function can retrieve the filename and return true but fail to 137 * retrieve the linenr and so can return zero in linenr 138 */ 139 bool get_linenr(symbol_index_t sym_idx, bfd_vma offset, 140 std::string & filename, unsigned int & linenr) const; 141 142 /** 143 * @param sym_idx symbol index 144 * @param start reference to start var 145 * @param end reference to end var 146 * 147 * Calculates the range of sample file entries covered by sym. start 148 * and end will be filled in appropriately. If index is the last entry 149 * in symbol table, all entries up to the end of the sample file will 150 * be used. After calculating start and end they are sanitized 151 * 152 * All errors are fatal. 153 */ 154 void get_symbol_range(symbol_index_t sym_idx, 155 unsigned long long & start, unsigned long long & end) const; 156 157 /** 158 * @param start reference to the start vma 159 * @param end reference to the end vma 160 * 161 * return in start, end the vma range for this binary object. 162 */ 163 void get_vma_range(bfd_vma & start, bfd_vma & end) const; 164 165 /** return the relocated PC value for the given file offset */ 166 bfd_vma offset_to_pc(bfd_vma offset) const; 167 168 /** 169 * If passed 0, return the file position of the .text section. 170 * Otherwise, return the filepos of a section with a matching 171 * vma. 172 */ 173 unsigned long get_start_offset(bfd_vma vma = 0) const; 174 175 /** 176 * Return the image name of the underlying binary image. For an 177 * archive, this returns the path *within* the archive, not the 178 * full path of the file. 179 */ 180 std::string get_filename() const; 181 182 /// sorted vector by vma of interesting symbol. 183 std::vector<op_bfd_symbol> syms; 184 185 /// return in bits the bfd_vma size for this binary. This is needed 186 /// because gprof output depend on the bfd_vma for *this* binary 187 /// and do not depend on sizeof(bfd_vma) 188 size_t bfd_arch_bits_per_address() const; 189 190 /// return true if binary contain some debug information 191 bool has_debug_info() const; 192 193 /** 194 * @param sym_idx symbol index 195 * 196 * Return true or false, indicating whether or not the 197 * symbol referenced by the passed sym_idx has code available. 198 * Some symbols have no code associated with them; for example, 199 * artificial symbols created for anonymous memory samples or for 200 * stripped binaries with no symbol debug info. Additionally, 201 * if the bfd object associated with the symbol is not valid, 202 * this function will also return false. 203 * 204 * NOTE: This call should be made prior to invoking 205 * get_symbol_contents to avoid unnecessarily allocating 206 * memory for the symbol contents. 207 */ 208 bool symbol_has_contents(symbol_index_t sym_idx); 209 210 bool get_symbol_contents(symbol_index_t sym_index, 211 unsigned char * contents) const; 212 213 bool valid() const { return ibfd.valid(); } 214 215 private: 216 /// temporary container type for getting symbols 217 typedef std::list<op_bfd_symbol> symbols_found_t; 218 219 /** 220 * Parse and sort in ascending order all symbols 221 * in the file pointed to by abfd that reside in 222 * a %SEC_CODE section. 223 * 224 * The symbols are filtered through 225 * the interesting_symbol() predicate and sorted 226 * with op_bfd_symbol::operator<() comparator. 227 */ 228 void get_symbols(symbols_found_t & symbols); 229 230 /** 231 * Helper function for get_symbols. 232 * Populates bfd_syms and extracts the "interesting_symbol"s. 233 */ 234 void get_symbols_from_file(bfd_info & bfd, size_t start, 235 op_bfd::symbols_found_t & symbols, 236 bool debug_file); 237 238 /** 239 * Add the symbols in the binary, applying filtering, 240 * and handling artificial symbols. 241 */ 242 void add_symbols(symbols_found_t & symbols, 243 string_filter const & symbol_filter); 244 245 /** 246 * symbol_size - return the size of a symbol 247 * @param sym symbol to get size 248 * @param next next symbol in vma order if any 249 */ 250 size_t symbol_size(op_bfd_symbol const & sym, 251 op_bfd_symbol const * next) const; 252 253 /// create an artificial symbol for a symbolless binary 254 op_bfd_symbol const create_artificial_symbol(); 255 256 /* Generate symbols using bfd functions for 257 * the image file associated with the ibfd arg. 258 */ 259 uint process_symtab(bfd_info * bfd, uint start); 260 261 /// filename we open (not including archive path) 262 std::string filename; 263 264 /// path to archive 265 std::string archive_path; 266 267 /// reference to extra_images 268 extra_images const & extra_found_images; 269 270 /// file size in bytes 271 off_t file_size; 272 273 /// corresponding debug file name 274 mutable std::string debug_filename; 275 276 /// true if at least one section has (flags & SEC_DEBUGGING) != 0 277 mutable cached_value<bool> debug_info; 278 279 /// our main bfd object: .bfd may be NULL 280 bfd_info ibfd; 281 282 // corresponding debug bfd object, if one is found 283 mutable bfd_info dbfd; 284 285 /// sections we will avoid to use symbol from, this is needed 286 /// because elf file allows sections with identical vma and we can't 287 /// allow overlapping symbols. Such elf layout is used actually by 288 /// kernel modules where all code section vma are set to 0. 289 std::vector<asection const *> filtered_section; 290 291 typedef std::map<std::string, u32> filepos_map_t; 292 // mapping of section names to filepos in the original binary 293 filepos_map_t filepos_map; 294 295 /** 296 * If spu_offset is non-zero, embedding_filename is the file containing 297 * the embedded SPU image. 298 */ 299 std::string embedding_filename; 300 301 bool anon_obj; 302 }; 303 304 305 #endif /* !OP_BFD_H */ 306