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 &¶meter: 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 &¶meter: 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