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