• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "disassembler.h"
17 
18 #include "utils/logger.h"
19 #include "utils/pandargs.h"
20 #include "ark_version.h"
21 #include "file_format_version.h"
22 
PrintHelp(panda::PandArgParser & pa_parser)23 void PrintHelp(panda::PandArgParser &pa_parser)
24 {
25     std::cerr << "Usage:" << std::endl;
26     std::cerr << "ark_disasm [options] input_file output_file" << std::endl << std::endl;
27     std::cerr << "Supported options:" << std::endl << std::endl;
28     std::cerr << pa_parser.GetHelpString() << std::endl;
29 }
30 
Disassemble(const std::string & input_file,const std::string & output_file,const bool verbose,const bool quiet,const bool skip_strings)31 void Disassemble(const std::string &input_file, const std::string &output_file, const bool verbose, const bool quiet,
32                  const bool skip_strings)
33 {
34     LOG(DEBUG, DISASSEMBLER) << "[initializing disassembler]\nfile: " << input_file << "\n";
35 
36     panda::disasm::Disassembler disasm {};
37     disasm.Disassemble(input_file, quiet, skip_strings);
38     if (verbose) {
39         disasm.CollectInfo();
40     }
41 
42     LOG(DEBUG, DISASSEMBLER) << "[serializing results]\n";
43 
44     std::ofstream res_pa;
45     res_pa.open(output_file, std::ios::trunc | std::ios::out);
46     disasm.Serialize(res_pa, true, verbose);
47     res_pa.close();
48 }
49 
ProcessArgs(panda::PandArgParser & pa_parser,const panda::PandArg<std::string> & input_file,const panda::PandArg<std::string> & output_file,panda::PandArg<bool> & debug,const panda::PandArg<std::string> & debug_file,const panda::PandArg<bool> & help,const panda::PandArg<bool> & version,int argc,const char ** argv)50 bool ProcessArgs(panda::PandArgParser &pa_parser, const panda::PandArg<std::string> &input_file,
51                  const panda::PandArg<std::string> &output_file, panda::PandArg<bool> &debug,
52                  const panda::PandArg<std::string> &debug_file, const panda::PandArg<bool> &help,
53                  const panda::PandArg<bool> &version, int argc, const char **argv)
54 {
55     if (!pa_parser.Parse(argc, argv)) {
56         PrintHelp(pa_parser);
57         return false;
58     }
59 
60     if (version.GetValue()) {
61         panda::PrintPandaVersion();
62         panda::panda_file::PrintBytecodeVersion();
63         return false;
64     }
65 
66     if (input_file.GetValue().empty() || output_file.GetValue().empty() || help.GetValue()) {
67         PrintHelp(pa_parser);
68         return false;
69     }
70 
71     panda::Logger::ComponentMask log_mask = panda::Logger::ComponentMask().set(panda::Logger::Component::DISASSEMBLER)
72                                                                           .set(panda::Logger::Component::PANDAFILE);
73     if (debug.GetValue()) {
74         if (debug_file.GetValue().empty()) {
75             panda::Logger::InitializeStdLogging(
76                 panda::Logger::Level::DEBUG, log_mask);
77         } else {
78             panda::Logger::InitializeFileLogging(
79                 debug_file.GetValue(), panda::Logger::Level::DEBUG, log_mask);
80         }
81     } else {
82         panda::Logger::InitializeStdLogging(panda::Logger::Level::ERROR, log_mask);
83     }
84 
85     return true;
86 }
87 
main(int argc,const char ** argv)88 int main(int argc, const char **argv)
89 {
90     panda::PandArg<bool> help("help", false, "Print this message and exit");
91     panda::PandArg<bool> verbose("verbose", false, "enable informative code output");
92     panda::PandArg<bool> quiet("quiet", false, "enables all of the --skip-* flags");
93     panda::PandArg<bool> skip_strings(
94         "skip-string-literals", false,
95         "replaces string literals with their respectie id's, thus shortening emitted code size");
96     panda::PandArg<bool> debug(
97         "debug", false, "enable debug messages (will be printed to standard output if no --debug-file was specified) ");
98     panda::PandArg<std::string> debug_file("debug-file", "",
99                                            "(--debug-file FILENAME) set debug file name. default is std::cout");
100     panda::PandArg<std::string> input_file("input_file", "", "Path to the source binary code");
101     panda::PandArg<std::string> output_file("output_file", "", "Path to the generated assembly code");
102     panda::PandArg<bool> version {"version", false,
103                                   "Ark version, file format version and minimum supported file format version"};
104 
105     panda::PandArgParser pa_parser;
106 
107     pa_parser.Add(&help);
108     pa_parser.Add(&verbose);
109     pa_parser.Add(&quiet);
110     pa_parser.Add(&skip_strings);
111     pa_parser.Add(&debug);
112     pa_parser.Add(&debug_file);
113     pa_parser.Add(&version);
114     pa_parser.PushBackTail(&input_file);
115     pa_parser.PushBackTail(&output_file);
116     pa_parser.EnableTail();
117 
118     if (!ProcessArgs(pa_parser, input_file, output_file, debug, debug_file, help, version, argc, argv)) {
119         return 1;
120     }
121 
122     Disassemble(input_file.GetValue(), output_file.GetValue(), verbose.GetValue(), quiet.GetValue(),
123                 skip_strings.GetValue());
124 
125     pa_parser.DisableTail();
126 
127     return 0;
128 }
129