• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * @file format_output.h
3  * outputting format for symbol lists
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 FORMAT_OUTPUT_H
13 #define FORMAT_OUTPUT_H
14 
15 #include "config.h"
16 
17 #include <string>
18 #include <map>
19 #include <iosfwd>
20 
21 #include "format_flags.h"
22 #include "symbol.h"
23 #include "string_filter.h"
24 #include "xml_output.h"
25 
26 class symbol_entry;
27 class sample_entry;
28 class callgraph_container;
29 class profile_container;
30 class diff_container;
31 class extra_images;
32 class op_bfd;
33 
34 struct profile_classes;
35 // FIXME: should be passed to the derived class formatter ctor
36 extern profile_classes classes;
37 
38 namespace format_output {
39 
40 /// base class for formatter, handle common options to formatter
41 class formatter {
42 public:
43 	formatter(extra_images const & extra);
44 	virtual ~formatter();
45 
46 	/// add a given column
47 	void add_format(format_flags flag);
48 
49 	/// set the need_header boolean to false
50 	void show_header(bool);
51 	/// format for 64 bit wide VMAs
52 	void vma_format_64bit(bool);
53 	/// show long (full path) filenames
54 	void show_long_filenames(bool);
55 	/// use global count rather symbol count for details percent
56 	void show_global_percent(bool);
57 
58 	/**
59 	 * Set the number of collected profile classes. Each class
60 	 * will output sample count and percentage in extra columns.
61 	 *
62 	 * This class assumes that the profile information has been
63 	 * populated with the right number of classes.
64 	 */
65 	void set_nr_classes(size_t nr_classes);
66 
67 	/// output table header, implemented by calling the virtual function
68 	/// output_header_field()
69 	void output_header(std::ostream & out);
70 
71 protected:
72 	struct counts_t {
73 		/// total sample count
74 		count_array_t total;
75 		/// samples so far
76 		count_array_t cumulated_samples;
77 		/// percentage so far
78 		count_array_t cumulated_percent;
79 		/// detailed percentage so far
80 		count_array_t cumulated_percent_details;
81 	};
82 
83 	/// data passed for output
84 	struct field_datum {
85 		field_datum(symbol_entry const & sym,
86 		            sample_entry const & s,
87 			    size_t pc, counts_t & c,
88 			    extra_images const & extra, double d = 0.0)
symbolfield_datum89 			: symbol(sym), sample(s), pclass(pc),
90 			  counts(c), extra(extra), diff(d) {}
91 		symbol_entry const & symbol;
92 		sample_entry const & sample;
93 		size_t pclass;
94 		counts_t & counts;
95 		extra_images const & extra;
96 		double diff;
97 	};
98 
99 	/// format callback type
100 	typedef std::string (formatter::*fct_format)(field_datum const &);
101 
102 	/** @name format functions.
103 	 * The set of formatting functions, used internally by output().
104 	 */
105 	//@{
106 	std::string format_vma(field_datum const &);
107 	std::string format_symb_name(field_datum const &);
108 	std::string format_image_name(field_datum const &);
109 	std::string format_app_name(field_datum const &);
110 	std::string format_linenr_info(field_datum const &);
111 	std::string format_nr_samples(field_datum const &);
112 	std::string format_nr_cumulated_samples(field_datum const &);
113 	std::string format_percent(field_datum const &);
114 	std::string format_cumulated_percent(field_datum const &);
115 	std::string format_percent_details(field_datum const &);
116 	std::string format_cumulated_percent_details(field_datum const &);
117 	std::string format_diff(field_datum const &);
118 	//@}
119 
120 	/// decribe one field of the colummned output.
121 	struct field_description {
field_descriptionfield_description122 		field_description() {}
field_descriptionfield_description123 		field_description(std::size_t w, std::string h,
124 				  fct_format f)
125 			: width(w), header_name(h), formatter(f) {}
126 
127 		std::size_t width;
128 		std::string header_name;
129 		fct_format formatter;
130 	};
131 
132 	typedef std::map<format_flags, field_description> format_map_t;
133 
134 	/// actually do output
135 	void do_output(std::ostream & out, symbol_entry const & symbol,
136 		      sample_entry const & sample, counts_t & c,
137 	              diff_array_t const & = diff_array_t(),
138 	              bool hide_immutable_field = false);
139 
140 	/// returns the nr of char needed to pad this field
141 	size_t output_header_field(std::ostream & out, format_flags fl,
142 	                           size_t padding);
143 
144 	/// returns the nr of char needed to pad this field
145 	size_t output_field(std::ostream & out, field_datum const & datum,
146 			   format_flags fl, size_t padding,
147 			   bool hide_immutable);
148 
149 	/// stores functors for doing actual formatting
150 	format_map_t format_map;
151 
152 	/// number of profile classes
153 	size_t nr_classes;
154 
155 	/// total counts
156 	counts_t counts;
157 
158 	/// formatting flags set
159 	format_flags flags;
160 	/// true if we need to format as 64 bits quantities
161 	bool vma_64;
162 	/// false if we use basename(filename) in output rather filename
163 	bool long_filenames;
164 	/// true if we need to show header before the first output
165 	bool need_header;
166 	/// bool if details percentage are relative to total count rather to
167 	/// symbol count
168 	bool global_percent;
169 
170 	/// To retrieve the real image location, usefull when acting on
171 	/// an archive and for 2.6 kernel modules
172 	extra_images const & extra_found_images;
173 };
174 
175 
176 /// class to output in a columned format symbols and associated samples
177 class opreport_formatter : public formatter {
178 public:
179 	/// build a ready to use formatter
180 	opreport_formatter(profile_container const & profile);
181 
182 	/** output a vector of symbols to out according to the output format
183 	 * specifier previously set by call(s) to add_format() */
184 	void output(std::ostream & out, symbol_collection const & syms);
185 
186 	/// set the output_details boolean
187 	void show_details(bool);
188 
189 private:
190 
191 	/** output one symbol symb to out according to the output format
192 	 * specifier previously set by call(s) to add_format() */
193 	void output(std::ostream & out, symbol_entry const * symb);
194 
195 	/// output details for the symbol
196 	void output_details(std::ostream & out, symbol_entry const * symb);
197 
198 	/// container we work from
199 	profile_container const & profile;
200 
201 	/// true if we need to show details for each symbols
202 	bool need_details;
203 };
204 
205 
206 /// class to output in a columned format caller/callee and associated samples
207 class cg_formatter : public formatter {
208 public:
209 	/// build a ready to use formatter
210 	cg_formatter(callgraph_container const & profile);
211 
212 	/** output callgraph information according to the previously format
213 	 * specifier set by call(s) to add_format() */
214 	void output(std::ostream & out, symbol_collection const & syms);
215 };
216 
217 /// class to output a columned format symbols plus diff values
218 class diff_formatter : public formatter {
219 public:
220 	/// build a ready to use formatter
221 	diff_formatter(diff_container const & profile,
222 		       extra_images const & extra);
223 
224 	/**
225 	 * Output a vector of symbols to out according to the output
226 	 * format specifier previously set by call(s) to add_format()
227 	 */
228 	void output(std::ostream & out, diff_collection const & syms);
229 
230 private:
231 	/// output a single symbol
232 	void output(std::ostream & out, diff_symbol const & sym);
233 
234 };
235 
236 
237 /// class to output in XML format
238 class xml_formatter : public formatter {
239 public:
240 	/// build a ready to use formatter
241 	xml_formatter(profile_container const * profile,
242 		      symbol_collection & symbols, extra_images const & extra,
243 		      string_filter const & symbol_filter);
244 
245 	// output body of XML output
246 	void output(std::ostream & out);
247 
248 	/** output one symbol symb to out according to the output format
249 	 * specifier previously set by call(s) to add_format() */
250 	virtual void output_symbol(std::ostream & out,
251 		symbol_entry const * symb, size_t lo, size_t hi,
252 		bool is_module);
253 
254 	/// output details for the symbol
255 	std::string output_symbol_details(symbol_entry const * symb,
256 		size_t & detail_index, size_t const lo, size_t const hi);
257 
258 	/// set the output_details boolean
259 	void show_details(bool);
260 
261 	// output SymbolData XML elements
262 	void output_symbol_data(std::ostream & out);
263 
264 private:
265 	/// container we work from
266 	profile_container const * profile;
267 
268 	// ordered collection of symbols associated with this profile
269 	symbol_collection & symbols;
270 
271 	/// true if we need to show details for each symbols
272 	bool need_details;
273 
274 	// count of DetailData items output so far
275 	size_t detail_count;
276 
277 	/// with --details we need to reopen the bfd object for each symb to
278 	/// get it's contents, hence we store the filter used by the bfd ctor.
279 	string_filter const & symbol_filter;
280 
281 	void output_sample_data(std::ostream & out,
282 		sample_entry const & sample, size_t count);
283 
284 	/// output attribute in XML
285 	void output_attribute(std::ostream & out, field_datum const & datum,
286 			      format_flags fl, tag_t tag);
287 
288 	/// Retrieve a bfd object for this symbol, reopening a new bfd object
289 	/// only if necessary
290 	bool get_bfd_object(symbol_entry const * symb, op_bfd * & abfd) const;
291 
292 	void output_the_symbol_data(std::ostream & out,
293 		symbol_entry const * symb, op_bfd * & abfd);
294 
295 	void output_cg_children(std::ostream & out,
296 		cg_symbol::children const cg_symb, op_bfd * & abfd);
297 };
298 
299 // callgraph XML output version
300 class xml_cg_formatter : public xml_formatter {
301 public:
302 	/// build a ready to use formatter
303 	xml_cg_formatter(callgraph_container const & callgraph,
304 		symbol_collection & symbols, string_filter const & sf);
305 
306 	/** output one symbol symb to out according to the output format
307 	 * specifier previously set by call(s) to add_format() */
308 	virtual void output_symbol(std::ostream & out,
309 		symbol_entry const * symb, size_t lo, size_t hi, bool is_module);
310 
311 private:
312 	/// container we work from
313 	callgraph_container const & callgraph;
314 
315 	void output_symbol_core(std::ostream & out,
316 		cg_symbol::children const cg_symb,
317 		std::string const selfname, std::string const qname,
318 		size_t lo, size_t hi, bool is_module, tag_t tag);
319 };
320 
321 } // namespace format_output
322 
323 
324 #endif /* !FORMAT_OUTPUT_H */
325