Home | History | Annotate | Download | only in pp
      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 
     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