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/json/ir_reader.h"
16 
17 #include "repr/ir_dumper.h"
18 #include "repr/ir_reader.h"
19 #include "repr/ir_representation_internal.h"
20 #include "repr/json/api.h"
21 #include "repr/json/converter.h"
22 
23 #include <json/reader.h>
24 #include <json/writer.h>
25 
26 #include <llvm/Support/raw_ostream.h>
27 
28 #include <cstdlib>
29 #include <fstream>
30 #include <sstream>
31 #include <string>
32 
33 
34 namespace header_checker {
35 namespace repr {
36 
37 
38 static const std::map<std::string, AccessSpecifierIR>
39     access_json_to_ir(CreateInverseMap(access_ir_to_json));
40 
41 static const std::map<std::string, RecordTypeIR::RecordKind>
42     record_kind_json_to_ir(CreateInverseMap(record_kind_ir_to_json));
43 
44 static const std::map<std::string, VTableComponentIR::Kind>
45     vtable_component_kind_json_to_ir(
46         CreateInverseMap(vtable_component_kind_ir_to_json));
47 
48 static const std::map<std::string, ElfSymbolIR::ElfSymbolBinding>
49     elf_symbol_binding_json_to_ir(
50         CreateInverseMap(elf_symbol_binding_ir_to_json));
51 
52 
JsonObjectRef(const Json::Value & json_value,bool & ok)53 JsonObjectRef::JsonObjectRef(const Json::Value &json_value, bool &ok)
54     : object_(json_value.isObject() ? json_value : json_empty_object), ok_(ok) {
55   if (!json_value.isObject()) {
56     ok_ = false;
57   }
58 }
59 
60 const Json::Value &
Get(const std::string & key,const Json::Value & default_value,IsExpectedJsonType is_expected_type) const61 JsonObjectRef::Get(const std::string &key, const Json::Value &default_value,
62                    IsExpectedJsonType is_expected_type) const {
63   if (!object_.isMember(key)) {
64     return default_value;
65   }
66   const Json::Value &value = object_[key];
67   if (!(value.*is_expected_type)()) {
68     ok_ = false;
69     return default_value;
70   }
71   return value;
72 }
73 
GetBool(const std::string & key) const74 bool JsonObjectRef::GetBool(const std::string &key) const {
75   return Get(key, json_false, &Json::Value::isBool).asBool();
76 }
77 
GetInt(const std::string & key) const78 int64_t JsonObjectRef::GetInt(const std::string &key) const {
79   return Get(key, json_0, &Json::Value::isIntegral).asInt64();
80 }
81 
GetUint(const std::string & key) const82 uint64_t JsonObjectRef::GetUint(const std::string &key) const {
83   return Get(key, json_0, &Json::Value::isIntegral).asUInt64();
84 }
85 
GetString(const std::string & key) const86 std::string JsonObjectRef::GetString(const std::string &key) const {
87   return Get(key, json_empty_string, &Json::Value::isString).asString();
88 }
89 
GetObject(const std::string & key) const90 JsonObjectRef JsonObjectRef::GetObject(const std::string &key) const {
91   return JsonObjectRef(Get(key, json_empty_object, &Json::Value::isObject),
92                        ok_);
93 }
94 
95 JsonArrayRef<JsonObjectRef>
GetObjects(const std::string & key) const96 JsonObjectRef::GetObjects(const std::string &key) const {
97   return JsonArrayRef<JsonObjectRef>(
98       Get(key, json_empty_array, &Json::Value::isArray), ok_);
99 }
100 
101 JsonArrayRef<std::string>
GetStrings(const std::string & key) const102 JsonObjectRef::GetStrings(const std::string &key) const {
103   return JsonArrayRef<std::string>(
104       Get(key, json_empty_array, &Json::Value::isArray), ok_);
105 }
106 
107 template <>
operator *() const108 JsonObjectRef JsonArrayRef<JsonObjectRef>::Iterator::operator*() const {
109   return JsonObjectRef(array_[index_], ok_);
110 }
111 
operator *() const112 template <> std::string JsonArrayRef<std::string>::Iterator::operator*() const {
113   return array_[index_].asString();
114 }
115 
GetAccess(const JsonObjectRef & type_decl)116 static AccessSpecifierIR GetAccess(const JsonObjectRef &type_decl) {
117   std::string access(type_decl.GetString("access"));
118   if (access.empty()) {
119     return default_access_ir;
120   }
121   return FindInMap(access_json_to_ir, access,
122                    "Failed to convert JSON to AccessSpecifierIR");
123 }
124 
125 static RecordTypeIR::RecordKind
GetRecordKind(const JsonObjectRef & record_type)126 GetRecordKind(const JsonObjectRef &record_type) {
127   std::string kind(record_type.GetString("record_kind"));
128   if (kind.empty()) {
129     return default_record_kind_ir;
130   }
131   return FindInMap(record_kind_json_to_ir, kind,
132                    "Failed to convert JSON to RecordKind");
133 }
134 
135 static VTableComponentIR::Kind
GetVTableComponentKind(const JsonObjectRef & vtable_component)136 GetVTableComponentKind(const JsonObjectRef &vtable_component) {
137   std::string kind(vtable_component.GetString("kind"));
138   if (kind.empty()) {
139     return default_vtable_component_kind_ir;
140   }
141   return FindInMap(vtable_component_kind_json_to_ir, kind,
142                    "Failed to convert JSON to VTableComponentIR::Kind");
143 }
144 
145 static ElfSymbolIR::ElfSymbolBinding
GetElfSymbolBinding(const JsonObjectRef & elf_symbol)146 GetElfSymbolBinding(const JsonObjectRef &elf_symbol) {
147   std::string binding(elf_symbol.GetString("binding"));
148   if (binding.empty()) {
149     return default_elf_symbol_binding_ir;
150   }
151   return FindInMap(elf_symbol_binding_json_to_ir, binding,
152                    "Failed to convert JSON to ElfSymbolBinding");
153 }
154 
ReadDumpImpl(const std::string & dump_file)155 bool JsonIRReader::ReadDumpImpl(const std::string &dump_file) {
156   Json::Value tu_json;
157   Json::CharReaderBuilder builder;
158   builder["collectComments"] = false;
159   std::ifstream input(dump_file);
160 
161   std::string errorMessage;
162   if (!Json::parseFromStream(builder, input, &tu_json, &errorMessage)) {
163     llvm::errs() << "Failed to parse JSON: " << errorMessage << "\n";
164     return false;
165   }
166   bool ok = true;
167   JsonObjectRef tu(tu_json, ok);
168   if (!ok) {
169     llvm::errs() << "Translation unit is not an object\n";
170     return false;
171   }
172 
173   ReadFunctions(tu);
174   ReadGlobalVariables(tu);
175   ReadEnumTypes(tu);
176   ReadRecordTypes(tu);
177   ReadFunctionTypes(tu);
178   ReadArrayTypes(tu);
179   ReadPointerTypes(tu);
180   ReadQualifiedTypes(tu);
181   ReadBuiltinTypes(tu);
182   ReadLvalueReferenceTypes(tu);
183   ReadRvalueReferenceTypes(tu);
184   ReadElfFunctions(tu);
185   ReadElfObjects(tu);
186   if (!ok) {
187     llvm::errs() << "Failed to convert JSON to IR\n";
188     return false;
189   }
190   return true;
191 }
192 
ReadTemplateInfo(const JsonObjectRef & type_decl,TemplatedArtifactIR * template_ir)193 void JsonIRReader::ReadTemplateInfo(const JsonObjectRef &type_decl,
194                                     TemplatedArtifactIR *template_ir) {
195   TemplateInfoIR template_info_ir;
196   for (auto &&referenced_type : type_decl.GetStrings("template_args")) {
197     TemplateElementIR template_element_ir(referenced_type);
198     template_info_ir.AddTemplateElement(std::move(template_element_ir));
199   }
200   template_ir->SetTemplateInfo(std::move(template_info_ir));
201 }
202 
ReadTypeInfo(const JsonObjectRef & type_decl,TypeIR * type_ir)203 void JsonIRReader::ReadTypeInfo(const JsonObjectRef &type_decl,
204                                 TypeIR *type_ir) {
205   type_ir->SetLinkerSetKey(type_decl.GetString("linker_set_key"));
206   type_ir->SetSourceFile(type_decl.GetString("source_file"));
207   type_ir->SetName(type_decl.GetString("name"));
208   type_ir->SetReferencedType(type_decl.GetString("referenced_type"));
209   type_ir->SetSelfType(type_decl.GetString("self_type"));
210   type_ir->SetSize(type_decl.GetUint("size"));
211   type_ir->SetAlignment(type_decl.GetUint("alignment"));
212 }
213 
ReadRecordFields(const JsonObjectRef & record_type,RecordTypeIR * record_ir)214 void JsonIRReader::ReadRecordFields(const JsonObjectRef &record_type,
215                                     RecordTypeIR *record_ir) {
216   for (auto &&field : record_type.GetObjects("fields")) {
217     RecordFieldIR record_field_ir(
218         field.GetString("field_name"), field.GetString("referenced_type"),
219         field.GetUint("field_offset"), GetAccess(field));
220     record_ir->AddRecordField(std::move(record_field_ir));
221   }
222 }
223 
ReadBaseSpecifiers(const JsonObjectRef & record_type,RecordTypeIR * record_ir)224 void JsonIRReader::ReadBaseSpecifiers(const JsonObjectRef &record_type,
225                                       RecordTypeIR *record_ir) {
226   for (auto &&base_specifier : record_type.GetObjects("base_specifiers")) {
227     CXXBaseSpecifierIR record_base_ir(
228         base_specifier.GetString("referenced_type"),
229         base_specifier.GetBool("is_virtual"), GetAccess(base_specifier));
230     record_ir->AddCXXBaseSpecifier(std::move(record_base_ir));
231   }
232 }
233 
ReadVTableLayout(const JsonObjectRef & record_type,RecordTypeIR * record_ir)234 void JsonIRReader::ReadVTableLayout(const JsonObjectRef &record_type,
235                                     RecordTypeIR *record_ir) {
236   VTableLayoutIR vtable_layout_ir;
237   for (auto &&vtable_component : record_type.GetObjects("vtable_components")) {
238     VTableComponentIR vtable_component_ir(
239         vtable_component.GetString("mangled_component_name"),
240         GetVTableComponentKind(vtable_component),
241         vtable_component.GetInt("component_value"),
242         vtable_component.GetBool("is_pure"));
243     vtable_layout_ir.AddVTableComponent(std::move(vtable_component_ir));
244   }
245   record_ir->SetVTableLayout(std::move(vtable_layout_ir));
246 }
247 
ReadEnumFields(const JsonObjectRef & enum_type,EnumTypeIR * enum_ir)248 void JsonIRReader::ReadEnumFields(const JsonObjectRef &enum_type,
249                                   EnumTypeIR *enum_ir) {
250   for (auto &&field : enum_type.GetObjects("enum_fields")) {
251     EnumFieldIR enum_field_ir(field.GetString("name"),
252                               field.GetInt("enum_field_value"));
253     enum_ir->AddEnumField(std::move(enum_field_ir));
254   }
255 }
256 
ReadFunctionParametersAndReturnType(const JsonObjectRef & function,CFunctionLikeIR * function_ir)257 void JsonIRReader::ReadFunctionParametersAndReturnType(
258     const JsonObjectRef &function, CFunctionLikeIR *function_ir) {
259   function_ir->SetReturnType(function.GetString("return_type"));
260   for (auto &&parameter : function.GetObjects("parameters")) {
261     ParamIR param_ir(parameter.GetString("referenced_type"),
262                      parameter.GetBool("default_arg"),
263                      parameter.GetBool("is_this_ptr"));
264     function_ir->AddParameter(std::move(param_ir));
265   }
266 }
267 
FunctionJsonToIR(const JsonObjectRef & function)268 FunctionIR JsonIRReader::FunctionJsonToIR(const JsonObjectRef &function) {
269   FunctionIR function_ir;
270   function_ir.SetLinkerSetKey(function.GetString("linker_set_key"));
271   function_ir.SetName(function.GetString("function_name"));
272   function_ir.SetAccess(GetAccess(function));
273   function_ir.SetSourceFile(function.GetString("source_file"));
274   ReadFunctionParametersAndReturnType(function, &function_ir);
275   ReadTemplateInfo(function, &function_ir);
276   return function_ir;
277 }
278 
279 FunctionTypeIR
FunctionTypeJsonToIR(const JsonObjectRef & function_type)280 JsonIRReader::FunctionTypeJsonToIR(const JsonObjectRef &function_type) {
281   FunctionTypeIR function_type_ir;
282   ReadTypeInfo(function_type, &function_type_ir);
283   ReadFunctionParametersAndReturnType(function_type, &function_type_ir);
284   return function_type_ir;
285 }
286 
287 RecordTypeIR
RecordTypeJsonToIR(const JsonObjectRef & record_type)288 JsonIRReader::RecordTypeJsonToIR(const JsonObjectRef &record_type) {
289   RecordTypeIR record_type_ir;
290   ReadTypeInfo(record_type, &record_type_ir);
291   ReadTemplateInfo(record_type, &record_type_ir);
292   record_type_ir.SetAccess(GetAccess(record_type));
293   ReadVTableLayout(record_type, &record_type_ir);
294   ReadRecordFields(record_type, &record_type_ir);
295   ReadBaseSpecifiers(record_type, &record_type_ir);
296   record_type_ir.SetRecordKind(GetRecordKind(record_type));
297   record_type_ir.SetAnonymity(record_type.GetBool("is_anonymous"));
298   return record_type_ir;
299 }
300 
EnumTypeJsonToIR(const JsonObjectRef & enum_type)301 EnumTypeIR JsonIRReader::EnumTypeJsonToIR(const JsonObjectRef &enum_type) {
302   EnumTypeIR enum_type_ir;
303   ReadTypeInfo(enum_type, &enum_type_ir);
304   enum_type_ir.SetUnderlyingType(enum_type.GetString("underlying_type"));
305   enum_type_ir.SetAccess(GetAccess(enum_type));
306   ReadEnumFields(enum_type, &enum_type_ir);
307   return enum_type_ir;
308 }
309 
ReadGlobalVariables(const JsonObjectRef & tu)310 void JsonIRReader::ReadGlobalVariables(const JsonObjectRef &tu) {
311   for (auto &&global_variable : tu.GetObjects("global_vars")) {
312     GlobalVarIR global_variable_ir;
313     global_variable_ir.SetName(global_variable.GetString("name"));
314     global_variable_ir.SetAccess(GetAccess(global_variable));
315     global_variable_ir.SetSourceFile(global_variable.GetString("source_file"));
316     global_variable_ir.SetReferencedType(
317         global_variable.GetString("referenced_type"));
318     global_variable_ir.SetLinkerSetKey(
319         global_variable.GetString("linker_set_key"));
320     module_->AddGlobalVariable(std::move(global_variable_ir));
321   }
322 }
323 
ReadPointerTypes(const JsonObjectRef & tu)324 void JsonIRReader::ReadPointerTypes(const JsonObjectRef &tu) {
325   for (auto &&pointer_type : tu.GetObjects("pointer_types")) {
326     PointerTypeIR pointer_type_ir;
327     ReadTypeInfo(pointer_type, &pointer_type_ir);
328     module_->AddPointerType(std::move(pointer_type_ir));
329   }
330 }
331 
ReadBuiltinTypes(const JsonObjectRef & tu)332 void JsonIRReader::ReadBuiltinTypes(const JsonObjectRef &tu) {
333   for (auto &&builtin_type : tu.GetObjects("builtin_types")) {
334     BuiltinTypeIR builtin_type_ir;
335     ReadTypeInfo(builtin_type, &builtin_type_ir);
336     builtin_type_ir.SetSignedness(builtin_type.GetBool("is_unsigned"));
337     builtin_type_ir.SetIntegralType(builtin_type.GetBool("is_integral"));
338     module_->AddBuiltinType(std::move(builtin_type_ir));
339   }
340 }
341 
ReadQualifiedTypes(const JsonObjectRef & tu)342 void JsonIRReader::ReadQualifiedTypes(const JsonObjectRef &tu) {
343   for (auto &&qualified_type : tu.GetObjects("qualified_types")) {
344     QualifiedTypeIR qualified_type_ir;
345     ReadTypeInfo(qualified_type, &qualified_type_ir);
346     qualified_type_ir.SetConstness(qualified_type.GetBool("is_const"));
347     qualified_type_ir.SetVolatility(qualified_type.GetBool("is_volatile"));
348     qualified_type_ir.SetRestrictedness(
349         qualified_type.GetBool("is_restricted"));
350     module_->AddQualifiedType(std::move(qualified_type_ir));
351   }
352 }
353 
ReadArrayTypes(const JsonObjectRef & tu)354 void JsonIRReader::ReadArrayTypes(const JsonObjectRef &tu) {
355   for (auto &&array_type : tu.GetObjects("array_types")) {
356     ArrayTypeIR array_type_ir;
357     ReadTypeInfo(array_type, &array_type_ir);
358     module_->AddArrayType(std::move(array_type_ir));
359   }
360 }
361 
ReadLvalueReferenceTypes(const JsonObjectRef & tu)362 void JsonIRReader::ReadLvalueReferenceTypes(const JsonObjectRef &tu) {
363   for (auto &&lvalue_reference_type : tu.GetObjects("lvalue_reference_types")) {
364     LvalueReferenceTypeIR lvalue_reference_type_ir;
365     ReadTypeInfo(lvalue_reference_type, &lvalue_reference_type_ir);
366     module_->AddLvalueReferenceType(std::move(lvalue_reference_type_ir));
367   }
368 }
369 
ReadRvalueReferenceTypes(const JsonObjectRef & tu)370 void JsonIRReader::ReadRvalueReferenceTypes(const JsonObjectRef &tu) {
371   for (auto &&rvalue_reference_type : tu.GetObjects("rvalue_reference_types")) {
372     RvalueReferenceTypeIR rvalue_reference_type_ir;
373     ReadTypeInfo(rvalue_reference_type, &rvalue_reference_type_ir);
374     module_->AddRvalueReferenceType(std::move(rvalue_reference_type_ir));
375   }
376 }
377 
ReadFunctions(const JsonObjectRef & tu)378 void JsonIRReader::ReadFunctions(const JsonObjectRef &tu) {
379   for (auto &&function : tu.GetObjects("functions")) {
380     FunctionIR function_ir = FunctionJsonToIR(function);
381     module_->AddFunction(std::move(function_ir));
382   }
383 }
384 
ReadRecordTypes(const JsonObjectRef & tu)385 void JsonIRReader::ReadRecordTypes(const JsonObjectRef &tu) {
386   for (auto &&record_type : tu.GetObjects("record_types")) {
387     RecordTypeIR record_type_ir = RecordTypeJsonToIR(record_type);
388     module_->AddRecordType(std::move(record_type_ir));
389   }
390 }
391 
ReadFunctionTypes(const JsonObjectRef & tu)392 void JsonIRReader::ReadFunctionTypes(const JsonObjectRef &tu) {
393   for (auto &&function_type : tu.GetObjects("function_types")) {
394     FunctionTypeIR function_type_ir = FunctionTypeJsonToIR(function_type);
395     module_->AddFunctionType(std::move(function_type_ir));
396   }
397 }
398 
ReadEnumTypes(const JsonObjectRef & tu)399 void JsonIRReader::ReadEnumTypes(const JsonObjectRef &tu) {
400   for (auto &&enum_type : tu.GetObjects("enum_types")) {
401     EnumTypeIR enum_type_ir = EnumTypeJsonToIR(enum_type);
402     module_->AddEnumType(std::move(enum_type_ir));
403   }
404 }
405 
ReadElfFunctions(const JsonObjectRef & tu)406 void JsonIRReader::ReadElfFunctions(const JsonObjectRef &tu) {
407   for (auto &&elf_function : tu.GetObjects("elf_functions")) {
408     ElfFunctionIR elf_function_ir(elf_function.GetString("name"),
409                                   GetElfSymbolBinding(elf_function));
410     module_->AddElfFunction(std::move(elf_function_ir));
411   }
412 }
413 
ReadElfObjects(const JsonObjectRef & tu)414 void JsonIRReader::ReadElfObjects(const JsonObjectRef &tu) {
415   for (auto &&elf_object : tu.GetObjects("elf_objects")) {
416     ElfObjectIR elf_object_ir(elf_object.GetString("name"),
417                               GetElfSymbolBinding(elf_object));
418     module_->AddElfObject(std::move(elf_object_ir));
419   }
420 }
421 
CreateJsonIRReader(const std::set<std::string> * exported_headers)422 std::unique_ptr<IRReader> CreateJsonIRReader(
423     const std::set<std::string> *exported_headers) {
424   return std::make_unique<JsonIRReader>(exported_headers);
425 }
426 
427 
428 }  // namespace repr
429 }  // header_checker
430