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