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 <iostream> 20 #include <string> 21 22 #include "VtsCompilerUtils.h" 23 #include "test/vts/proto/ComponentSpecificationMessage.pb.h" 24 25 using namespace std; 26 using namespace android; 27 28 namespace android { 29 namespace vts { 30 31 const char* const LibSharedCodeGen::kInstanceVariableName = "sharedlib_"; 32 33 void LibSharedCodeGen::GenerateCppBodyFuzzFunction( 34 Formatter& out, const ComponentSpecificationMessage& message, 35 const string& fuzzer_extended_class_name) { 36 out << "bool " << fuzzer_extended_class_name << "::Fuzz(" << "\n"; 37 out << " FunctionSpecificationMessage* func_msg," << "\n"; 38 out << " void** result, const string& callback_socket_name) {" << "\n"; 39 out.indent(); 40 out << "const char* func_name = func_msg->name().c_str();" << "\n"; 41 out << "LOG(INFO) << \"Function: \" << func_name;\n"; 42 43 for (auto const& api : message.interface().api()) { 44 std::stringstream ss; 45 46 out << "if (!strcmp(func_name, \"" << api.name() << "\")) {" << "\n"; 47 48 // args - definition; 49 int arg_count = 0; 50 for (auto const& arg : api.arg()) { 51 if (arg_count == 0 && arg.type() == TYPE_PREDEFINED && 52 !strncmp(arg.predefined_type().c_str(), 53 message.original_data_structure_name().c_str(), 54 message.original_data_structure_name().length()) && 55 message.original_data_structure_name().length() > 0) { 56 out << " " << GetCppVariableType(arg) << " " 57 << "arg" << arg_count << " = "; 58 out << "reinterpret_cast<" << GetCppVariableType(arg) << ">(" 59 << kInstanceVariableName << ")"; 60 } else if (arg.type() == TYPE_SCALAR) { 61 if (arg.scalar_type() == "char_pointer" || 62 arg.scalar_type() == "uchar_pointer") { 63 if (arg.scalar_type() == "char_pointer") { 64 out << " char "; 65 } else { 66 out << " unsigned char "; 67 } 68 out << "arg" << arg_count 69 << "[func_msg->arg(" << arg_count 70 << ").string_value().length() + 1];" << "\n"; 71 out << " if (func_msg->arg(" << arg_count 72 << ").type() == TYPE_SCALAR && " 73 << "func_msg->arg(" << arg_count 74 << ").string_value().has_message()) {" << "\n"; 75 out << " strcpy(arg" << arg_count << ", " 76 << "func_msg->arg(" << arg_count << ").string_value()" 77 << ".message().c_str());" << "\n"; 78 out << " } else {" << "\n"; 79 out << " strcpy(arg" << arg_count << ", " 80 << GetCppInstanceType(arg) << ");" << "\n"; 81 out << " }" << "\n"; 82 } else { 83 out << " " << GetCppVariableType(arg) << " " 84 << "arg" << arg_count << " = "; 85 out << "(func_msg->arg(" << arg_count 86 << ").type() == TYPE_SCALAR && " 87 << "func_msg->arg(" << arg_count 88 << ").scalar_value().has_" << arg.scalar_type() << "()) ? "; 89 if (arg.scalar_type() == "void_pointer") { 90 out << "reinterpret_cast<" << GetCppVariableType(arg) << ">("; 91 } 92 out << "func_msg->arg(" << arg_count << ").scalar_value()." 93 << arg.scalar_type() << "()"; 94 if (arg.scalar_type() == "void_pointer") { 95 out << ")"; 96 } 97 out << " : " << GetCppInstanceType(arg); 98 } 99 } else { 100 out << " " << GetCppVariableType(arg) << " " 101 << "arg" << arg_count << " = "; 102 out << GetCppInstanceType(arg); 103 } 104 out << ";" << "\n"; 105 out << "LOG(INFO) << \"arg" << arg_count << " = \" << arg" << arg_count 106 << ";\n"; 107 arg_count++; 108 } 109 110 out << " "; 111 out << "typedef void* (*"; 112 out << "func_type_" << api.name() << ")(..."; 113 out << ");" << "\n"; 114 115 // actual function call 116 if (!api.has_return_type() || api.return_type().type() == TYPE_VOID) { 117 out << "*result = NULL;" << "\n"; 118 } else { 119 out << "*result = const_cast<void*>(reinterpret_cast<const void*>("; 120 } 121 out << " "; 122 out << "((func_type_" << api.name() << ") " 123 << "target_loader_.GetLoaderFunction(\"" << api.name() << "\"))("; 124 // out << "reinterpret_cast<" << message.original_data_structure_name() 125 // << "*>(" << kInstanceVariableName << ")->" << api.name() << "("; 126 127 if (arg_count > 0) out << "\n"; 128 129 for (int index = 0; index < arg_count; index++) { 130 out << " arg" << index; 131 if (index != (arg_count - 1)) { 132 out << "," << "\n"; 133 } 134 } 135 if (api.has_return_type() || api.return_type().type() != TYPE_VOID) { 136 out << "))"; 137 } 138 out << ");" << "\n"; 139 out << " return true;" << "\n"; 140 out << " }" << "\n"; 141 } 142 // TODO: if there were pointers, free them. 143 out << "return false;" << "\n"; 144 out.unindent(); 145 out << "}" << "\n"; 146 } 147 148 void LibSharedCodeGen::GenerateCppBodyGetAttributeFunction( 149 Formatter& out, 150 const ComponentSpecificationMessage& /*message*/, 151 const string& fuzzer_extended_class_name) { 152 out << "bool " << fuzzer_extended_class_name << "::GetAttribute(" << "\n"; 153 out << " FunctionSpecificationMessage* func_msg," << "\n"; 154 out << " void** result) {" << "\n"; 155 out.indent(); 156 out << "const char* func_name = func_msg->name().c_str();" << "\n"; 157 out << "LOG(INFO) << \" '\" << func_name << \"'\";\n"; 158 out << "LOG(ERROR) << \"attribute not supported for shared lib yet.\";" 159 << "\n"; 160 out << "return false;" << "\n"; 161 out.unindent(); 162 out << "}" << "\n"; 163 } 164 165 void LibSharedCodeGen::GenerateClassConstructionFunction(Formatter& out, 166 const ComponentSpecificationMessage& /*message*/, 167 const string& fuzzer_extended_class_name) { 168 out << fuzzer_extended_class_name << "() : DriverBase(LIB_SHARED) {}\n"; 169 } 170 171 } // namespace vts 172 } // namespace android 173