| /** |
| * @file populate.cpp |
| * Fill up a profile_container from inverted profiles |
| * |
| * @remark Copyright 2003 OProfile authors |
| * @remark Read the file COPYING |
| * |
| * @author John Levon |
| * @author Philippe Elie |
| * |
| * Modified by Maynard Johnson <maynardj@us.ibm.com> |
| * (C) Copyright IBM Corporation 2007 |
| */ |
| |
| #include "profile.h" |
| #include "profile_container.h" |
| #include "arrange_profiles.h" |
| #include "op_bfd.h" |
| #include "op_header.h" |
| #include "populate.h" |
| #include "populate_for_spu.h" |
| |
| #include "image_errors.h" |
| |
| #include <iostream> |
| |
| using namespace std; |
| |
| namespace { |
| |
| /// load merged files for one set of sample files |
| bool |
| populate_from_files(profile_t & profile, op_bfd const & abfd, |
| list<profile_sample_files> const & files) |
| { |
| list<profile_sample_files>::const_iterator it = files.begin(); |
| list<profile_sample_files>::const_iterator const end = files.end(); |
| |
| bool found = false; |
| // we can't handle cg files here obviously |
| for (; it != end; ++it) { |
| // A bit ugly but we must accept silently empty sample filename |
| // since we can create a profile_sample_files for cg file only |
| // (i.e no sample to the binary) |
| if (!it->sample_filename.empty()) { |
| profile.add_sample_file(it->sample_filename); |
| profile.set_offset(abfd); |
| found = true; |
| } |
| } |
| |
| return found; |
| } |
| |
| } // anon namespace |
| |
| |
| void |
| populate_for_image(profile_container & samples, inverted_profile const & ip, |
| string_filter const & symbol_filter, bool * has_debug_info) |
| { |
| if (is_spu_profile(ip)) { |
| populate_for_spu_image(samples, ip, symbol_filter, |
| has_debug_info); |
| return; |
| } |
| |
| bool ok = ip.error == image_ok; |
| op_bfd abfd(ip.image, symbol_filter, |
| samples.extra_found_images, ok); |
| if (!ok && ip.error == image_ok) |
| ip.error = image_format_failure; |
| |
| if (ip.error == image_format_failure) |
| report_image_error(ip, false, samples.extra_found_images); |
| |
| opd_header header; |
| |
| bool found = false; |
| for (size_t i = 0; i < ip.groups.size(); ++i) { |
| list<image_set>::const_iterator it |
| = ip.groups[i].begin(); |
| list<image_set>::const_iterator const end |
| = ip.groups[i].end(); |
| |
| // we can only share a profile_t amongst each |
| // image_set's files - this is because it->app_image |
| // changes, and the .add() would mis-attribute |
| // to the wrong app_image otherwise |
| for (; it != end; ++it) { |
| profile_t profile; |
| if (populate_from_files(profile, abfd, it->files)) { |
| header = profile.get_header(); |
| samples.add(profile, abfd, it->app_image, i); |
| found = true; |
| } |
| } |
| } |
| |
| if (found == true && ip.error == image_ok) { |
| image_error error; |
| string filename = |
| samples.extra_found_images.find_image_path( |
| ip.image, error, true); |
| check_mtime(filename, header); |
| } |
| |
| if (has_debug_info) |
| *has_debug_info = abfd.has_debug_info(); |
| } |