summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard@openedhand.com>2007-02-22 16:58:36 +0000
committerRichard Purdie <richard@openedhand.com>2007-02-22 16:58:36 +0000
commit1b447bc1c9f5c9b6bd39e2ce2d24e78813422b5d (patch)
tree62ea7d1896621d3085ee25dfe1d2571f4d36ae10
parent1a8420b775f36dadd47f848df412092858f8659c (diff)
downloadpoky-1b447bc1c9f5c9b6bd39e2ce2d24e78813422b5d.tar.gz
oprofile: Add ability to output XML callgraph information
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@1289 311d38ba-8fff-0310-9ca6-ca027cbcb966
-rw-r--r--meta/packages/oprofile/oprofile/xml_callgraph.patch759
-rw-r--r--meta/packages/oprofile/oprofile_cvs.bb3
2 files changed, 761 insertions, 1 deletions
diff --git a/meta/packages/oprofile/oprofile/xml_callgraph.patch b/meta/packages/oprofile/oprofile/xml_callgraph.patch
new file mode 100644
index 0000000000..0c2b567614
--- /dev/null
+++ b/meta/packages/oprofile/oprofile/xml_callgraph.patch
@@ -0,0 +1,759 @@
1Index: oprofile/libpp/callgraph_container.cpp
2===================================================================
3--- oprofile.orig/libpp/callgraph_container.cpp
4+++ oprofile/libpp/callgraph_container.cpp
5@@ -379,17 +379,19 @@ process(count_array_t total, double thre
6
7 process_children(sym, threshold);
8
9- cg_syms.push_back(sym);
10+ cg_syms_objs.push_back(sym);
11 }
12+
13+ for (unsigned int i = 0; i < cg_syms_objs.size(); i++)
14+ cg_syms.push_back(&cg_syms_objs[i]);
15 }
16
17
18-cg_collection arc_recorder::get_symbols() const
19+symbol_collection arc_recorder::get_symbols() const
20 {
21 return cg_syms;
22 }
23
24-
25 void callgraph_container::populate(string const & archive_path,
26 list<inverted_profile> const & iprofiles,
27 extra_images const & extra, bool debug_info, double threshold,
28@@ -580,12 +582,14 @@ column_flags callgraph_container::output
29 column_flags output_hints = cf_none;
30
31 // FIXME: costly: must we access directly recorder map ?
32- cg_collection syms = recorder.get_symbols();
33+ symbol_collection syms = recorder.get_symbols();
34
35- cg_collection::const_iterator it;
36- cg_collection::const_iterator const end = syms.end();
37- for (it = syms.begin(); it != end; ++it)
38- output_hints = it->output_hint(output_hints);
39+ symbol_collection::iterator it;
40+ symbol_collection::iterator const end = syms.end();
41+ for (it = syms.begin(); it != end; ++it) {
42+ cg_symbol const *cg_symb = dynamic_cast<const cg_symbol *>(*it);
43+ output_hints = cg_symb->output_hint(output_hints);
44+ }
45
46 return output_hints;
47 }
48@@ -597,7 +601,7 @@ count_array_t callgraph_container::sampl
49 }
50
51
52-cg_collection callgraph_container::get_symbols() const
53+symbol_collection callgraph_container::get_symbols() const
54 {
55 return recorder.get_symbols();
56 }
57Index: oprofile/libpp/callgraph_container.h
58===================================================================
59--- oprofile.orig/libpp/callgraph_container.h
60+++ oprofile/libpp/callgraph_container.h
61@@ -53,7 +53,7 @@ public:
62 count_array_t const & arc_count);
63
64 /// return all the cg symbols
65- cg_collection get_symbols() const;
66+ symbol_collection get_symbols() const;
67
68 /**
69 * After population, build the final output, and do
70@@ -91,7 +91,8 @@ private:
71 map_t sym_map;
72
73 /// final output data
74- cg_collection cg_syms;
75+ symbol_collection cg_syms;
76+ cg_collection_objs cg_syms_objs;
77 };
78
79
80@@ -126,7 +127,7 @@ public:
81 count_array_t samples_count() const;
82
83 // return all the cg symbols
84- cg_collection get_symbols() const;
85+ symbol_collection get_symbols() const;
86
87 private:
88 /**
89Index: oprofile/libpp/format_output.cpp
90===================================================================
91--- oprofile.orig/libpp/format_output.cpp
92+++ oprofile/libpp/format_output.cpp
93@@ -489,7 +489,7 @@ cg_formatter::cg_formatter(callgraph_con
94 }
95
96
97-void cg_formatter::output(ostream & out, cg_collection const & syms)
98+void cg_formatter::output(ostream & out, symbol_collection const & syms)
99 {
100 // amount of spacing prefixing child and parent lines
101 string const child_parent_prefix(" ");
102@@ -498,37 +498,37 @@ void cg_formatter::output(ostream & out,
103
104 out << string(79, '-') << endl;
105
106- cg_collection::const_iterator it;
107- cg_collection::const_iterator end = syms.end();
108+ symbol_collection::const_iterator it;
109+ symbol_collection::const_iterator end = syms.end();
110
111 for (it = syms.begin(); it < end; ++it) {
112- cg_symbol const & sym = *it;
113+ cg_symbol const *sym = dynamic_cast<const cg_symbol *>(*it);
114
115 cg_symbol::children::const_iterator cit;
116- cg_symbol::children::const_iterator cend = sym.callers.end();
117+ cg_symbol::children::const_iterator cend = sym->callers.end();
118
119 counts_t c;
120 if (global_percent)
121 c.total = counts.total;
122 else
123- c.total = sym.total_caller_count;
124+ c.total = sym->total_caller_count;
125
126- for (cit = sym.callers.begin(); cit != cend; ++cit) {
127+ for (cit = sym->callers.begin(); cit != cend; ++cit) {
128 out << child_parent_prefix;
129 do_output(out, *cit, cit->sample, c);
130 }
131
132- do_output(out, sym, sym.sample, counts);
133+ do_output(out, *sym, sym->sample, counts);
134
135 c = counts_t();
136 if (global_percent)
137 c.total = counts.total;
138 else
139- c.total = sym.total_callee_count;
140+ c.total = sym->total_callee_count;
141
142- cend = sym.callees.end();
143+ cend = sym->callees.end();
144
145- for (cit = sym.callees.begin(); cit != cend; ++cit) {
146+ for (cit = sym->callees.begin(); cit != cend; ++cit) {
147 out << child_parent_prefix;
148 do_output(out, *cit, cit->sample, c);
149 }
150@@ -562,6 +562,20 @@ ostringstream bytes_out;
151 map<string, size_t> symbol_data_table;
152 size_t symbol_data_index = 0;
153
154+/* Return any existing index or add to the table */
155+size_t xml_get_symbol_index(string const name)
156+{
157+ size_t index = symbol_data_index;
158+ map<string, size_t>::iterator it = symbol_data_table.find(name);
159+
160+ if (it == symbol_data_table.end()) {
161+ symbol_data_table[name] = symbol_data_index++;
162+ return index;
163+ }
164+
165+ return it->second;
166+}
167+
168
169 class symbol_details_t {
170 public:
171@@ -577,14 +591,15 @@ symbol_details_array_t symbol_details;
172 size_t detail_table_index = 0;
173
174 xml_formatter::
175-xml_formatter(profile_container const & p,
176+xml_formatter(profile_container const *p,
177 symbol_collection & s)
178 :
179 profile(p),
180 symbols(s),
181 need_details(false)
182 {
183- counts.total = profile.samples_count();
184+ if (profile)
185+ counts.total = profile->samples_count();
186 }
187
188
189@@ -640,12 +655,11 @@ void xml_formatter::output_symbol_data(o
190 string const image = get_image_name(symb->image_name, true);
191 string const qname = image + ":" + name;
192 map<string, size_t>::iterator sd_it = symbol_data_table.find(qname);
193- size_t si = xml_support->get_symbol_index(it);
194
195- if (sd_it->second == si) {
196+ if (sd_it != symbol_data_table.end()) {
197 // first time we've seen this symbol
198 out << open_element(SYMBOL_DATA, true);
199- out << init_attr(TABLE_ID, si);
200+ out << init_attr(TABLE_ID, sd_it->second);
201
202 field_datum datum(*symb, symb->sample, 0, counts);
203
204@@ -660,9 +674,12 @@ void xml_formatter::output_symbol_data(o
205 output_attribute(out, datum, ff_vma, STARTING_ADDR);
206
207 if (need_details)
208- xml_support->output_symbol_bytes(bytes_out, symb, si);
209+ xml_support->output_symbol_bytes(bytes_out, symb, sd_it->second);
210 }
211 out << close_element();
212+
213+ // seen so remove (otherwise get several "no symbols")
214+ symbol_data_table.erase(qname);
215 }
216 }
217 out << close_element(SYMBOL_TABLE);
218@@ -675,8 +692,8 @@ output_symbol_details(symbol_entry const
219 if (!has_sample_counts(symb->sample.counts, lo, hi))
220 return "";
221
222- sample_container::samples_iterator it = profile.begin(symb);
223- sample_container::samples_iterator end = profile.end(symb);
224+ sample_container::samples_iterator it = profile->begin(symb);
225+ sample_container::samples_iterator end = profile->end(symb);
226
227 ostringstream str;
228 for (; it != end; ++it) {
229@@ -725,10 +742,10 @@ output_symbol_details(symbol_entry const
230
231 void xml_formatter::
232 output_symbol(ostream & out,
233- symbol_collection::const_iterator const it, size_t lo, size_t hi)
234+ symbol_entry const * symb, size_t lo, size_t hi)
235 {
236- symbol_entry const * symb = *it;
237 ostringstream str;
238+ size_t indx;
239
240 // output symbol's summary data for each profile class
241 bool got_samples = false;
242@@ -750,27 +767,21 @@ output_symbol(ostream & out,
243
244 string const image = get_image_name(symb->image_name, true);
245 string const qname = image + ":" + name;
246- map<string, size_t>::iterator sd_it = symbol_data_table.find(qname);
247- size_t si = xml_support->get_symbol_index(it);
248
249- // if this is the first time we've seen this symbol, save it's index
250- if (sd_it == symbol_data_table.end())
251- symbol_data_table[qname] = si;
252- else
253- si = sd_it->second;
254+ indx = xml_get_symbol_index(qname);
255
256- out << init_attr(ID_REF, si);
257+ out << init_attr(ID_REF, indx);
258
259 if (need_details) {
260 ostringstream details;
261- symbol_details_t & sd = symbol_details[si];
262+ symbol_details_t & sd = symbol_details[indx];
263 size_t const detail_lo = sd.index;
264
265 string detail_str = output_symbol_details(symb, sd.index, lo, hi);
266
267 if (detail_str.size() > 0) {
268 if (sd.id < 0)
269- sd.id = si;
270+ sd.id = indx;
271 details << detail_str;
272 }
273
274@@ -826,5 +837,170 @@ output_attribute(ostream & out, field_da
275 }
276 }
277
278+xml_cg_formatter::
279+xml_cg_formatter(callgraph_container const * cg, symbol_collection & s)
280+ :
281+ xml_formatter(NULL, s),
282+ callgraph(cg)
283+{
284+ counts.total = callgraph->samples_count();
285+}
286+
287+void xml_cg_formatter::output(ostream & out)
288+{
289+ xml_support->build_subclasses(out);
290+
291+ xml_support->output_program_structure(out);
292+ output_symbol_data(out);
293+
294+ out << close_element(PROFILE);
295+}
296+
297+void xml_cg_formatter::
298+output_symbol_core(ostream & out,
299+ symbol_entry const * symb, size_t lo, size_t hi)
300+{
301+ cg_symbol const * cg_symb = dynamic_cast<const cg_symbol *>(symb);
302+ ostringstream str;
303+
304+ // output symbol's summary data for each profile class
305+ bool got_samples = false;
306+
307+ for (size_t p = lo; p <= hi; ++p) {
308+ got_samples |= xml_support->output_summary_data(str,
309+ symb->sample.counts, p);
310+ }
311+
312+ if (!got_samples)
313+ return;
314+
315+ cverb << vxml << " <!-- symbol_ref=" << symbol_names.name(symb->name) << " -->" << endl;
316+
317+ out << open_element(SYMBOL, true);
318+
319+ string const name = symbol_names.name(symb->name);
320+ assert(name.size() > 0);
321+
322+ string const image = get_image_name(symb->image_name, true);
323+ string const qname = image + ":" + name;
324+
325+ string const selfname = symbol_names.demangle(symb->name) + " [self]";
326+
327+ out << init_attr(ID_REF, xml_get_symbol_index(qname));
328+
329+ out << close_element(NONE, true);
330+
331+ out << open_element(CALLERS);
332+ if (cg_symb) {
333+ cg_symbol::children::const_iterator cit;
334+ cg_symbol::children::const_iterator cend = cg_symb->callers.end();
335+
336+ for (cit = cg_symb->callers.begin(); cit != cend; ++cit) {
337+ ostringstream str1;
338+ string binary = get_image_name((cit)->app_name, true);
339+ string module = get_image_name((cit)->image_name, true);
340+
341+
342+ got_samples = false;
343+
344+ for (size_t p = lo; p <= hi; ++p) {
345+ got_samples |= xml_support->output_summary_data(str1, cit->sample.counts, p);
346+ }
347+
348+ if (!got_samples)
349+ continue;
350+
351+ out << open_element(MODULE, true);
352+ out << init_attr(NAME, module) << close_element(NONE, true);
353+
354+ cverb << vxml << " <!-- symbol_ref=" << symbol_names.name(cit->name) << " -->" << endl;
355+
356+ out << open_element(SYMBOL, true);
357+
358+ string const name1 = symbol_names.name(cit->name);
359+ assert(name1.size() > 0);
360+
361+ string const qname1 = module + ":" + name1;
362+
363+ out << init_attr(ID_REF, xml_get_symbol_index(qname1));
364+
365+ out << close_element(NONE, true);
366+
367+ out << str1.str();
368+
369+ out << close_element(SYMBOL);
370+
371+ out << close_element(MODULE);
372+ }
373+ }
374+ out << close_element(CALLERS);
375+
376+ out << open_element(CALLEES);
377+ if (cg_symb) {
378+ cg_symbol::children::const_iterator cit;
379+ cg_symbol::children::const_iterator cend = cg_symb->callees.end();
380+
381+ for (cit = cg_symb->callees.begin(); cit != cend; ++cit) {
382+ size_t indx;
383+ ostringstream str1;
384+ string binary = get_image_name((cit)->app_name, true);
385+ string module = get_image_name((cit)->image_name, true);
386+ bool self = false;
387+
388+ got_samples = false;
389+
390+ for (size_t p = lo; p <= hi; ++p) {
391+ got_samples |= xml_support->output_summary_data(str1, cit->sample.counts, p);
392+ }
393+
394+ if (!got_samples)
395+ continue;
396+
397+ out << open_element(MODULE, true);
398+ out << init_attr(NAME, module) << close_element(NONE, true);
399+
400+ cverb << vxml << " <!-- symbol_ref=" << symbol_names.name(cit->name) << " -->" << endl;
401+
402+ out << open_element(SYMBOL, true);
403+
404+ string name1 = symbol_names.name(cit->name);
405+ assert(name1.size() > 0);
406+ string const qname1 = module + ":" + name1;
407+
408+ /* Find any self references and handle */
409+ if (name1 == selfname) {
410+ self = true;
411+ indx = xml_get_symbol_index(qname);
412+ } else
413+ indx = xml_get_symbol_index(qname1);
414+
415+ out << init_attr(ID_REF, indx);
416+
417+ if (self)
418+ out << init_attr(SELFREF, "true");
419+
420+ out << close_element(NONE, true);
421+
422+ out << str1.str();
423+
424+ out << close_element(SYMBOL);
425+
426+ out << close_element(MODULE);
427+ }
428+ }
429+ out << close_element(CALLEES);
430+
431+ // output summary
432+ out << str.str();
433+ out << close_element(SYMBOL);
434+}
435+
436+
437+void xml_cg_formatter::
438+output_symbol(ostream & out,
439+ symbol_entry const * symb, size_t lo, size_t hi)
440+{
441+ output_symbol_core(out, symb, lo, hi);
442+}
443
444 } // namespace format_output
445Index: oprofile/libpp/format_output.h
446===================================================================
447--- oprofile.orig/libpp/format_output.h
448+++ oprofile/libpp/format_output.h
449@@ -201,7 +201,7 @@ public:
450
451 /** output callgraph information according to the previously format
452 * specifier set by call(s) to add_format() */
453- void output(std::ostream & out, cg_collection const & syms);
454+ void output(std::ostream & out, symbol_collection const & syms);
455 };
456
457 /// class to output a columned format symbols plus diff values
458@@ -227,7 +227,7 @@ private:
459 class xml_formatter : public formatter {
460 public:
461 /// build a ready to use formatter
462- xml_formatter(profile_container const & profile,
463+ xml_formatter(profile_container const * profile,
464 symbol_collection & symbols);
465
466 // output body of XML output
467@@ -235,9 +235,8 @@ public:
468
469 /** output one symbol symb to out according to the output format
470 * specifier previously set by call(s) to add_format() */
471- void output_symbol(std::ostream & out,
472- symbol_collection::const_iterator const it,
473- size_t lo, size_t hi);
474+ virtual void output_symbol(std::ostream & out,
475+ symbol_entry const * symb, size_t lo, size_t hi);
476
477 /// output details for the symbol
478 std::string output_symbol_details(symbol_entry const * symb,
479@@ -246,9 +245,12 @@ public:
480 /// set the output_details boolean
481 void show_details(bool);
482
483+ // output SymbolData XML elements
484+ void output_symbol_data(std::ostream & out);
485+
486 private:
487 /// container we work from
488- profile_container const & profile;
489+ profile_container const * profile;
490
491 // ordered collection of symbols associated with this profile
492 symbol_collection & symbols;
493@@ -256,9 +258,6 @@ private:
494 /// true if we need to show details for each symbols
495 bool need_details;
496
497- // output SymbolData XML elements
498- void output_symbol_data(std::ostream & out);
499-
500 // count of DetailData items output so far
501 size_t detail_count;
502
503@@ -270,6 +269,28 @@ private:
504 format_flags fl, tag_t tag);
505 };
506
507+// callgraph XML output version
508+class xml_cg_formatter : public xml_formatter {
509+public:
510+ /// build a ready to use formatter
511+ xml_cg_formatter(callgraph_container const * callgraph,
512+ symbol_collection & symbols);
513+
514+ // output body of XML output
515+ void output(std::ostream & out);
516+
517+ /** output one symbol symb to out according to the output format
518+ * specifier previously set by call(s) to add_format() */
519+ virtual void output_symbol(std::ostream & out,
520+ symbol_entry const * symb, size_t lo, size_t hi);
521+
522+private:
523+ /// container we work from
524+ callgraph_container const * callgraph;
525+
526+ void output_symbol_core(std::ostream & out,
527+ symbol_entry const * symb, size_t lo, size_t hi);
528+};
529
530 } // namespace format_output
531
532Index: oprofile/libpp/symbol.h
533===================================================================
534--- oprofile.orig/libpp/symbol.h
535+++ oprofile/libpp/symbol.h
536@@ -55,8 +55,11 @@ struct sample_entry {
537
538
539 /// associate a symbol with a file location, samples count and vma address
540-struct symbol_entry {
541+class symbol_entry {
542+public:
543 symbol_entry() : size(0) {}
544+ virtual ~symbol_entry() {}
545+
546 /// which image this symbol belongs to
547 image_name_id image_name;
548 /// owning application name: identical to image name if profiling
549@@ -92,7 +95,8 @@ typedef std::vector<symbol_entry const *
550 * the sample counts replaced with the relevant arc counts, whilst
551 * the cg_symbol retains its self count.
552 */
553-struct cg_symbol : public symbol_entry {
554+class cg_symbol : public symbol_entry {
555+public:
556 cg_symbol(symbol_entry const & sym) : symbol_entry(sym) {}
557
558 typedef std::vector<symbol_entry> children;
559@@ -108,9 +112,12 @@ struct cg_symbol : public symbol_entry {
560 count_array_t total_callee_count;
561 };
562
563+/// a collection of sorted callgraph symbols (the objects themselves)
564+typedef std::vector<cg_symbol> cg_collection_objs;
565+
566
567-/// a collection of sorted callgraph symbols
568-typedef std::vector<cg_symbol> cg_collection;
569+/// a collection of sorted callgraph symbols (pointers too, compatible with symbol_collection)
570+//typedef std::vector<cg_symbol const *> cg_collection;
571
572
573 /// for storing diff %ages
574Index: oprofile/libpp/symbol_sort.cpp
575===================================================================
576--- oprofile.orig/libpp/symbol_sort.cpp
577+++ oprofile/libpp/symbol_sort.cpp
578@@ -146,23 +146,6 @@ sort(symbol_collection & syms, bool reve
579
580
581 void sort_options::
582-sort(cg_collection & syms, bool reverse_sort, bool lf) const
583-{
584- long_filenames = lf;
585-
586- vector<sort_order> sort_option(options);
587- for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) {
588- if (find(sort_option.begin(), sort_option.end(), cur) ==
589- sort_option.end())
590- sort_option.push_back(cur);
591- }
592-
593- stable_sort(syms.begin(), syms.end(),
594- symbol_compare(sort_option, reverse_sort));
595-}
596-
597-
598-void sort_options::
599 sort(diff_collection & syms, bool reverse_sort, bool lf) const
600 {
601 long_filenames = lf;
602Index: oprofile/libpp/symbol_sort.h
603===================================================================
604--- oprofile.orig/libpp/symbol_sort.h
605+++ oprofile/libpp/symbol_sort.h
606@@ -44,12 +44,6 @@ struct sort_options {
607 /**
608 * Sort the given container by the given criteria.
609 */
610- void sort(cg_collection & syms, bool reverse_sort,
611- bool long_filenames) const;
612-
613- /**
614- * Sort the given container by the given criteria.
615- */
616 void sort(diff_collection & syms, bool reverse_sort,
617 bool long_filenames) const;
618
619Index: oprofile/libpp/xml_utils.cpp
620===================================================================
621--- oprofile.orig/libpp/xml_utils.cpp
622+++ oprofile/libpp/xml_utils.cpp
623@@ -257,13 +257,6 @@ void xml_utils::output_xml_header(string
624 cout << close_element(SETUP) << endl;
625 }
626
627-size_t xml_utils::get_symbol_index(sym_iterator const it)
628-{
629- return it - symbols_begin;
630-}
631-
632-
633-
634 class subclass_info_t {
635 public:
636 string unitmask;
637@@ -589,7 +582,7 @@ void module_info::output_summary(ostream
638 void module_info::output_symbols(ostream & out)
639 {
640 for (sym_iterator it = begin; it != end; ++it)
641- xml_out->output_symbol(out, it, lo, hi);
642+ xml_out->output_symbol(out, *it, lo, hi);
643 }
644
645
646Index: oprofile/libutil++/xml_output.cpp
647===================================================================
648--- oprofile.orig/libutil++/xml_output.cpp
649+++ oprofile/libutil++/xml_output.cpp
650@@ -47,8 +47,11 @@ string const xml_tag_map[] = {
651 "binary",
652 "module",
653 "name",
654+ "callers",
655+ "callees",
656 "symbol",
657 "idref",
658+ "self",
659 "detaillo",
660 "detailhi",
661 "symboltable",
662Index: oprofile/libutil++/xml_output.h
663===================================================================
664--- oprofile.orig/libutil++/xml_output.h
665+++ oprofile/libutil++/xml_output.h
666@@ -28,7 +28,8 @@ typedef enum {
667 THREAD, THREAD_ID,
668 BINARY,
669 MODULE, NAME,
670- SYMBOL, ID_REF, DETAIL_LO, DETAIL_HI,
671+ CALLERS, CALLEES,
672+ SYMBOL, ID_REF, SELFREF, DETAIL_LO, DETAIL_HI,
673 SYMBOL_TABLE,
674 SYMBOL_DATA, STARTING_ADDR,
675 SOURCE_FILE, SOURCE_LINE, CODE_LENGTH,
676Index: oprofile/pp/opreport.cpp
677===================================================================
678--- oprofile.orig/pp/opreport.cpp
679+++ oprofile/pp/opreport.cpp
680@@ -378,7 +378,7 @@ void output_symbols(profile_container co
681 format_output::opreport_formatter * text_out = 0;
682
683 if (options::xml) {
684- xml_out = new format_output::xml_formatter(pc, symbols);
685+ xml_out = new format_output::xml_formatter(&pc, symbols);
686 xml_out->show_details(options::details);
687 out = xml_out;
688 // for XML always output long filenames
689@@ -445,25 +445,45 @@ void output_cg_symbols(callgraph_contain
690 {
691 column_flags output_hints = cg.output_hint();
692
693- cg_collection symbols = cg.get_symbols();
694+ symbol_collection symbols = cg.get_symbols();
695+
696 options::sort_by.sort(symbols, options::reverse_sort,
697 options::long_filenames);
698
699- format_output::cg_formatter out(cg);
700+ format_output::formatter * out;
701+ format_output::xml_cg_formatter * xml_out = 0;
702+ format_output::cg_formatter * text_out = 0;
703
704- out.set_nr_classes(nr_classes);
705- out.show_long_filenames(options::long_filenames);
706- out.show_header(options::show_header);
707- out.vma_format_64bit(output_hints & cf_64bit_vma);
708- out.show_global_percent(options::global_percent);
709+ if (options::xml) {
710+ xml_out = new format_output::xml_cg_formatter(&cg, symbols);
711+ out = xml_out;
712+ // for XML always output long filenames
713+ out->show_long_filenames(true);
714+ } else {
715+ text_out = new format_output::cg_formatter(cg);
716+ out = text_out;
717+ out->show_long_filenames(options::long_filenames);
718+ }
719+
720+ out->set_nr_classes(nr_classes);
721+ out->show_header(options::show_header);
722+ out->vma_format_64bit(output_hints & cf_64bit_vma);
723+ out->show_global_percent(options::global_percent);
724
725 format_flags flags = get_format_flags(output_hints);
726 if (multiple_apps)
727 flags = format_flags(flags | ff_app_name);
728
729- out.add_format(flags);
730+ out->add_format(flags);
731+
732+ if (options::xml) {
733+ xml_support = new xml_utils(xml_out, symbols, nr_classes,
734+ &options::symbol_filter, options::archive_path);
735+ xml_out->output(cout);
736+ } else {
737+ text_out->output(cout, symbols);
738+ }
739
740- out.output(cout, symbols);
741 }
742
743
744Index: oprofile/pp/opreport_options.cpp
745===================================================================
746--- oprofile.orig/pp/opreport_options.cpp
747+++ oprofile/pp/opreport_options.cpp
748@@ -177,11 +177,6 @@ void check_options(bool diff)
749 }
750
751 if (xml) {
752- if (callgraph) {
753- cerr << "--callgraph is incompatible with --xml" << endl;
754- do_exit = true;
755- }
756-
757 if (accumulated) {
758 cerr << "--accumulated is incompatible with --xml" << endl;
759 do_exit = true;
diff --git a/meta/packages/oprofile/oprofile_cvs.bb b/meta/packages/oprofile/oprofile_cvs.bb
index 3b9eae9110..a085cc41de 100644
--- a/meta/packages/oprofile/oprofile_cvs.bb
+++ b/meta/packages/oprofile/oprofile_cvs.bb
@@ -1,5 +1,5 @@
1PV = "0.9.2+cvs${SRCDATE}" 1PV = "0.9.2+cvs${SRCDATE}"
2PR = "r1" 2PR = "r2"
3SECTION = "devel" 3SECTION = "devel"
4DESCRIPTION = "OProfile is a system-wide profiler for Linux systems, capable \ 4DESCRIPTION = "OProfile is a system-wide profiler for Linux systems, capable \
5of profiling all running code at low overhead." 5of profiling all running code at low overhead."
@@ -11,6 +11,7 @@ SRC_URI = "cvs://anonymous@oprofile.cvs.sourceforge.net/cvsroot/oprofile;module=
11 file://oparchive-debug-dir.patch;patch=1 \ 11 file://oparchive-debug-dir.patch;patch=1 \
12 file://oparchive-list-files.patch;patch=1 \ 12 file://oparchive-list-files.patch;patch=1 \
13 file://opreport-xml-output-fixes.patch;patch=1 \ 13 file://opreport-xml-output-fixes.patch;patch=1 \
14 file://xml_callgraph.patch;patch=1 \
14 file://acinclude.m4" 15 file://acinclude.m4"
15S = "${WORKDIR}/oprofile" 16S = "${WORKDIR}/oprofile"
16 17