18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file profile.h 38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Encapsulation for samples files over all profile classes 48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * belonging to the same binary image 58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002 OProfile authors 78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING 88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie 108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon 118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifndef PROFILE_H 148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define PROFILE_H 158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <string> 178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <map> 188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <iterator> 198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "odb.h" 218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_types.h" 228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "utility.h" 238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "populate_for_spu.h" 248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass opd_header; 268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass op_bfd; 278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Class containing a single sample file contents. 308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * i.e. set of count values for VMA offsets for 318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * a particular binary. 328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass profile_t : noncopyable { 348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic: 358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /** 368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * profile_t - construct an empty profile_t object 378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd profile_t(); 398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /// return true if no sample file has been loaded 418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool empty() const { return !file_header.get(); } 428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /// return the header of the last opened samples file 448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd opd_header const & get_header() const { 458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return *file_header; 468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /** 498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * count samples count w/o recording them 508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param filename sample filename 518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * convenience interface for raw access to sample count w/o recording 538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * them. It's placed here so all access to samples files go through 548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * profile_t static or non static member. 558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd static count_type sample_count(std::string const & filename); 578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /** 598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Indicate if given sample file is from a Cell Broadband Engine 608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * SPU profile 618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param filename sample filename 628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Convenience interface put here so all access to samples files 648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * go through profile_t static or non static member. 658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd static enum profile_type is_spu_sample_file(std::string const & filename); 678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /** 698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * cumulate sample file to our container of samples 708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param filename sample file name 718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * store samples for one sample file, sample file header is sanitized. 738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * all error are fatal 758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd void add_sample_file(std::string const & filename); 778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /// Set an appropriate start offset, see comments below. 798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd void set_offset(op_bfd const & abfd); 808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd class const_iterator; 828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd typedef std::pair<const_iterator, const_iterator> iterator_pair; 838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /** 858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param start start offset 868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param end end offset 878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * return an iterator pair to [start, end) range 898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd iterator_pair 918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd samples_range(odb_key_t start, odb_key_t end) const; 928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /// return a pair of iterator for all samples 948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd iterator_pair samples_range() const; 958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprivate: 978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /// helper for sample_count() and add_sample_file(). All error launch 988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /// an exception. 998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd static void 1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd open_sample_file(std::string const & filename, odb_t &); 1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /// copy of the samples file header 1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd scoped_ptr<opd_header> file_header; 1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /// storage type for samples sorted by eip 1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd typedef std::map<odb_key_t, count_type> ordered_samples_t; 1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /** 1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Samples are stored in hash table, iterating over hash table don't 1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * provide any ordering, the above count() interface rely on samples 1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * ordered by eip. This map is only a temporary storage where samples 1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * are ordered by eip. 1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ordered_samples_t ordered_samples; 1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /** 1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * For certain profiles, such as kernel/modules, and anon 1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * regions with a matching binary, this value is non-zero, 1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * and represents the file offset of the relevant section. 1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * For kernel profiles, this is done because we use the information 1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * provided in /proc/ksyms, which only gives the mapped position of 1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * .text, and the symbol _text from vmlinux. This value is used to fix 1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * up the sample offsets for kernel code as a result of this difference 1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * In user-space samples, the sample offset is from the start of the 1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * mapped file, as seen in /proc/pid/maps. This is fine for 1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * mappings of permanent files, but with anon mappings, we need 1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * to adjust the key values to be a file offset against the 1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * *binary* (if there is one). This can obviously be different. 1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * So we pass our anon mapping start VMA to op_bfd, which looks 1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * for a section with that VMA, then returns the section's 1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * filepos. So all is good. 1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Finally, note that for cg we can't use this inside the 1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * profile_t, as we're storing two offsets in the key value. So 1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * we do it later in that case. 1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Phew. 1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd u64 start_offset; 1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}; 1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// It will be easier to derive profile_t::const_iterator from 1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// std::iterator<std::input_iterator_tag, unsigned int> but this doesn't 1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// work for gcc <= 2.95 so we provide the neccessary typedef in the hard way. 1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// See ISO C++ 17.4.3.1 � 1 and 14.7.3 � 9. 1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace std { 1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd template <> 1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct iterator_traits<profile_t::const_iterator> { 1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd typedef ptrdiff_t difference_type; 1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd typedef count_type value_type; 1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd typedef count_type * pointer; 1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd typedef count_type & reference; 1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd typedef input_iterator_tag iterator_category; 1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd }; 1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass profile_t::const_iterator 1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd typedef ordered_samples_t::const_iterator iterator_t; 1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic: 1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd const_iterator() : start_offset(0) {} 1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd const_iterator(iterator_t it_, u64 start_offset_) 1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd : it(it_), start_offset(start_offset_) {} 1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd count_type operator*() const { return it->second; } 1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd const_iterator & operator++() { ++it; return *this; } 1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd odb_key_t vma() const { return it->first + start_offset; } 1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd count_type count() const { return **this; } 1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool operator!=(const_iterator const & rhs) const { 1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return it != rhs.it; 1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool operator==(const_iterator const & rhs) const { 1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return it == rhs.it; 1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprivate: 1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd iterator_t it; 1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd u64 start_offset; 1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}; 1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif /* !PROFILE_H */ 188