Home | History | Annotate | Download | only in driver
      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