• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "code_gen/driver/LibSharedCodeGen.h"
18 
19 #include <fstream>
20 #include <iostream>
21 #include <sstream>
22 #include <string>
23 
24 #include "test/vts/proto/ComponentSpecificationMessage.pb.h"
25 
26 #include "VtsCompilerUtils.h"
27 
28 using namespace std;
29 using namespace android;
30 
31 namespace android {
32 namespace vts {
33 
34 const char* const LibSharedCodeGen::kInstanceVariableName = "sharedlib_";
35 
GenerateCppBodyFuzzFunction(Formatter & out,const ComponentSpecificationMessage & message,const string & fuzzer_extended_class_name)36 void LibSharedCodeGen::GenerateCppBodyFuzzFunction(
37     Formatter& out, const ComponentSpecificationMessage& message,
38     const string& fuzzer_extended_class_name) {
39   out << "bool " << fuzzer_extended_class_name << "::Fuzz(" << "\n";
40   out << "    FunctionSpecificationMessage* func_msg," << "\n";
41   out << "    void** result, const string& callback_socket_name) {" << "\n";
42   out.indent();
43   out << "const char* func_name = func_msg->name().c_str();" << "\n";
44   out << "cout << \"Function: \" << func_name << endl;" << "\n";
45 
46   for (auto const& api : message.interface().api()) {
47     std::stringstream ss;
48 
49     out << "if (!strcmp(func_name, \"" << api.name() << "\")) {" << "\n";
50 
51     // args - definition;
52     int arg_count = 0;
53     for (auto const& arg : api.arg()) {
54       if (arg_count == 0 && arg.type() == TYPE_PREDEFINED &&
55           !strncmp(arg.predefined_type().c_str(),
56                    message.original_data_structure_name().c_str(),
57                    message.original_data_structure_name().length()) &&
58           message.original_data_structure_name().length() > 0) {
59         out << "    " << GetCppVariableType(arg) << " "
60             << "arg" << arg_count << " = ";
61         out << "reinterpret_cast<" << GetCppVariableType(arg) << ">("
62                << kInstanceVariableName << ")";
63       } else if (arg.type() == TYPE_SCALAR) {
64         if (arg.scalar_type() == "char_pointer" ||
65             arg.scalar_type() == "uchar_pointer") {
66           if (arg.scalar_type() == "char_pointer") {
67             out << "    char ";
68           } else {
69             out << "    unsigned char ";
70           }
71           out << "arg" << arg_count
72                  << "[func_msg->arg(" << arg_count
73                  << ").string_value().length() + 1];" << "\n";
74           out << "    if (func_msg->arg(" << arg_count
75                  << ").type() == TYPE_SCALAR && "
76                  << "func_msg->arg(" << arg_count
77                  << ").string_value().has_message()) {" << "\n";
78           out << "      strcpy(arg" << arg_count << ", "
79                  << "func_msg->arg(" << arg_count << ").string_value()"
80                  << ".message().c_str());" << "\n";
81           out << "    } else {" << "\n";
82           out << "   strcpy(arg" << arg_count << ", "
83                  << GetCppInstanceType(arg) << ");" << "\n";
84           out << "    }" << "\n";
85         } else {
86           out << "    " << GetCppVariableType(arg) << " "
87                  << "arg" << arg_count << " = ";
88           out << "(func_msg->arg(" << arg_count
89                  << ").type() == TYPE_SCALAR && "
90                  << "func_msg->arg(" << arg_count
91                  << ").scalar_value().has_" << arg.scalar_type() << "()) ? ";
92           if (arg.scalar_type() == "void_pointer") {
93             out << "reinterpret_cast<" << GetCppVariableType(arg) << ">(";
94           }
95           out << "func_msg->arg(" << arg_count << ").scalar_value()."
96                  << arg.scalar_type() << "()";
97           if (arg.scalar_type() == "void_pointer") {
98             out << ")";
99           }
100           out << " : " << GetCppInstanceType(arg);
101         }
102       } else {
103         out << "    " << GetCppVariableType(arg) << " "
104                << "arg" << arg_count << " = ";
105         out << GetCppInstanceType(arg);
106       }
107       out << ";" << "\n";
108       out << "    cout << \"arg" << arg_count << " = \" << arg" << arg_count
109           << " << endl;" << "\n";
110       arg_count++;
111     }
112 
113     out << "    ";
114     out << "typedef void* (*";
115     out << "func_type_" << api.name() << ")(...";
116     out << ");" << "\n";
117 
118     // actual function call
119     if (!api.has_return_type() || api.return_type().type() == TYPE_VOID) {
120       out << "*result = NULL;" << "\n";
121     } else {
122       out << "*result = const_cast<void*>(reinterpret_cast<const void*>(";
123     }
124     out << "    ";
125     out << "((func_type_" << api.name() << ") "
126            << "target_loader_.GetLoaderFunction(\"" << api.name() << "\"))(";
127     // out << "reinterpret_cast<" << message.original_data_structure_name()
128     //    << "*>(" << kInstanceVariableName << ")->" << api.name() << "(";
129 
130     if (arg_count > 0) out << "\n";
131 
132     for (int index = 0; index < arg_count; index++) {
133       out << "      arg" << index;
134       if (index != (arg_count - 1)) {
135         out << "," << "\n";
136       }
137     }
138     if (api.has_return_type() || api.return_type().type() != TYPE_VOID) {
139       out << "))";
140     }
141     out << ");" << "\n";
142     out << "    return true;" << "\n";
143     out << "  }" << "\n";
144   }
145   // TODO: if there were pointers, free them.
146   out << "return false;" << "\n";
147   out.unindent();
148   out << "}" << "\n";
149 }
150 
GenerateCppBodyGetAttributeFunction(Formatter & out,const ComponentSpecificationMessage &,const string & fuzzer_extended_class_name)151 void LibSharedCodeGen::GenerateCppBodyGetAttributeFunction(
152     Formatter& out,
153     const ComponentSpecificationMessage& /*message*/,
154     const string& fuzzer_extended_class_name) {
155   out << "bool " << fuzzer_extended_class_name << "::GetAttribute(" << "\n";
156   out << "    FunctionSpecificationMessage* func_msg," << "\n";
157   out << "    void** result) {" << "\n";
158   out.indent();
159   out << "const char* func_name = func_msg->name().c_str();" << "\n";
160   out << "cout << \"Function: \" << __func__ << \" '\" << func_name << \"'\" << endl;"
161       << "\n";
162   out << "cerr << \"attribute not supported for shared lib yet\" << endl;"
163       << "\n";
164   out << "return false;" << "\n";
165   out.unindent();
166   out << "}" << "\n";
167 }
168 
GenerateClassConstructionFunction(Formatter & out,const ComponentSpecificationMessage &,const string & fuzzer_extended_class_name)169 void LibSharedCodeGen::GenerateClassConstructionFunction(Formatter& out,
170     const ComponentSpecificationMessage& /*message*/,
171     const string& fuzzer_extended_class_name) {
172   out << fuzzer_extended_class_name << "() : FuzzerBase(LIB_SHARED) {}\n";
173 }
174 
175 }  // namespace vts
176 }  // namespace android
177