blob: 8e527d5a847962cbacb54c900d29476d9759f99b [file] [log] [blame]
Mike Dodd8cfa7022010-11-17 11:12:26 -08001/**
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
26class symbol_entry;
27class sample_entry;
28class callgraph_container;
29class profile_container;
30class diff_container;
31class extra_images;
32class op_bfd;
33
34struct profile_classes;
35// FIXME: should be passed to the derived class formatter ctor
36extern profile_classes classes;
37
38namespace format_output {
39
40/// base class for formatter, handle common options to formatter
41class formatter {
42public:
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
71protected:
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)
89 : 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;
Conley Owens90b78b12011-11-09 14:05:49 -080094 counts_t & counts;
Mike Dodd8cfa7022010-11-17 11:12:26 -080095 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 {
122 field_description() {}
123 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
177class opreport_formatter : public formatter {
178public:
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
189private:
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
207class cg_formatter : public formatter {
208public:
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
218class diff_formatter : public formatter {
219public:
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
230private:
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
238class xml_formatter : public formatter {
239public:
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
264private:
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
300class xml_cg_formatter : public xml_formatter {
301public:
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
311private:
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 */