Home | History | Annotate | Download | only in protobuf
      1 // Copyright (C) 2019 The Android Open Source Project
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "repr/protobuf/ir_reader.h"
     16 
     17 #include "repr/ir_representation_internal.h"
     18 #include "repr/protobuf/api.h"
     19 #include "repr/protobuf/converter.h"
     20 
     21 #include <fstream>
     22 #include <memory>
     23 
     24 #include <google/protobuf/text_format.h>
     25 
     26 
     27 namespace header_checker {
     28 namespace repr {
     29 
     30 
     31 void ProtobufIRReader::ReadTypeInfo(
     32     const abi_dump::BasicNamedAndTypedDecl &type_info, TypeIR *typep) {
     33   typep->SetLinkerSetKey(type_info.linker_set_key());
     34   typep->SetName(type_info.name());
     35   typep->SetSourceFile(type_info.source_file());
     36   typep->SetReferencedType(type_info.referenced_type());
     37   typep->SetSelfType(type_info.self_type());
     38   typep->SetSize(type_info.size());
     39   typep->SetAlignment(type_info.alignment());
     40 }
     41 
     42 bool ProtobufIRReader::ReadDump(const std::string &dump_file) {
     43   abi_dump::TranslationUnit tu;
     44   std::ifstream input(dump_file);
     45   google::protobuf::io::IstreamInputStream text_is(&input);
     46 
     47   if (!google::protobuf::TextFormat::Parse(&text_is, &tu)) {
     48     llvm::errs() << "Failed to parse protobuf TextFormat file\n";
     49     return false;
     50   }
     51   ReadFunctions(tu);
     52   ReadGlobalVariables(tu);
     53 
     54   ReadEnumTypes(tu);
     55   ReadRecordTypes(tu);
     56   ReadFunctionTypes(tu);
     57   ReadArrayTypes(tu);
     58   ReadPointerTypes(tu);
     59   ReadQualifiedTypes(tu);
     60   ReadBuiltinTypes(tu);
     61   ReadLvalueReferenceTypes(tu);
     62   ReadRvalueReferenceTypes(tu);
     63 
     64   ReadElfFunctions(tu);
     65   ReadElfObjects(tu);
     66   return true;
     67 }
     68 
     69 TemplateInfoIR ProtobufIRReader::TemplateInfoProtobufToIR(
     70     const abi_dump::TemplateInfo &template_info_protobuf) {
     71   TemplateInfoIR template_info_ir;
     72   for (auto &&template_element : template_info_protobuf.elements()) {
     73     TemplateElementIR template_element_ir(template_element.referenced_type());
     74     template_info_ir.AddTemplateElement(std::move(template_element_ir));
     75   }
     76   return template_info_ir;
     77 }
     78 
     79 template <typename T>
     80 static void SetupCFunctionLikeIR(const T &cfunction_like_protobuf,
     81                                  CFunctionLikeIR *cfunction_like_ir) {
     82   cfunction_like_ir->SetReturnType(cfunction_like_protobuf.return_type());
     83   for (auto &&parameter: cfunction_like_protobuf.parameters()) {
     84     ParamIR param_ir(parameter.referenced_type(), parameter.default_arg(),
     85                      false);
     86     cfunction_like_ir->AddParameter(std::move(param_ir));
     87   }
     88 }
     89 
     90 FunctionIR ProtobufIRReader::FunctionProtobufToIR(
     91     const abi_dump::FunctionDecl &function_protobuf) {
     92   FunctionIR function_ir;
     93   function_ir.SetReturnType(function_protobuf.return_type());
     94   function_ir.SetLinkerSetKey(function_protobuf.linker_set_key());
     95   function_ir.SetName(function_protobuf.function_name());
     96   function_ir.SetAccess(AccessProtobufToIR(function_protobuf.access()));
     97   function_ir.SetSourceFile(function_protobuf.source_file());
     98   // Set parameters
     99   for (auto &&parameter: function_protobuf.parameters()) {
    100     ParamIR param_ir(parameter.referenced_type(), parameter.default_arg(),
    101                      parameter.is_this_ptr());
    102     function_ir.AddParameter(std::move(param_ir));
    103   }
    104   // Set Template info
    105   function_ir.SetTemplateInfo(
    106       TemplateInfoProtobufToIR(function_protobuf.template_info()));
    107   return function_ir;
    108 }
    109 
    110 FunctionTypeIR ProtobufIRReader::FunctionTypeProtobufToIR(
    111     const abi_dump::FunctionType &function_type_protobuf) {
    112   FunctionTypeIR function_type_ir;
    113   ReadTypeInfo(function_type_protobuf.type_info(), &function_type_ir);
    114   SetupCFunctionLikeIR(function_type_protobuf, &function_type_ir);
    115   return function_type_ir;
    116 }
    117 
    118 VTableLayoutIR ProtobufIRReader::VTableLayoutProtobufToIR(
    119     const abi_dump::VTableLayout &vtable_layout_protobuf) {
    120   VTableLayoutIR vtable_layout_ir;
    121   for (auto &&vtable_component : vtable_layout_protobuf.vtable_components()) {
    122     VTableComponentIR vtable_component_ir(
    123         vtable_component.mangled_component_name(),
    124         VTableComponentKindProtobufToIR(vtable_component.kind()),
    125         vtable_component.component_value(),
    126         vtable_component.is_pure());
    127     vtable_layout_ir.AddVTableComponent(std::move(vtable_component_ir));
    128   }
    129   return vtable_layout_ir;
    130 }
    131 
    132 std::vector<RecordFieldIR> ProtobufIRReader::RecordFieldsProtobufToIR(
    133     const google::protobuf::RepeatedPtrField<abi_dump::RecordFieldDecl> &rfp) {
    134   std::vector<RecordFieldIR> record_type_fields_ir;
    135   for (auto &&field : rfp) {
    136     RecordFieldIR record_field_ir(field.field_name(), field.referenced_type(),
    137                                   field.field_offset(),
    138                                   AccessProtobufToIR(field.access()));
    139     record_type_fields_ir.emplace_back(std::move(record_field_ir));
    140   }
    141   return record_type_fields_ir;
    142 }
    143 
    144 std::vector<CXXBaseSpecifierIR>
    145 ProtobufIRReader::RecordCXXBaseSpecifiersProtobufToIR(
    146     const google::protobuf::RepeatedPtrField<abi_dump::CXXBaseSpecifier> &rbs) {
    147   std::vector<CXXBaseSpecifierIR> record_type_bases_ir;
    148   for (auto &&base : rbs) {
    149     CXXBaseSpecifierIR record_base_ir(
    150         base.referenced_type(), base.is_virtual(),
    151         AccessProtobufToIR(base.access()));
    152     record_type_bases_ir.emplace_back(std::move(record_base_ir));
    153   }
    154   return record_type_bases_ir;
    155 }
    156 
    157 RecordTypeIR ProtobufIRReader::RecordTypeProtobufToIR(
    158     const abi_dump::RecordType &record_type_protobuf) {
    159   RecordTypeIR record_type_ir;
    160   ReadTypeInfo(record_type_protobuf.type_info(), &record_type_ir);
    161   record_type_ir.SetTemplateInfo(
    162       TemplateInfoProtobufToIR(record_type_protobuf.template_info()));
    163   record_type_ir.SetAccess(AccessProtobufToIR(record_type_protobuf.access()));
    164   record_type_ir.SetVTableLayout(
    165       VTableLayoutProtobufToIR(record_type_protobuf.vtable_layout()));
    166   // Get fields
    167   record_type_ir.SetRecordFields(RecordFieldsProtobufToIR(
    168       record_type_protobuf.fields()));
    169   // Base Specifiers
    170   record_type_ir.SetCXXBaseSpecifiers(RecordCXXBaseSpecifiersProtobufToIR(
    171       record_type_protobuf.base_specifiers()));
    172   record_type_ir.SetRecordKind(
    173       RecordKindProtobufToIR(record_type_protobuf.record_kind()));
    174   record_type_ir.SetAnonymity(record_type_protobuf.is_anonymous());
    175   record_type_ir.SetUniqueId(record_type_protobuf.tag_info().unique_id());
    176   return record_type_ir;
    177 }
    178 
    179 std::vector<EnumFieldIR> ProtobufIRReader::EnumFieldsProtobufToIR(
    180     const google::protobuf::RepeatedPtrField<abi_dump::EnumFieldDecl> &efp) {
    181   std::vector<EnumFieldIR> enum_type_fields_ir;
    182   for (auto &&field : efp) {
    183     EnumFieldIR enum_field_ir(field.name(), field.enum_field_value());
    184     enum_type_fields_ir.emplace_back(std::move(enum_field_ir));
    185   }
    186   return enum_type_fields_ir;
    187 }
    188 
    189 EnumTypeIR ProtobufIRReader::EnumTypeProtobufToIR(
    190     const abi_dump::EnumType &enum_type_protobuf) {
    191   EnumTypeIR enum_type_ir;
    192   ReadTypeInfo(enum_type_protobuf.type_info(), &enum_type_ir);
    193   enum_type_ir.SetUnderlyingType(enum_type_protobuf.underlying_type());
    194   enum_type_ir.SetAccess(AccessProtobufToIR(enum_type_protobuf.access()));
    195   enum_type_ir.SetFields(
    196       EnumFieldsProtobufToIR(enum_type_protobuf.enum_fields()));
    197   enum_type_ir.SetUniqueId(enum_type_protobuf.tag_info().unique_id());
    198   return enum_type_ir;
    199 }
    200 
    201 void ProtobufIRReader::ReadGlobalVariables(
    202     const abi_dump::TranslationUnit &tu) {
    203   for (auto &&global_variable_protobuf : tu.global_vars()) {
    204     GlobalVarIR global_variable_ir;
    205     global_variable_ir.SetName(global_variable_protobuf.name());
    206     global_variable_ir.SetAccess(AccessProtobufToIR(global_variable_protobuf.access()));
    207     global_variable_ir.SetSourceFile(global_variable_protobuf.source_file());
    208     global_variable_ir.SetReferencedType(
    209         global_variable_protobuf.referenced_type());
    210     global_variable_ir.SetLinkerSetKey(
    211         global_variable_protobuf.linker_set_key());
    212     module_->AddGlobalVariable(std::move(global_variable_ir));
    213   }
    214 }
    215 
    216 void ProtobufIRReader::ReadPointerTypes(const abi_dump::TranslationUnit &tu) {
    217   for (auto &&pointer_type_protobuf : tu.pointer_types()) {
    218     PointerTypeIR pointer_type_ir;
    219     ReadTypeInfo(pointer_type_protobuf.type_info(), &pointer_type_ir);
    220     module_->AddPointerType(std::move(pointer_type_ir));
    221   }
    222 }
    223 
    224 void ProtobufIRReader::ReadBuiltinTypes(const abi_dump::TranslationUnit &tu) {
    225   for (auto &&builtin_type_protobuf : tu.builtin_types()) {
    226     BuiltinTypeIR builtin_type_ir;
    227     ReadTypeInfo(builtin_type_protobuf.type_info(), &builtin_type_ir);
    228     builtin_type_ir.SetSignedness(builtin_type_protobuf.is_unsigned());
    229     builtin_type_ir.SetIntegralType(builtin_type_protobuf.is_integral());
    230     module_->AddBuiltinType(std::move(builtin_type_ir));
    231   }
    232 }
    233 
    234 void ProtobufIRReader::ReadQualifiedTypes(const abi_dump::TranslationUnit &tu) {
    235   for (auto &&qualified_type_protobuf : tu.qualified_types()) {
    236     QualifiedTypeIR qualified_type_ir;
    237     ReadTypeInfo(qualified_type_protobuf.type_info(), &qualified_type_ir);
    238     qualified_type_ir.SetConstness(qualified_type_protobuf.is_const());
    239     qualified_type_ir.SetVolatility(qualified_type_protobuf.is_volatile());
    240     qualified_type_ir.SetRestrictedness(
    241         qualified_type_protobuf.is_restricted());
    242     module_->AddQualifiedType(std::move(qualified_type_ir));
    243   }
    244 }
    245 
    246 void ProtobufIRReader::ReadArrayTypes(const abi_dump::TranslationUnit &tu) {
    247   for (auto &&array_type_protobuf : tu.array_types()) {
    248     ArrayTypeIR array_type_ir;
    249     ReadTypeInfo(array_type_protobuf.type_info(), &array_type_ir);
    250     module_->AddArrayType(std::move(array_type_ir));
    251   }
    252 }
    253 
    254 void ProtobufIRReader::ReadLvalueReferenceTypes(
    255     const abi_dump::TranslationUnit &tu) {
    256   for (auto &&lvalue_reference_type_protobuf : tu.lvalue_reference_types()) {
    257     LvalueReferenceTypeIR lvalue_reference_type_ir;
    258     ReadTypeInfo(lvalue_reference_type_protobuf.type_info(),
    259                  &lvalue_reference_type_ir);
    260     module_->AddLvalueReferenceType(std::move(lvalue_reference_type_ir));
    261   }
    262 }
    263 
    264 void ProtobufIRReader::ReadRvalueReferenceTypes(
    265     const abi_dump::TranslationUnit &tu) {
    266   for (auto &&rvalue_reference_type_protobuf : tu.rvalue_reference_types()) {
    267     RvalueReferenceTypeIR rvalue_reference_type_ir;
    268     ReadTypeInfo(rvalue_reference_type_protobuf.type_info(),
    269                  &rvalue_reference_type_ir);
    270     module_->AddRvalueReferenceType(std::move(rvalue_reference_type_ir));
    271   }
    272 }
    273 
    274 void ProtobufIRReader::ReadFunctions(const abi_dump::TranslationUnit &tu) {
    275   for (auto &&function_protobuf : tu.functions()) {
    276     FunctionIR function_ir = FunctionProtobufToIR(function_protobuf);
    277     module_->AddFunction(std::move(function_ir));
    278   }
    279 }
    280 
    281 void ProtobufIRReader::ReadRecordTypes(const abi_dump::TranslationUnit &tu) {
    282   for (auto &&record_type_protobuf : tu.record_types()) {
    283     RecordTypeIR record_type_ir = RecordTypeProtobufToIR(record_type_protobuf);
    284     module_->AddRecordType(std::move(record_type_ir));
    285   }
    286 }
    287 
    288 void ProtobufIRReader::ReadFunctionTypes(const abi_dump::TranslationUnit &tu) {
    289   for (auto &&function_type_protobuf : tu.function_types()) {
    290     FunctionTypeIR function_type_ir =
    291         FunctionTypeProtobufToIR(function_type_protobuf);
    292     module_->AddFunctionType(std::move(function_type_ir));
    293   }
    294 }
    295 
    296 void ProtobufIRReader::ReadEnumTypes(const abi_dump::TranslationUnit &tu) {
    297   for (auto &&enum_type_protobuf : tu.enum_types()) {
    298     EnumTypeIR enum_type_ir = EnumTypeProtobufToIR(enum_type_protobuf);
    299     module_->AddEnumType(std::move(enum_type_ir));
    300   }
    301 }
    302 
    303 void ProtobufIRReader::ReadElfFunctions(const abi_dump::TranslationUnit &tu) {
    304   for (auto &&elf_function : tu.elf_functions()) {
    305     ElfFunctionIR elf_function_ir(
    306         elf_function.name(),
    307         ElfSymbolBindingProtobufToIR(elf_function.binding()));
    308     module_->AddElfFunction(std::move(elf_function_ir));
    309   }
    310 }
    311 
    312 void ProtobufIRReader::ReadElfObjects(const abi_dump::TranslationUnit &tu) {
    313   for (auto &&elf_object : tu.elf_objects()) {
    314     ElfObjectIR elf_object_ir(
    315         elf_object.name(), ElfSymbolBindingProtobufToIR(elf_object.binding()));
    316     module_->AddElfObject(std::move(elf_object_ir));
    317   }
    318 }
    319 
    320 std::unique_ptr<IRReader> CreateProtobufIRReader(
    321     const std::set<std::string> *exported_headers) {
    322   return std::make_unique<ProtobufIRReader>(exported_headers);
    323 }
    324 
    325 
    326 }  // namespace repr
    327 }  // namespace header_checker
    328