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
27using namespace std;
28
29profile_classes classes;
30
31namespace 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
46namespace {
47
48string include_symbols;
49string exclude_symbols;
50string include_file;
51string exclude_file;
52string demangle_option = "normal";
53vector<string> mergespec;
54
55popt::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
89void 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