flow_analysis.h revision 242758af3cf6eae389f43d3804acaabaa4ba93da
1/* 2 * Copyright (C) 2018 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#ifndef ART_TOOLS_VERIDEX_FLOW_ANALYSIS_H_ 18#define ART_TOOLS_VERIDEX_FLOW_ANALYSIS_H_ 19 20#include "dex/code_item_accessors.h" 21#include "dex/dex_file_reference.h" 22#include "dex/method_reference.h" 23#include "veridex.h" 24 25namespace art { 26 27class VeridexClass; 28class VeridexResolver; 29 30/** 31 * The source where a dex register comes from. 32 */ 33enum class RegisterSource { 34 kParameter, 35 kField, 36 kMethod, 37 kClass, 38 kString, 39 kNone 40}; 41 42/** 43 * Abstract representation of a dex register value. 44 */ 45class RegisterValue { 46 public: 47 RegisterValue() : source_(RegisterSource::kNone), reference_(nullptr, 0), type_(nullptr) {} 48 RegisterValue(RegisterSource source, DexFileReference reference, const VeriClass* type) 49 : source_(source), reference_(reference), type_(type) {} 50 51 RegisterSource GetSource() const { return source_; } 52 DexFileReference GetDexFileReference() const { return reference_; } 53 const VeriClass* GetType() const { return type_; } 54 55 const char* ToString() const { 56 switch (source_) { 57 case RegisterSource::kString: 58 return reference_.dex_file->StringDataByIdx(dex::StringIndex(reference_.index)); 59 case RegisterSource::kClass: 60 return reference_.dex_file->StringByTypeIdx(dex::TypeIndex(reference_.index)); 61 default: 62 return "<unknown>"; 63 } 64 } 65 66 private: 67 RegisterSource source_; 68 DexFileReference reference_; 69 const VeriClass* type_; 70}; 71 72struct InstructionInfo { 73 bool has_been_visited; 74}; 75 76class VeriFlowAnalysis { 77 public: 78 VeriFlowAnalysis(VeridexResolver* resolver, 79 const CodeItemDataAccessor& code_item_accessor) 80 : resolver_(resolver), 81 code_item_accessor_(code_item_accessor), 82 dex_registers_(code_item_accessor.InsnsSizeInCodeUnits()), 83 instruction_infos_(code_item_accessor.InsnsSizeInCodeUnits()) {} 84 85 void Run(); 86 87 const std::vector<std::pair<RegisterValue, RegisterValue>>& GetFieldUses() const { 88 return field_uses_; 89 } 90 91 const std::vector<std::pair<RegisterValue, RegisterValue>>& GetMethodUses() const { 92 return method_uses_; 93 } 94 95 private: 96 // Find all branches in the code. 97 void FindBranches(); 98 99 // Analyze all non-deead instructions in the code. 100 void AnalyzeCode(); 101 102 // Set the instruction at the given pc as a branch target. 103 void SetAsBranchTarget(uint32_t dex_pc); 104 105 // Whether the instruction at the given pc is a branch target. 106 bool IsBranchTarget(uint32_t dex_pc); 107 108 // Merge the register values at the given pc with `current_registers`. 109 // Return whether the register values have changed, and the instruction needs 110 // to be visited again. 111 bool MergeRegisterValues(uint32_t dex_pc); 112 113 void UpdateRegister( 114 uint32_t dex_register, RegisterSource kind, VeriClass* cls, uint32_t source_id); 115 void UpdateRegister(uint32_t dex_register, const RegisterValue& value); 116 void UpdateRegister(uint32_t dex_register, const VeriClass* cls); 117 const RegisterValue& GetRegister(uint32_t dex_register); 118 void ProcessDexInstruction(const Instruction& inst); 119 void SetVisited(uint32_t dex_pc); 120 RegisterValue GetReturnType(uint32_t method_index); 121 RegisterValue GetFieldType(uint32_t field_index); 122 123 VeridexResolver* resolver_; 124 const CodeItemDataAccessor& code_item_accessor_; 125 126 // Vector of register values for all branch targets. 127 std::vector<std::unique_ptr<std::vector<RegisterValue>>> dex_registers_; 128 129 // The current values of dex registers. 130 std::vector<RegisterValue> current_registers_; 131 132 // Information on each instruction useful for the analysis. 133 std::vector<InstructionInfo> instruction_infos_; 134 135 // The value of invoke instructions, to be fetched when visiting move-result. 136 RegisterValue last_result_; 137 138 // List of reflection field uses found. 139 std::vector<std::pair<RegisterValue, RegisterValue>> field_uses_; 140 141 // List of reflection method uses found. 142 std::vector<std::pair<RegisterValue, RegisterValue>> method_uses_; 143}; 144 145} // namespace art 146 147#endif // ART_TOOLS_VERIDEX_FLOW_ANALYSIS_H_ 148