1 // Copyright 2015 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 #include "perf_option_parser.h" 5 6 #include <algorithm> 7 #include <map> 8 9 #include "compat/string.h" 10 11 namespace quipper { 12 13 namespace { 14 15 enum class OptionType { 16 Boolean, // has no value 17 Value, // Uses another argument. 18 }; 19 20 const std::map<string, OptionType>& GetPerfRecordOptions() { 21 static const auto* kPerfRecordOptions = new std::map<string, OptionType>{ 22 {"-e", OptionType::Value}, 23 {"--event", OptionType::Value}, 24 {"--filter", OptionType::Value}, 25 {"-p", OptionType::Value}, 26 {"--pid", OptionType::Value}, 27 {"-t", OptionType::Value}, 28 {"--tid", OptionType::Value}, 29 {"-r", OptionType::Value}, 30 {"--realtime", OptionType::Value}, 31 /* Banned: {"--no-buffering", OptionType::Boolean}, */ 32 {"-R", OptionType::Boolean}, 33 {"--raw-samples", OptionType::Boolean}, 34 {"-a", OptionType::Boolean}, 35 {"--all-cpus", OptionType::Boolean}, 36 {"-C", OptionType::Value}, 37 {"--cpu", OptionType::Value}, 38 {"-c", OptionType::Value}, 39 {"--count", OptionType::Value}, 40 /* Banned: {"-o", OptionType::Value}, 41 * {"--output", OptionType::Value}, */ 42 {"-i", OptionType::Boolean}, 43 {"--no-inherit", OptionType::Boolean}, 44 {"-F", OptionType::Value}, 45 {"--freq", OptionType::Value}, 46 /* Banned: {"-m", OptionType::Value}, 47 * {"--mmap-pages", OptionType::Value}, */ 48 {"--group", OptionType::Boolean}, /* new? */ 49 {"-g", OptionType::Boolean}, /* NB: in stat, this is short for --group */ 50 {"--call-graph", OptionType::Value}, 51 /* Banned: {"-v", OptionType::Boolean}, 52 * {"--verbose", OptionType::Boolean}, */ 53 /* Banned: {"-q", OptionType::Boolean}, 54 * {"--quiet", OptionType::Boolean}, */ 55 {"-s", OptionType::Boolean}, 56 {"--stat", OptionType::Boolean}, 57 {"-d", OptionType::Boolean}, 58 {"--data", OptionType::Boolean}, 59 {"-T", OptionType::Boolean}, 60 {"--timestamp", OptionType::Boolean}, 61 {"-P", OptionType::Boolean}, /* new? */ 62 {"--period", OptionType::Boolean}, /* new? */ 63 {"-n", OptionType::Boolean}, 64 {"--no-samples", OptionType::Boolean}, 65 {"-N", OptionType::Boolean}, 66 {"--no-buildid-cache", OptionType::Boolean}, 67 {"-B", OptionType::Boolean}, /* new? */ 68 {"--no-buildid", OptionType::Boolean}, /* new? */ 69 {"-G", OptionType::Value}, 70 {"--cgroup", OptionType::Value}, 71 /* Changed between v3.13 to v3.14 from: 72 {"-D", OptionType::Boolean}, 73 {"--no-delay", OptionType::Boolean}, 74 * to: 75 {"-D", OptionType::Value}, 76 {"--delay", OptionType::Value}, 77 * ... So just ban it until the new option is universal on ChromeOS perf. 78 */ 79 {"-u", OptionType::Value}, 80 {"--uid", OptionType::Value}, 81 {"-b", OptionType::Boolean}, 82 {"--branch-any", OptionType::Boolean}, 83 {"-j", OptionType::Value}, 84 {"--branch-filter", OptionType::Value}, 85 {"-W", OptionType::Boolean}, 86 {"--weight", OptionType::Boolean}, 87 {"--transaction", OptionType::Boolean}, 88 /* Banned: {"--per-thread", OptionType::Boolean}, 89 * Only briefly present in v3.12-v3.13, but also banned: 90 * {"--force-per-cpu", OptionType::Boolean}, */ 91 /* Banned: {"-I", OptionType::Boolean}, // may reveal PII 92 {"--intr-regs", OptionType::Boolean}, */ 93 {"--running-time", OptionType::Boolean}, 94 {"-k", OptionType::Value}, 95 {"--clockid", OptionType::Value}, 96 {"-S", OptionType::Value}, 97 {"--snapshot", OptionType::Value}, 98 99 {"--pfm-events", OptionType::Value}, 100 }; 101 return *kPerfRecordOptions; 102 } 103 104 const std::map<string, OptionType>& GetPerfStatOptions() { 105 static const auto* kPerfStatOptions = new std::map<string, OptionType>{ 106 {"-T", OptionType::Boolean}, 107 {"--transaction", OptionType::Boolean}, 108 {"-e", OptionType::Value}, 109 {"--event", OptionType::Value}, 110 {"--filter", OptionType::Value}, 111 {"-i", OptionType::Boolean}, 112 {"--no-inherit", OptionType::Boolean}, 113 {"-p", OptionType::Value}, 114 {"--pid", OptionType::Value}, 115 {"-t", OptionType::Value}, 116 {"--tid", OptionType::Value}, 117 {"-a", OptionType::Boolean}, 118 {"--all-cpus", OptionType::Boolean}, 119 {"-g", OptionType::Boolean}, 120 {"--group", OptionType::Boolean}, 121 {"-c", OptionType::Boolean}, 122 {"--scale", OptionType::Boolean}, 123 /* Banned: {"-v", OptionType::Boolean}, 124 * {"--verbose", OptionType::Boolean}, */ 125 /* Banned: {"-r", OptionType::Value}, 126 * {"--repeat", OptionType::Value}, */ 127 /* Banned: {"-n", OptionType::Boolean}, 128 * {"--null", OptionType::Boolean}, */ 129 /* Banned: {"-d", OptionType::Boolean}, 130 * {"--detailed", OptionType::Boolean}, */ 131 /* Banned: {"-S", OptionType::Boolean}, 132 * {"--sync", OptionType::Boolean}, */ 133 /* Banned: {"-B", OptionType::Boolean}, 134 * {"--big-num", OptionType::Boolean}, */ 135 {"-C", OptionType::Value}, 136 {"--cpu", OptionType::Value}, 137 {"-A", OptionType::Boolean}, 138 {"--no-aggr", OptionType::Boolean}, 139 /* Banned: {"-x", OptionType::Value}, 140 * {"--field-separator", OptionType::Value}, */ 141 {"-G", OptionType::Value}, 142 {"--cgroup", OptionType::Value}, 143 /* Banned: {"-o", OptionType::Value}, 144 * {"--output", OptionType::Value}, */ 145 /* Banned: {"--append", OptionType::Value}, */ 146 /* Banned: {"--log-fd", OptionType::Value}, */ 147 /* Banned: {"--pre", OptionType::Value}, */ 148 /* Banned: {"--post", OptionType::Value}, */ 149 /* Banned: {"-I", OptionType::Value}, 150 * {"--interval-print", OptionType::Value}, */ 151 {"--per-socket", OptionType::Boolean}, 152 {"--per-core", OptionType::Boolean}, 153 {"-D", OptionType::Value}, 154 {"--delay", OptionType::Value}, 155 }; 156 return *kPerfStatOptions; 157 } 158 159 const std::map<string, OptionType>& GetPerfMemOptions() { 160 static const auto* kPerfMemOptions = new std::map<string, OptionType>{ 161 {"-t", OptionType::Value}, {"--type", OptionType::Value}, 162 {"-D", OptionType::Boolean}, {"--dump-raw-samples", OptionType::Boolean}, 163 {"-x", OptionType::Value}, {"--field-separator", OptionType::Value}, 164 {"-C", OptionType::Value}, {"--cpu-list", OptionType::Value}, 165 }; 166 return *kPerfMemOptions; 167 } 168 169 bool ValidatePerfCommandLineOptions( 170 std::vector<string>::const_iterator begin_arg, 171 std::vector<string>::const_iterator end_arg, 172 const std::map<string, OptionType>& options) { 173 for (auto args_iter = begin_arg; args_iter != end_arg; ++args_iter) { 174 const auto& it = options.find(*args_iter); 175 if (it == options.end()) { 176 return false; 177 } 178 if (it->second == OptionType::Value) { 179 ++args_iter; 180 if (args_iter == end_arg) { 181 return false; // missing value 182 } 183 } 184 } 185 return true; 186 } 187 188 } // namespace 189 190 bool ValidatePerfCommandLine(const std::vector<string>& args) { 191 if (args.size() < 2) { 192 return false; 193 } 194 if (args[0] != "perf") { 195 return false; 196 } 197 if (args[1] == "record") { 198 return ValidatePerfCommandLineOptions(args.begin() + 2, args.end(), 199 GetPerfRecordOptions()); 200 } 201 if (args[1] == "mem") { 202 auto record_arg_iter = std::find(args.begin(), args.end(), "record"); 203 if (record_arg_iter == args.end()) return false; 204 205 return ValidatePerfCommandLineOptions(args.begin() + 2, record_arg_iter, 206 GetPerfMemOptions()) && 207 ValidatePerfCommandLineOptions(record_arg_iter + 1, args.end(), 208 GetPerfRecordOptions()); 209 } 210 if (args[1] == "stat") { 211 return ValidatePerfCommandLineOptions(args.begin() + 2, args.end(), 212 GetPerfStatOptions()); 213 } 214 return false; 215 } 216 217 } // namespace quipper 218