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 <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 
     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 
    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 
    169 void LibSharedCodeGen::GenerateClassConstructionFunction(Formatter& out,
    170     const ComponentSpecificationMessage& /*message*/,
    171     const string& fuzzer_extended_class_name) {
    172   out << fuzzer_extended_class_name << "() : DriverBase(LIB_SHARED) {}\n";
    173 }
    174 
    175 }  // namespace vts
    176 }  // namespace android
    177