| /** |
| * @file opannotate_options.cpp |
| * Options for opannotate tool |
| * |
| * @remark Copyright 2003 OProfile authors |
| * @remark Read the file COPYING |
| * |
| * @author John Levon |
| * @author Philippe Elie |
| */ |
| |
| #include <cstdlib> |
| |
| #include <vector> |
| #include <list> |
| #include <iterator> |
| #include <iostream> |
| #include <cstdlib> |
| |
| #include "profile_spec.h" |
| #include "arrange_profiles.h" |
| #include "op_exception.h" |
| #include "opannotate_options.h" |
| #include "popt_options.h" |
| #include "cverb.h" |
| |
| using namespace std; |
| |
| profile_classes classes; |
| |
| namespace options { |
| demangle_type demangle = dmt_normal; |
| string output_dir; |
| vector<string> search_dirs; |
| vector<string> base_dirs; |
| merge_option merge_by; |
| path_filter file_filter; |
| string_filter symbol_filter; |
| bool source; |
| bool assembly; |
| vector<string> objdump_params; |
| bool exclude_dependent; |
| } |
| |
| |
| namespace { |
| |
| string include_symbols; |
| string exclude_symbols; |
| string include_file; |
| string exclude_file; |
| string demangle_option = "normal"; |
| vector<string> mergespec; |
| |
| popt::option options_array[] = { |
| popt::option(demangle_option, "demangle", 'D', |
| "demangle GNU C++ symbol names (default normal)", |
| "none|normal|smart"), |
| popt::option(options::output_dir, "output-dir", 'o', |
| "output directory", "directory name"), |
| popt::option(options::search_dirs, "search-dirs", 'd', |
| "directories to look for source files", "comma-separated paths"), |
| popt::option(options::base_dirs, "base-dirs", 'b', |
| "source file prefixes to strip", "comma-separated paths"), |
| popt::option(include_file, "include-file", '\0', |
| "include these comma separated filename", "filenames"), |
| popt::option(exclude_file, "exclude-file", '\0', |
| "exclude these comma separated filename", "filenames"), |
| popt::option(include_symbols, "include-symbols", 'i', |
| "include these comma separated symbols", "symbols"), |
| popt::option(exclude_symbols, "exclude-symbols", 'e', |
| "exclude these comma separated symbols", "symbols"), |
| popt::option(options::objdump_params, "objdump-params", '\0', |
| "additional params to pass to objdump", "parameters"), |
| popt::option(options::exclude_dependent, "exclude-dependent", 'x', |
| "exclude libs, kernel, and module samples for applications"), |
| popt::option(mergespec, "merge", 'm', |
| "comma separated list", "cpu,tid,tgid,unitmask,all"), |
| popt::option(options::source, "source", 's', "output source"), |
| popt::option(options::assembly, "assembly", 'a', "output assembly"), |
| popt::option(options::threshold_opt, "threshold", 't', |
| "minimum percentage needed to produce output", |
| "percent"), |
| }; |
| |
| } // anonymous namespace |
| |
| |
| void handle_options(options::spec const & spec) |
| { |
| using namespace options; |
| |
| if (spec.first.size()) { |
| cerr << "differential profiles not allowed" << endl; |
| exit(EXIT_FAILURE); |
| } |
| |
| if (!assembly && !source) { |
| cerr << "you must specify at least --source or --assembly\n"; |
| exit(EXIT_FAILURE); |
| } |
| |
| if (!objdump_params.empty() && !assembly) { |
| cerr << "--objdump-params is meaningless without --assembly\n"; |
| exit(EXIT_FAILURE); |
| } |
| |
| if (search_dirs.empty() && !base_dirs.empty()) { |
| cerr << "--base-dirs is useless unless you specify an " |
| "alternative source location with --search-dirs" |
| << endl; |
| exit(EXIT_FAILURE); |
| } |
| |
| if (assembly && !output_dir.empty()) { |
| cerr << "--output-dir is meaningless with --assembly" << endl; |
| exit(EXIT_FAILURE); |
| } |
| |
| options::symbol_filter = string_filter(include_symbols, exclude_symbols); |
| |
| options::file_filter = path_filter(include_file, exclude_file); |
| |
| profile_spec const pspec = |
| profile_spec::create(spec.common, options::image_path, |
| options::root_path); |
| |
| list<string> sample_files = pspec.generate_file_list(exclude_dependent, true); |
| |
| cverb << vsfile << "Archive: " << pspec.get_archive_path() << endl; |
| |
| cverb << vsfile << "Matched sample files: " << sample_files.size() |
| << endl; |
| copy(sample_files.begin(), sample_files.end(), |
| ostream_iterator<string>(cverb << vsfile, "\n")); |
| |
| demangle = handle_demangle_option(demangle_option); |
| |
| // we always merge but this have no effect on output since at source |
| // or assembly point of view the result will be merged anyway |
| merge_by = handle_merge_option(mergespec, false, exclude_dependent); |
| |
| classes = arrange_profiles(sample_files, merge_by, |
| pspec.extra_found_images); |
| |
| cverb << vsfile << "profile_classes:\n" << classes << endl; |
| |
| if (classes.v.empty()) { |
| cerr << "error: no sample files found: profile specification " |
| "too strict ?" << endl; |
| exit(EXIT_FAILURE); |
| } |
| } |