• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
25 using namespace std;
26 
27 namespace {
28 
29 static 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  */
46 void
populate_spu_profile_from_files(list<profile_sample_files> const & files,string const app_image,profile_container & samples,inverted_profile const & ip,string_filter const & symbol_filter,size_t ip_grp_num,bool * has_debug_info)47 populate_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 
105 void
populate_for_spu_image(profile_container & samples,inverted_profile const & ip,string_filter const & symbol_filter,bool * has_debug_info)106 populate_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 
is_spu_profile(inverted_profile const & ip)125 bool 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 
156 do_check:
157 	spu_profile = profile_t::is_spu_sample_file(sfname);
158 
159 	if (spu_profile == cell_spu_profile)
160 		retval = true;
161 
162 out:
163 	return retval;
164 }
165 
166 
167