1/** 2 * @file libpp/populate_for_spu.cpp 3 * Fill up a profile_container from inverted profiles for 4 * a Cell BE SPU profile 5 * 6 * @remark Copyright 2007 OProfile authors 7 * @remark Read the file COPYING 8 * 9 * @author Maynard Johnson 10 * (C) Copyright IBM Corporation 2007 11 */ 12 13#include "profile.h" 14#include "profile_container.h" 15#include "arrange_profiles.h" 16#include "op_bfd.h" 17#include "op_header.h" 18#include "populate.h" 19#include "populate_for_spu.h" 20 21#include "image_errors.h" 22 23#include <iostream> 24 25using namespace std; 26 27namespace { 28 29static int spu_profile = unknown_profile; 30 31/* 32 * On Cell Broadband Engine, an application executing on an SPE may 33 * have been loaded from a separate SPU executable binary file or may 34 * have been loaded from an embedded section of a PPE application or 35 * shared library. In the embedded case, the embedding file may actually 36 * contain multiple SPU images, resulting in different SPU images being loaded 37 * onto different SPUs. Thus, the SPUs may be executing different code, even 38 * though the application of the parent PPE process is the same. Therefore, 39 * we must be sure to create a separate op_bfd object for each SPU. When doing 40 * so below, we examine header.embedded_offset. If embedded_offset is > 0, it's 41 * interpreted as the offset of an SPU image embedded in the containing file, 42 * so the filename to do the check_mtime on is the containing file, ip.image; 43 * otherwise, the filename to do the check_mtime on is the separate backing 44 * file of the SPU image, abfd->filename. 45 */ 46void 47populate_spu_profile_from_files(list<profile_sample_files> const & files, 48 string const app_image, 49 profile_container & samples, 50 inverted_profile const & ip, 51 string_filter const & symbol_filter, 52 size_t ip_grp_num, bool * has_debug_info) 53{ 54 string archive_path = samples.extra_found_images.get_archive_path(); 55 bool ok = ip.error == image_ok; 56 op_bfd * abfd = NULL; 57 string fname_to_check; 58 list<profile_sample_files>::const_iterator it = files.begin(); 59 list<profile_sample_files>::const_iterator const end = files.end(); 60 for (; it != end; ++it) { 61 profile_t profile; 62 if (it->sample_filename.empty()) 63 continue; 64 65 profile.add_sample_file(it->sample_filename); 66 opd_header header = profile.get_header(); 67 if (header.embedded_offset) { 68 abfd = new op_bfd(header.embedded_offset, 69 ip.image, 70 symbol_filter, 71 samples.extra_found_images, 72 ok); 73 fname_to_check = ip.image; 74 } else { 75 abfd = new op_bfd(ip.image, 76 symbol_filter, 77 samples.extra_found_images, 78 ok); 79 fname_to_check = abfd->get_filename(); 80 } 81 profile.set_offset(*abfd); 82 if (!ok && ip.error == image_ok) 83 ip.error = image_format_failure; 84 85 if (ip.error == image_format_failure) 86 report_image_error(ip, false, 87 samples.extra_found_images); 88 89 samples.add(profile, *abfd, app_image, ip_grp_num); 90 if (ip.error == image_ok) { 91 image_error error; 92 string filename = 93 samples.extra_found_images.find_image_path( 94 fname_to_check, error, true); 95 check_mtime(filename, profile.get_header()); 96 } 97 98 if (has_debug_info && !*has_debug_info) 99 *has_debug_info = abfd->has_debug_info(); 100 delete abfd; 101 } 102} 103} // anon namespace 104 105void 106populate_for_spu_image(profile_container & samples, 107 inverted_profile const & ip, 108 string_filter const & symbol_filter, 109 bool * has_debug_info) 110{ 111 112 for (size_t i = 0; i < ip.groups.size(); ++i) { 113 list < image_set >::const_iterator it= 114 ip.groups[i].begin(); 115 list < image_set >::const_iterator const end 116 = ip.groups[i].end(); 117 118 for (; it != end; ++it) 119 populate_spu_profile_from_files(it->files, 120 it->app_image, samples, ip, 121 symbol_filter, i, has_debug_info); 122 } 123} 124 125bool is_spu_profile(inverted_profile const & ip) 126{ 127 bool retval = false; 128 string sfname = ""; 129 if (spu_profile != unknown_profile) 130 return spu_profile; 131 132 if (!ip.groups.size()) 133 return false; 134 135 for (size_t i = 0; i < ip.groups.size(); ++i) { 136 list<image_set>::const_iterator grp_it 137 = ip.groups[i].begin(); 138 list<image_set>::const_iterator const grp_end 139 = ip.groups[i].end(); 140 141 for (; grp_it != grp_end; ++grp_it) { 142 list<profile_sample_files>::const_iterator sfiles_it = 143 grp_it->files.begin(); 144 list<profile_sample_files>::const_iterator sfiles_end = 145 grp_it->files.end(); 146 for (; sfiles_it != sfiles_end; ++sfiles_it) { 147 if (!sfiles_it->sample_filename.empty()) { 148 sfname = sfiles_it->sample_filename; 149 goto do_check; 150 } 151 } 152 } 153 } 154 goto out; 155 156do_check: 157 spu_profile = profile_t::is_spu_sample_file(sfname); 158 159 if (spu_profile == cell_spu_profile) 160 retval = true; 161 162out: 163 return retval; 164} 165 166 167