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