• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * @file opannotate_options.cpp
3  * Options for opannotate tool
4  *
5  * @remark Copyright 2003 OProfile authors
6  * @remark Read the file COPYING
7  *
8  * @author John Levon
9  * @author Philippe Elie
10  */
11 
12 #include <cstdlib>
13 
14 #include <vector>
15 #include <list>
16 #include <iterator>
17 #include <iostream>
18 #include <cstdlib>
19 
20 #include "profile_spec.h"
21 #include "arrange_profiles.h"
22 #include "op_exception.h"
23 #include "opannotate_options.h"
24 #include "popt_options.h"
25 #include "cverb.h"
26 
27 using namespace std;
28 
29 profile_classes classes;
30 
31 namespace options {
32 	demangle_type demangle = dmt_normal;
33 	string output_dir;
34 	vector<string> search_dirs;
35 	vector<string> base_dirs;
36 	merge_option merge_by;
37 	path_filter file_filter;
38 	string_filter symbol_filter;
39 	bool source;
40 	bool assembly;
41 	vector<string> objdump_params;
42 	bool exclude_dependent;
43 }
44 
45 
46 namespace {
47 
48 string include_symbols;
49 string exclude_symbols;
50 string include_file;
51 string exclude_file;
52 string demangle_option = "normal";
53 vector<string> mergespec;
54 
55 popt::option options_array[] = {
56 	popt::option(demangle_option, "demangle", 'D',
57 		     "demangle GNU C++ symbol names (default normal)",
58 	             "none|normal|smart"),
59 	popt::option(options::output_dir, "output-dir", 'o',
60 		     "output directory", "directory name"),
61 	popt::option(options::search_dirs, "search-dirs", 'd',
62 	             "directories to look for source files", "comma-separated paths"),
63 	popt::option(options::base_dirs, "base-dirs", 'b',
64 	             "source file prefixes to strip", "comma-separated paths"),
65 	popt::option(include_file, "include-file", '\0',
66 		     "include these comma separated filename", "filenames"),
67 	popt::option(exclude_file, "exclude-file", '\0',
68 		     "exclude these comma separated filename", "filenames"),
69 	popt::option(include_symbols, "include-symbols", 'i',
70 		     "include these comma separated symbols", "symbols"),
71 	popt::option(exclude_symbols, "exclude-symbols", 'e',
72 		     "exclude these comma separated symbols", "symbols"),
73 	popt::option(options::objdump_params, "objdump-params", '\0',
74 		     "additional params to pass to objdump", "parameters"),
75 	popt::option(options::exclude_dependent, "exclude-dependent", 'x',
76 		     "exclude libs, kernel, and module samples for applications"),
77 	popt::option(mergespec, "merge", 'm',
78 		     "comma separated list", "cpu,tid,tgid,unitmask,all"),
79 	popt::option(options::source, "source", 's', "output source"),
80 	popt::option(options::assembly, "assembly", 'a', "output assembly"),
81 	popt::option(options::threshold_opt, "threshold", 't',
82 		     "minimum percentage needed to produce output",
83 		     "percent"),
84 };
85 
86 }  // anonymous namespace
87 
88 
handle_options(options::spec const & spec)89 void handle_options(options::spec const & spec)
90 {
91 	using namespace options;
92 
93 	if (spec.first.size()) {
94 		cerr << "differential profiles not allowed" << endl;
95 		exit(EXIT_FAILURE);
96 	}
97 
98 	if (!assembly && !source) {
99 		cerr <<	"you must specify at least --source or --assembly\n";
100 		exit(EXIT_FAILURE);
101 	}
102 
103 	if (!objdump_params.empty() && !assembly) {
104 		cerr << "--objdump-params is meaningless without --assembly\n";
105 		exit(EXIT_FAILURE);
106 	}
107 
108 	if (search_dirs.empty() && !base_dirs.empty()) {
109 		cerr << "--base-dirs is useless unless you specify an "
110 			"alternative source location with --search-dirs"
111 		     << endl;
112 		exit(EXIT_FAILURE);
113 	}
114 
115 	if (assembly && !output_dir.empty()) {
116 		cerr << "--output-dir is meaningless with --assembly" << endl;
117 		exit(EXIT_FAILURE);
118 	}
119 
120 	options::symbol_filter = string_filter(include_symbols, exclude_symbols);
121 
122 	options::file_filter = path_filter(include_file, exclude_file);
123 
124 	profile_spec const pspec =
125 		profile_spec::create(spec.common, options::image_path,
126 				     options::root_path);
127 
128 	list<string> sample_files = pspec.generate_file_list(exclude_dependent, true);
129 
130 	cverb << vsfile << "Archive: " << pspec.get_archive_path() << endl;
131 
132 	cverb << vsfile << "Matched sample files: " << sample_files.size()
133 	      << endl;
134 	copy(sample_files.begin(), sample_files.end(),
135 	     ostream_iterator<string>(cverb << vsfile, "\n"));
136 
137 	demangle = handle_demangle_option(demangle_option);
138 
139 	// we always merge but this have no effect on output since at source
140 	// or assembly point of view the result will be merged anyway
141 	merge_by = handle_merge_option(mergespec, false, exclude_dependent);
142 
143 	classes = arrange_profiles(sample_files, merge_by,
144 				   pspec.extra_found_images);
145 
146 	cverb << vsfile << "profile_classes:\n" << classes << endl;
147 
148 	if (classes.v.empty()) {
149 		cerr << "error: no sample files found: profile specification "
150 		     "too strict ?" << endl;
151 		exit(EXIT_FAILURE);
152 	}
153 }
154