xref: /aosp_15_r20/system/extras/pinner/pintool.cpp (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker #include <android-base/parseint.h>
2*288bf522SAndroid Build Coastguard Worker #include <fcntl.h>
3*288bf522SAndroid Build Coastguard Worker #include <sys/endian.h>
4*288bf522SAndroid Build Coastguard Worker #include <sys/mman.h>
5*288bf522SAndroid Build Coastguard Worker #include <sys/stat.h>
6*288bf522SAndroid Build Coastguard Worker #include <sys/types.h>
7*288bf522SAndroid Build Coastguard Worker #include <unistd.h>
8*288bf522SAndroid Build Coastguard Worker #include <iostream>
9*288bf522SAndroid Build Coastguard Worker #include <string>
10*288bf522SAndroid Build Coastguard Worker #include <vector>
11*288bf522SAndroid Build Coastguard Worker 
12*288bf522SAndroid Build Coastguard Worker #include <meminspect.h>
13*288bf522SAndroid Build Coastguard Worker #include <pin_utils.h>
14*288bf522SAndroid Build Coastguard Worker 
15*288bf522SAndroid Build Coastguard Worker using namespace std;
16*288bf522SAndroid Build Coastguard Worker using namespace android::base;
17*288bf522SAndroid Build Coastguard Worker 
18*288bf522SAndroid Build Coastguard Worker enum ToolMode {
19*288bf522SAndroid Build Coastguard Worker     MAPPED_FILE,  // Files that are mapped in memory
20*288bf522SAndroid Build Coastguard Worker     PINLIST,      // pinlist.meta style file
21*288bf522SAndroid Build Coastguard Worker     UNKNOWN
22*288bf522SAndroid Build Coastguard Worker };
23*288bf522SAndroid Build Coastguard Worker 
print_pinlist_ranges(const std::vector<VmaRange> & ranges)24*288bf522SAndroid Build Coastguard Worker void print_pinlist_ranges(const std::vector<VmaRange>& ranges) {
25*288bf522SAndroid Build Coastguard Worker     cout << "--pinlist memory ranges--" << endl;
26*288bf522SAndroid Build Coastguard Worker     for (auto&& range : ranges) {
27*288bf522SAndroid Build Coastguard Worker         cout << "start=" << range.offset << " bytes=" << range.length << endl;
28*288bf522SAndroid Build Coastguard Worker     }
29*288bf522SAndroid Build Coastguard Worker }
30*288bf522SAndroid Build Coastguard Worker 
print_pinlist_summary(const std::vector<VmaRange> & ranges)31*288bf522SAndroid Build Coastguard Worker void print_pinlist_summary(const std::vector<VmaRange>& ranges) {
32*288bf522SAndroid Build Coastguard Worker     cout << "--pinlist summary--" << endl;
33*288bf522SAndroid Build Coastguard Worker     uint64_t total_bytes = 0;
34*288bf522SAndroid Build Coastguard Worker     for (auto&& range : ranges) {
35*288bf522SAndroid Build Coastguard Worker         total_bytes += range.length;
36*288bf522SAndroid Build Coastguard Worker     }
37*288bf522SAndroid Build Coastguard Worker     cout << "total_bytes_to_pin=" << total_bytes << endl;
38*288bf522SAndroid Build Coastguard Worker }
39*288bf522SAndroid Build Coastguard Worker 
perform_file_action(const vector<string> & options)40*288bf522SAndroid Build Coastguard Worker int perform_file_action(const vector<string>& options) {
41*288bf522SAndroid Build Coastguard Worker     std::string custom_probe_file;
42*288bf522SAndroid Build Coastguard Worker     std::string output_file;
43*288bf522SAndroid Build Coastguard Worker     std::string pinconfig_file;
44*288bf522SAndroid Build Coastguard Worker 
45*288bf522SAndroid Build Coastguard Worker     bool verbose = false;
46*288bf522SAndroid Build Coastguard Worker     bool is_zip = false;
47*288bf522SAndroid Build Coastguard Worker     bool dump_results = false;
48*288bf522SAndroid Build Coastguard Worker     ProbeType probe_type = UNSET;
49*288bf522SAndroid Build Coastguard Worker     int64_t write_quota = -1;  // unbounded by default
50*288bf522SAndroid Build Coastguard Worker 
51*288bf522SAndroid Build Coastguard Worker     if (options.empty()) {
52*288bf522SAndroid Build Coastguard Worker         cerr << "Missing filename for file action, see usage for details." << endl;
53*288bf522SAndroid Build Coastguard Worker         return 1;
54*288bf522SAndroid Build Coastguard Worker     }
55*288bf522SAndroid Build Coastguard Worker 
56*288bf522SAndroid Build Coastguard Worker     std::string input_file = options[0];
57*288bf522SAndroid Build Coastguard Worker 
58*288bf522SAndroid Build Coastguard Worker     // Validate that the file exists.
59*288bf522SAndroid Build Coastguard Worker     if (get_file_size(input_file) == -1) {
60*288bf522SAndroid Build Coastguard Worker         cerr << "Error: Could not read file: " << input_file << endl;
61*288bf522SAndroid Build Coastguard Worker         return 1;
62*288bf522SAndroid Build Coastguard Worker     }
63*288bf522SAndroid Build Coastguard Worker 
64*288bf522SAndroid Build Coastguard Worker     if (input_file.empty()) {
65*288bf522SAndroid Build Coastguard Worker         cerr << "Error: Should specify an input file." << endl;
66*288bf522SAndroid Build Coastguard Worker         return 1;
67*288bf522SAndroid Build Coastguard Worker     }
68*288bf522SAndroid Build Coastguard Worker 
69*288bf522SAndroid Build Coastguard Worker     // Parse flags
70*288bf522SAndroid Build Coastguard Worker     for (int i = 1; i < options.size(); ++i) {
71*288bf522SAndroid Build Coastguard Worker         string option = options[i];
72*288bf522SAndroid Build Coastguard Worker         if (option == "--gen-probe") {
73*288bf522SAndroid Build Coastguard Worker             if (probe_type != ProbeType::UNSET) {
74*288bf522SAndroid Build Coastguard Worker                 cerr << "Should only specify one probe treatment. See usage for details." << endl;
75*288bf522SAndroid Build Coastguard Worker                 return 1;
76*288bf522SAndroid Build Coastguard Worker             }
77*288bf522SAndroid Build Coastguard Worker             probe_type = ProbeType::GENERATE;
78*288bf522SAndroid Build Coastguard Worker             continue;
79*288bf522SAndroid Build Coastguard Worker         }
80*288bf522SAndroid Build Coastguard Worker 
81*288bf522SAndroid Build Coastguard Worker         if (option == "--use-probe") {
82*288bf522SAndroid Build Coastguard Worker             if (probe_type != ProbeType::UNSET) {
83*288bf522SAndroid Build Coastguard Worker                 cerr << "Should only specify one probe treatment. See usage for details." << endl;
84*288bf522SAndroid Build Coastguard Worker                 return 1;
85*288bf522SAndroid Build Coastguard Worker             }
86*288bf522SAndroid Build Coastguard Worker             probe_type = ProbeType::CUSTOM;
87*288bf522SAndroid Build Coastguard Worker             ++i;
88*288bf522SAndroid Build Coastguard Worker             custom_probe_file = options[i];
89*288bf522SAndroid Build Coastguard Worker             continue;
90*288bf522SAndroid Build Coastguard Worker         }
91*288bf522SAndroid Build Coastguard Worker         if (option == "--pinconfig") {
92*288bf522SAndroid Build Coastguard Worker             ++i;
93*288bf522SAndroid Build Coastguard Worker             pinconfig_file = options[i];
94*288bf522SAndroid Build Coastguard Worker             continue;
95*288bf522SAndroid Build Coastguard Worker         }
96*288bf522SAndroid Build Coastguard Worker         if (option == "-o") {
97*288bf522SAndroid Build Coastguard Worker             ++i;
98*288bf522SAndroid Build Coastguard Worker             output_file = options[i];
99*288bf522SAndroid Build Coastguard Worker             continue;
100*288bf522SAndroid Build Coastguard Worker         }
101*288bf522SAndroid Build Coastguard Worker         if (option == "--quota") {
102*288bf522SAndroid Build Coastguard Worker             ++i;
103*288bf522SAndroid Build Coastguard Worker             android::base::ParseInt(options[i], &write_quota);
104*288bf522SAndroid Build Coastguard Worker             continue;
105*288bf522SAndroid Build Coastguard Worker         }
106*288bf522SAndroid Build Coastguard Worker         if (option == "-v") {
107*288bf522SAndroid Build Coastguard Worker             verbose = true;
108*288bf522SAndroid Build Coastguard Worker             continue;
109*288bf522SAndroid Build Coastguard Worker         }
110*288bf522SAndroid Build Coastguard Worker         if (option == "--zip") {
111*288bf522SAndroid Build Coastguard Worker             is_zip = true;
112*288bf522SAndroid Build Coastguard Worker             continue;
113*288bf522SAndroid Build Coastguard Worker         }
114*288bf522SAndroid Build Coastguard Worker         if (option == "--dump") {
115*288bf522SAndroid Build Coastguard Worker             dump_results = true;
116*288bf522SAndroid Build Coastguard Worker             continue;
117*288bf522SAndroid Build Coastguard Worker         }
118*288bf522SAndroid Build Coastguard Worker     }
119*288bf522SAndroid Build Coastguard Worker 
120*288bf522SAndroid Build Coastguard Worker     if (verbose) {
121*288bf522SAndroid Build Coastguard Worker         cout << "Setting output pinlist file: " << output_file.c_str() << endl;
122*288bf522SAndroid Build Coastguard Worker         cout << "Setting input file: " << input_file.c_str() << endl;
123*288bf522SAndroid Build Coastguard Worker         cout << "Setting pinconfig file: " << pinconfig_file.c_str() << endl;
124*288bf522SAndroid Build Coastguard Worker         cout << "Setting custom probe file: " << custom_probe_file.c_str() << endl;
125*288bf522SAndroid Build Coastguard Worker         cout << "Setting probe type: " << probe_type << endl;
126*288bf522SAndroid Build Coastguard Worker         cout << "Dump enabled: " << dump_results << endl;
127*288bf522SAndroid Build Coastguard Worker         cout << "Is Zip file: " << is_zip << endl;
128*288bf522SAndroid Build Coastguard Worker         if (write_quota != -1) {
129*288bf522SAndroid Build Coastguard Worker             cout << "Set Write quota: " << write_quota << endl;
130*288bf522SAndroid Build Coastguard Worker         }
131*288bf522SAndroid Build Coastguard Worker     }
132*288bf522SAndroid Build Coastguard Worker 
133*288bf522SAndroid Build Coastguard Worker     PinTool pintool(input_file);
134*288bf522SAndroid Build Coastguard Worker 
135*288bf522SAndroid Build Coastguard Worker     if (is_zip) {
136*288bf522SAndroid Build Coastguard Worker         pintool.set_verbose_output(verbose);
137*288bf522SAndroid Build Coastguard Worker         if (probe_type == ProbeType::CUSTOM) {
138*288bf522SAndroid Build Coastguard Worker             if (verbose) {
139*288bf522SAndroid Build Coastguard Worker                 cout << "Using custom probe file: " << custom_probe_file << endl;
140*288bf522SAndroid Build Coastguard Worker             }
141*288bf522SAndroid Build Coastguard Worker             pintool.read_probe_from_pinlist(custom_probe_file);
142*288bf522SAndroid Build Coastguard Worker         } else if (probe_type == ProbeType::GENERATE) {
143*288bf522SAndroid Build Coastguard Worker             if (verbose) {
144*288bf522SAndroid Build Coastguard Worker                 cout << "Generating probe" << endl;
145*288bf522SAndroid Build Coastguard Worker             }
146*288bf522SAndroid Build Coastguard Worker             int res = pintool.probe_resident();
147*288bf522SAndroid Build Coastguard Worker             if (res > 0) {
148*288bf522SAndroid Build Coastguard Worker                 cerr << "Failed to generate probe. Error Code: " << res << endl;
149*288bf522SAndroid Build Coastguard Worker                 return 1;
150*288bf522SAndroid Build Coastguard Worker             }
151*288bf522SAndroid Build Coastguard Worker         }
152*288bf522SAndroid Build Coastguard Worker         pintool.compute_zip_entry_coverages();
153*288bf522SAndroid Build Coastguard Worker 
154*288bf522SAndroid Build Coastguard Worker         if (pinconfig_file.length() > 0) {
155*288bf522SAndroid Build Coastguard Worker             // We have provided a pinconfig file so perform filtering
156*288bf522SAndroid Build Coastguard Worker             // of computed coverages based on it.
157*288bf522SAndroid Build Coastguard Worker             pintool.filter_zip_entry_coverages(pinconfig_file);
158*288bf522SAndroid Build Coastguard Worker         }
159*288bf522SAndroid Build Coastguard Worker 
160*288bf522SAndroid Build Coastguard Worker         if (dump_results) {
161*288bf522SAndroid Build Coastguard Worker             cout << endl << "----Unfiltered file coverages----" << endl << endl;
162*288bf522SAndroid Build Coastguard Worker             pintool.dump_coverages(PinTool::DumpType::FILE_COVERAGE);
163*288bf522SAndroid Build Coastguard Worker 
164*288bf522SAndroid Build Coastguard Worker             if (pinconfig_file.length() > 0) {
165*288bf522SAndroid Build Coastguard Worker                 cout << endl << "----Filtered file coverages----" << endl << endl;
166*288bf522SAndroid Build Coastguard Worker                 pintool.dump_coverages(PinTool::DumpType::FILTERED);
167*288bf522SAndroid Build Coastguard Worker             }
168*288bf522SAndroid Build Coastguard Worker         }
169*288bf522SAndroid Build Coastguard Worker 
170*288bf522SAndroid Build Coastguard Worker         if (output_file.length() > 0) {
171*288bf522SAndroid Build Coastguard Worker             pintool.write_coverages_as_pinlist(output_file, write_quota);
172*288bf522SAndroid Build Coastguard Worker         }
173*288bf522SAndroid Build Coastguard Worker 
174*288bf522SAndroid Build Coastguard Worker         return 0;
175*288bf522SAndroid Build Coastguard Worker     } else {
176*288bf522SAndroid Build Coastguard Worker         if (probe_type != ProbeType::GENERATE) {
177*288bf522SAndroid Build Coastguard Worker             cerr << "Only generating probes is supported for non-zip files, please include "
178*288bf522SAndroid Build Coastguard Worker                     "--gen-probe on your command"
179*288bf522SAndroid Build Coastguard Worker                  << endl;
180*288bf522SAndroid Build Coastguard Worker             return 1;
181*288bf522SAndroid Build Coastguard Worker         }
182*288bf522SAndroid Build Coastguard Worker 
183*288bf522SAndroid Build Coastguard Worker         // Generic file probing will just return resident memory and offsets
184*288bf522SAndroid Build Coastguard Worker         // without more contextual information.
185*288bf522SAndroid Build Coastguard Worker         VmaRangeGroup resident;
186*288bf522SAndroid Build Coastguard Worker 
187*288bf522SAndroid Build Coastguard Worker         int res = pintool.probe_resident();
188*288bf522SAndroid Build Coastguard Worker         if (res > 0) {
189*288bf522SAndroid Build Coastguard Worker             cerr << "Failed to generate probe. Error Code: " << res << endl;
190*288bf522SAndroid Build Coastguard Worker             return 1;
191*288bf522SAndroid Build Coastguard Worker         }
192*288bf522SAndroid Build Coastguard Worker 
193*288bf522SAndroid Build Coastguard Worker         pintool.dump_coverages(PinTool::DumpType::PROBE);
194*288bf522SAndroid Build Coastguard Worker 
195*288bf522SAndroid Build Coastguard Worker         if (output_file.length() > 0) {
196*288bf522SAndroid Build Coastguard Worker             res = write_pinlist_file(output_file, resident.ranges, write_quota);
197*288bf522SAndroid Build Coastguard Worker             if (res > 0) {
198*288bf522SAndroid Build Coastguard Worker                 cerr << "Failed to write pin file at: " << output_file << endl;
199*288bf522SAndroid Build Coastguard Worker             } else if (verbose) {
200*288bf522SAndroid Build Coastguard Worker                 cout << "Finished writing pin file at: " << output_file << endl;
201*288bf522SAndroid Build Coastguard Worker             }
202*288bf522SAndroid Build Coastguard Worker         }
203*288bf522SAndroid Build Coastguard Worker         return res;
204*288bf522SAndroid Build Coastguard Worker     }
205*288bf522SAndroid Build Coastguard Worker     return 0;
206*288bf522SAndroid Build Coastguard Worker }
207*288bf522SAndroid Build Coastguard Worker 
perform_pinlist_action(const vector<string> & options)208*288bf522SAndroid Build Coastguard Worker int perform_pinlist_action(const vector<string>& options) {
209*288bf522SAndroid Build Coastguard Worker     string pinner_file;
210*288bf522SAndroid Build Coastguard Worker     bool verbose = false;
211*288bf522SAndroid Build Coastguard Worker     bool dump = false;
212*288bf522SAndroid Build Coastguard Worker     bool summary = false;
213*288bf522SAndroid Build Coastguard Worker 
214*288bf522SAndroid Build Coastguard Worker     if (options.size() < 1) {
215*288bf522SAndroid Build Coastguard Worker         cerr << "Missing arguments for pinlist mode. See usage for details << endl";
216*288bf522SAndroid Build Coastguard Worker         return 1;
217*288bf522SAndroid Build Coastguard Worker     }
218*288bf522SAndroid Build Coastguard Worker     pinner_file = options[0];
219*288bf522SAndroid Build Coastguard Worker     for (int i = 1; i < options.size(); ++i) {
220*288bf522SAndroid Build Coastguard Worker         string option = options[i];
221*288bf522SAndroid Build Coastguard Worker 
222*288bf522SAndroid Build Coastguard Worker         if (option == "-v") {
223*288bf522SAndroid Build Coastguard Worker             verbose = true;
224*288bf522SAndroid Build Coastguard Worker         }
225*288bf522SAndroid Build Coastguard Worker 
226*288bf522SAndroid Build Coastguard Worker         if (option == "--dump") {
227*288bf522SAndroid Build Coastguard Worker             dump = true;
228*288bf522SAndroid Build Coastguard Worker         }
229*288bf522SAndroid Build Coastguard Worker 
230*288bf522SAndroid Build Coastguard Worker         if (option == "--summary") {
231*288bf522SAndroid Build Coastguard Worker             summary = true;
232*288bf522SAndroid Build Coastguard Worker         }
233*288bf522SAndroid Build Coastguard Worker     }
234*288bf522SAndroid Build Coastguard Worker 
235*288bf522SAndroid Build Coastguard Worker     if (pinner_file.empty()) {
236*288bf522SAndroid Build Coastguard Worker         cerr << "Error: Pinlist file to dump is missing. Specify it with '-p <file>'" << endl;
237*288bf522SAndroid Build Coastguard Worker         return 1;
238*288bf522SAndroid Build Coastguard Worker     }
239*288bf522SAndroid Build Coastguard Worker 
240*288bf522SAndroid Build Coastguard Worker     if (verbose) {
241*288bf522SAndroid Build Coastguard Worker         cout << "Setting file to dump: " << pinner_file.c_str() << endl;
242*288bf522SAndroid Build Coastguard Worker     }
243*288bf522SAndroid Build Coastguard Worker 
244*288bf522SAndroid Build Coastguard Worker     vector<VmaRange> vma_ranges;
245*288bf522SAndroid Build Coastguard Worker     if (read_pinlist_file(pinner_file, vma_ranges) == 1) {
246*288bf522SAndroid Build Coastguard Worker         cerr << "Failed reading pinlist file" << endl;
247*288bf522SAndroid Build Coastguard Worker     }
248*288bf522SAndroid Build Coastguard Worker 
249*288bf522SAndroid Build Coastguard Worker     if (dump) {
250*288bf522SAndroid Build Coastguard Worker         print_pinlist_ranges(vma_ranges);
251*288bf522SAndroid Build Coastguard Worker     }
252*288bf522SAndroid Build Coastguard Worker 
253*288bf522SAndroid Build Coastguard Worker     if (summary) {
254*288bf522SAndroid Build Coastguard Worker         print_pinlist_summary(vma_ranges);
255*288bf522SAndroid Build Coastguard Worker     }
256*288bf522SAndroid Build Coastguard Worker 
257*288bf522SAndroid Build Coastguard Worker     return 0;
258*288bf522SAndroid Build Coastguard Worker }
259*288bf522SAndroid Build Coastguard Worker 
print_usage()260*288bf522SAndroid Build Coastguard Worker void print_usage() {
261*288bf522SAndroid Build Coastguard Worker     const string usage = R"(
262*288bf522SAndroid Build Coastguard Worker     Expected usage: pintool <mode> <required> [option]
263*288bf522SAndroid Build Coastguard Worker     where:
264*288bf522SAndroid Build Coastguard Worker     ./pintool <MODE>
265*288bf522SAndroid Build Coastguard Worker     <MODE>
266*288bf522SAndroid Build Coastguard Worker         file <filename> [option]
267*288bf522SAndroid Build Coastguard Worker             [option]
268*288bf522SAndroid Build Coastguard Worker                 --gen-probe
269*288bf522SAndroid Build Coastguard Worker                     Generate a probe from current resident memory based on provided "file"
270*288bf522SAndroid Build Coastguard Worker                 --use-probe <path_to_input_pinlist.meta>
271*288bf522SAndroid Build Coastguard Worker                     Use a previously generated pinlist.meta style file as the probe to match against.
272*288bf522SAndroid Build Coastguard Worker                 --dump
273*288bf522SAndroid Build Coastguard Worker                     Dump output contents to console.
274*288bf522SAndroid Build Coastguard Worker                 --zip
275*288bf522SAndroid Build Coastguard Worker                     Treat the file as a zip/apk file required for doing per-file coverage analysis and generation.
276*288bf522SAndroid Build Coastguard Worker                 --pinconfig <path_to_pinconfig.txt>
277*288bf522SAndroid Build Coastguard Worker                     Filter output coverage ranges using a provided pinconfig.txt style file. See README.md for samples
278*288bf522SAndroid Build Coastguard Worker                     on the format of that file.
279*288bf522SAndroid Build Coastguard Worker                 -v
280*288bf522SAndroid Build Coastguard Worker                     Enable verbose output.
281*288bf522SAndroid Build Coastguard Worker 
282*288bf522SAndroid Build Coastguard Worker         pinlist <pinlist_file> [option]
283*288bf522SAndroid Build Coastguard Worker             <pinlist_file>
284*288bf522SAndroid Build Coastguard Worker                 this is the file that will be used for reading and it should follow the pinlist.meta format.
285*288bf522SAndroid Build Coastguard Worker             [option]
286*288bf522SAndroid Build Coastguard Worker                 --dump
287*288bf522SAndroid Build Coastguard Worker                     Dump <pinlist_file> contents to console output.
288*288bf522SAndroid Build Coastguard Worker                 -v
289*288bf522SAndroid Build Coastguard Worker                     Enable verbose output.
290*288bf522SAndroid Build Coastguard Worker                 --summary
291*288bf522SAndroid Build Coastguard Worker                     Summary results for the pinlist.meta file
292*288bf522SAndroid Build Coastguard Worker     )";
293*288bf522SAndroid Build Coastguard Worker     cout << usage.c_str();
294*288bf522SAndroid Build Coastguard Worker }
295*288bf522SAndroid Build Coastguard Worker 
main(int argc,char ** argv)296*288bf522SAndroid Build Coastguard Worker int main(int argc, char** argv) {
297*288bf522SAndroid Build Coastguard Worker     if (argc == 1) {
298*288bf522SAndroid Build Coastguard Worker         print_usage();
299*288bf522SAndroid Build Coastguard Worker         return 0;
300*288bf522SAndroid Build Coastguard Worker     }
301*288bf522SAndroid Build Coastguard Worker 
302*288bf522SAndroid Build Coastguard Worker     if (argc < 2) {
303*288bf522SAndroid Build Coastguard Worker         cerr << "<mode> is missing";
304*288bf522SAndroid Build Coastguard Worker         return 1;
305*288bf522SAndroid Build Coastguard Worker     }
306*288bf522SAndroid Build Coastguard Worker 
307*288bf522SAndroid Build Coastguard Worker     if (strcmp(argv[1], "--help") == 0) {
308*288bf522SAndroid Build Coastguard Worker         print_usage();
309*288bf522SAndroid Build Coastguard Worker         return 0;
310*288bf522SAndroid Build Coastguard Worker     }
311*288bf522SAndroid Build Coastguard Worker 
312*288bf522SAndroid Build Coastguard Worker     ToolMode mode = ToolMode::UNKNOWN;
313*288bf522SAndroid Build Coastguard Worker     if (strcmp(argv[1], "file") == 0) {
314*288bf522SAndroid Build Coastguard Worker         mode = ToolMode::MAPPED_FILE;
315*288bf522SAndroid Build Coastguard Worker     } else if (strcmp(argv[1], "pinlist") == 0) {
316*288bf522SAndroid Build Coastguard Worker         mode = ToolMode::PINLIST;
317*288bf522SAndroid Build Coastguard Worker     }
318*288bf522SAndroid Build Coastguard Worker 
319*288bf522SAndroid Build Coastguard Worker     if (mode == ToolMode::UNKNOWN) {
320*288bf522SAndroid Build Coastguard Worker         cerr << "Failed to find mode: " << argv[1] << ". See usage for available modes." << endl;
321*288bf522SAndroid Build Coastguard Worker         return 1;
322*288bf522SAndroid Build Coastguard Worker     }
323*288bf522SAndroid Build Coastguard Worker 
324*288bf522SAndroid Build Coastguard Worker     vector<string> options;
325*288bf522SAndroid Build Coastguard Worker     for (int i = 2; i < argc; ++i) {
326*288bf522SAndroid Build Coastguard Worker         options.push_back(argv[i]);
327*288bf522SAndroid Build Coastguard Worker     }
328*288bf522SAndroid Build Coastguard Worker 
329*288bf522SAndroid Build Coastguard Worker     int res;
330*288bf522SAndroid Build Coastguard Worker     switch (mode) {
331*288bf522SAndroid Build Coastguard Worker         case ToolMode::MAPPED_FILE:
332*288bf522SAndroid Build Coastguard Worker             res = perform_file_action(options);
333*288bf522SAndroid Build Coastguard Worker             break;
334*288bf522SAndroid Build Coastguard Worker         case ToolMode::PINLIST:
335*288bf522SAndroid Build Coastguard Worker             res = perform_pinlist_action(options);
336*288bf522SAndroid Build Coastguard Worker             break;
337*288bf522SAndroid Build Coastguard Worker         case ToolMode::UNKNOWN:
338*288bf522SAndroid Build Coastguard Worker             cerr << "Unknown <MODE> see usage for details." << endl;
339*288bf522SAndroid Build Coastguard Worker             return 1;
340*288bf522SAndroid Build Coastguard Worker     }
341*288bf522SAndroid Build Coastguard Worker 
342*288bf522SAndroid Build Coastguard Worker     return res;
343*288bf522SAndroid Build Coastguard Worker }
344