profile_container.h revision cc2ee177dbb3befca43e36cfc56778b006c3d050
1/**
2 * @file profile_container.h
3 * Container associating symbols and samples
4 *
5 * @remark Copyright 2002, 2003 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author Philippe Elie
9 * @author John Levon
10 */
11
12#ifndef PROFILE_CONTAINER_H
13#define PROFILE_CONTAINER_H
14
15#include <string>
16#include <vector>
17
18#include "profile.h"
19#include "utility.h"
20#include "op_bfd.h"
21#include "sample_container.h"
22#include "symbol_container.h"
23#include "format_flags.h"
24
25class string_filter;
26class symbol_entry;
27class sample_entry;
28
29/**
30 * Store multiple samples files belonging to the same profiling session.
31 * This is the main container capable of holding the profiles for arbitrary
32 * binary images and arbitrary profile classes.
33 */
34class profile_container : noncopyable {
35public:
36	/**
37	 * Build an object to store information on samples. All parameters
38	 * acts as hint for what you will request after recording samples and
39	 * so allow optimizations during recording the information.
40	 *
41	 * @param debug_info If true line numbers and source files are recorded.
42	 *
43	 * @param need_details If true if we need to record all samples or to
44	 * to record them at symbol level.
45	 */
46	profile_container(bool debug_info, bool need_details);
47
48	~profile_container();
49
50	/**
51	 * add() - record symbols/samples in the underlying container
52	 *
53	 * @param profile the samples files container
54	 * @param abfd the associated bfd object
55	 * @param app_name the owning application name of sample
56	 * @param pclass the profile class to add results for
57	 *
58	 * add() is an helper for delayed ctor. Take care you can't safely
59	 * make any call to add after any other member function call.
60	 * Obviously you can add only samples files which are coherent (same
61	 * sampling rate, same events etc.)
62	 */
63	void add(profile_t const & profile, op_bfd const & abfd,
64		 std::string const & app_name, size_t pclass);
65
66	/// Find a symbol from its image_name, vma, return zero if no symbol
67	/// for this image at this vma
68	symbol_entry const * find_symbol(std::string const & image_name,
69					 bfd_vma vma) const;
70
71	/// Find a symbol from its filename, linenr, return zero if no symbol
72	/// at this location
73	symbol_entry const * find_symbol(debug_name_id filename,
74					size_t linenr) const;
75
76	/// Find a sample by its symbol, vma, return zero if there is no sample
77	/// at this vma
78	sample_entry const * find_sample(symbol_entry const * symbol,
79					 bfd_vma vma) const;
80
81	/// Find a symbol. Return NULL if not found.
82	symbol_entry const * find(symbol_entry const & symbol) const;
83
84	/// used for select_symbols()
85	struct symbol_choice {
86		symbol_choice()
87			: hints(cf_none), threshold(0.0), match_image(false) {}
88
89		/// hints filled in
90		column_flags hints;
91		/// percentage threshold
92		double threshold;
93		/// match the image name only
94		bool match_image;
95		/// owning image name
96		std::string image_name;
97	};
98
99	/**
100	 * select_symbols - create a set of symbols sorted by sample count
101	 * @param choice  parameters to use/fill in when selecting
102	 */
103	symbol_collection const select_symbols(symbol_choice & choice) const;
104
105	/// Like select_symbols for filename without allowing sort by vma.
106	std::vector<debug_name_id> const select_filename(double threshold) const;
107
108	/// return the total number of samples
109	count_array_t samples_count() const;
110
111	/// Get the samples count which belongs to filename. Return 0 if
112	/// no samples found.
113	count_array_t samples_count(debug_name_id filename_id) const;
114	/// Get the samples count which belongs to filename, linenr. Return
115	/// 0 if no samples found.
116	count_array_t samples_count(debug_name_id filename,
117			   size_t linenr) const;
118
119	/// return an iterator to the first symbol
120	symbol_container::symbols_t::iterator begin_symbol() const;
121	/// return an iterator to the last symbol
122	symbol_container::symbols_t::iterator end_symbol() const;
123
124	/// return iterator to the first samples
125	sample_container::samples_iterator begin() const;
126	/// return iterator to the last samples
127	sample_container::samples_iterator end() const;
128
129	/// return iterator to the first samples for this symbol
130	sample_container::samples_iterator begin(symbol_entry const *) const;
131	/// return iterator to the last samples for this symbol
132	sample_container::samples_iterator end(symbol_entry const *) const;
133
134private:
135	/// helper for add()
136	void add_samples(op_bfd const & abfd, symbol_index_t sym_index,
137	                 profile_t::iterator_pair const &,
138	                 symbol_entry const * symbol, size_t pclass);
139
140	/**
141	 * create an unique artificial symbol for an offset range. The range
142	 * is only a hint of the maximum size of the created symbol. We
143	 * give to the symbol an unique name as ?image_file_name#order and
144	 * a range up to the nearest of syms or for the whole range if no
145	 * syms exist after the start offset. the end parameter is updated
146	 * to reflect the symbol range.
147	 *
148	 * The rationale here is to try to create symbols for alignment between
149	 * function as little as possible and to create meaningfull symbols
150	 * for special case such image w/o symbol.
151	 */
152	std::string create_artificial_symbol(op_bfd const & abfd, u32 start,
153	                                     u32 & end, size_t & order);
154
155	/// The symbols collected by pp tools sorted by increased vma, provide
156	/// also a sort order on samples count for each profile class
157	scoped_ptr<symbol_container> symbols;
158	/// The samples count collected by pp tools sorted by increased vma,
159	/// provide also a sort order on (filename, linenr)
160	scoped_ptr<sample_container> samples;
161	/// build() must count samples count for each profile class so cache it
162	/// here since user of profile_container often need it later.
163	count_array_t total_count;
164
165	/**
166	 * Optimization hints for what information we are going to need,
167	 * see the explanation in profile_container()
168	 */
169	//@{
170	bool debug_info;
171	bool need_details;
172	//@}
173};
174
175#endif /* !PROFILE_CONTAINER_H */
176