1 /* 2 * Copyright (C) 2013 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_RUNTIME_MAPPING_TABLE_H_ 18 #define ART_RUNTIME_MAPPING_TABLE_H_ 19 20 #include "base/logging.h" 21 #include "leb128.h" 22 23 namespace art { 24 25 // A utility for processing the raw uleb128 encoded mapping table created by the quick compiler. 26 class MappingTable { 27 public: MappingTable(const uint8_t * encoded_map)28 explicit MappingTable(const uint8_t* encoded_map) : encoded_table_(encoded_map) { 29 } 30 TotalSize()31 uint32_t TotalSize() const PURE { 32 const uint8_t* table = encoded_table_; 33 if (table == NULL) { 34 return 0; 35 } else { 36 return DecodeUnsignedLeb128(&table); 37 } 38 } 39 DexToPcSize()40 uint32_t DexToPcSize() const PURE { 41 const uint8_t* table = encoded_table_; 42 if (table == NULL) { 43 return 0; 44 } else { 45 uint32_t total_size = DecodeUnsignedLeb128(&table); 46 uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table); 47 return total_size - pc_to_dex_size; 48 } 49 } 50 FirstDexToPcPtr()51 const uint8_t* FirstDexToPcPtr() const { 52 const uint8_t* table = encoded_table_; 53 if (table != NULL) { 54 DecodeUnsignedLeb128(&table); // Total_size, unused. 55 uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table); 56 for (uint32_t i = 0; i < pc_to_dex_size; ++i) { 57 DecodeUnsignedLeb128(&table); // Move ptr past native PC. 58 DecodeUnsignedLeb128(&table); // Move ptr past dex PC. 59 } 60 } 61 return table; 62 } 63 64 class DexToPcIterator { 65 public: DexToPcIterator(const MappingTable * table,uint32_t element)66 DexToPcIterator(const MappingTable* table, uint32_t element) : 67 table_(table), element_(element), end_(table_->DexToPcSize()), encoded_table_ptr_(NULL), 68 native_pc_offset_(0), dex_pc_(0) { 69 if (element == 0) { 70 encoded_table_ptr_ = table_->FirstDexToPcPtr(); 71 native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_); 72 dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_); 73 } else { 74 DCHECK_EQ(table_->DexToPcSize(), element); 75 } 76 } NativePcOffset()77 uint32_t NativePcOffset() const { 78 return native_pc_offset_; 79 } DexPc()80 uint32_t DexPc() const { 81 return dex_pc_; 82 } 83 void operator++() { 84 ++element_; 85 if (element_ != end_) { // Avoid reading beyond the end of the table. 86 native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_); 87 dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_); 88 } 89 } 90 bool operator==(const DexToPcIterator& rhs) const { 91 CHECK(table_ == rhs.table_); 92 return element_ == rhs.element_; 93 } 94 bool operator!=(const DexToPcIterator& rhs) const { 95 CHECK(table_ == rhs.table_); 96 return element_ != rhs.element_; 97 } 98 99 private: 100 const MappingTable* const table_; // The original table. 101 uint32_t element_; // A value in the range 0 to end_. 102 const uint32_t end_; // Equal to table_->DexToPcSize(). 103 const uint8_t* encoded_table_ptr_; // Either NULL or points to encoded data after this entry. 104 uint32_t native_pc_offset_; // The current value of native pc offset. 105 uint32_t dex_pc_; // The current value of dex pc. 106 }; 107 DexToPcBegin()108 DexToPcIterator DexToPcBegin() const { 109 return DexToPcIterator(this, 0); 110 } 111 DexToPcEnd()112 DexToPcIterator DexToPcEnd() const { 113 uint32_t size = DexToPcSize(); 114 return DexToPcIterator(this, size); 115 } 116 PcToDexSize()117 uint32_t PcToDexSize() const PURE { 118 const uint8_t* table = encoded_table_; 119 if (table == NULL) { 120 return 0; 121 } else { 122 DecodeUnsignedLeb128(&table); // Total_size, unused. 123 uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table); 124 return pc_to_dex_size; 125 } 126 } 127 FirstPcToDexPtr()128 const uint8_t* FirstPcToDexPtr() const { 129 const uint8_t* table = encoded_table_; 130 if (table != NULL) { 131 DecodeUnsignedLeb128(&table); // Total_size, unused. 132 DecodeUnsignedLeb128(&table); // PC to Dex size, unused. 133 } 134 return table; 135 } 136 137 class PcToDexIterator { 138 public: PcToDexIterator(const MappingTable * table,uint32_t element)139 PcToDexIterator(const MappingTable* table, uint32_t element) : 140 table_(table), element_(element), end_(table_->PcToDexSize()), encoded_table_ptr_(NULL), 141 native_pc_offset_(0), dex_pc_(0) { 142 if (element == 0) { 143 encoded_table_ptr_ = table_->FirstPcToDexPtr(); 144 native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_); 145 dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_); 146 } else { 147 DCHECK_EQ(table_->PcToDexSize(), element); 148 } 149 } NativePcOffset()150 uint32_t NativePcOffset() const { 151 return native_pc_offset_; 152 } DexPc()153 uint32_t DexPc() const { 154 return dex_pc_; 155 } 156 void operator++() { 157 ++element_; 158 if (element_ != end_) { // Avoid reading beyond the end of the table. 159 native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_); 160 dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_); 161 } 162 } 163 bool operator==(const PcToDexIterator& rhs) const { 164 CHECK(table_ == rhs.table_); 165 return element_ == rhs.element_; 166 } 167 bool operator!=(const PcToDexIterator& rhs) const { 168 CHECK(table_ == rhs.table_); 169 return element_ != rhs.element_; 170 } 171 172 private: 173 const MappingTable* const table_; // The original table. 174 uint32_t element_; // A value in the range 0 to PcToDexSize. 175 const uint32_t end_; // Equal to table_->PcToDexSize(). 176 const uint8_t* encoded_table_ptr_; // Either NULL or points to encoded data after this entry. 177 uint32_t native_pc_offset_; // The current value of native pc offset. 178 uint32_t dex_pc_; // The current value of dex pc. 179 }; 180 PcToDexBegin()181 PcToDexIterator PcToDexBegin() const { 182 return PcToDexIterator(this, 0); 183 } 184 PcToDexEnd()185 PcToDexIterator PcToDexEnd() const { 186 uint32_t size = PcToDexSize(); 187 return PcToDexIterator(this, size); 188 } 189 190 private: 191 const uint8_t* const encoded_table_; 192 }; 193 194 } // namespace art 195 196 #endif // ART_RUNTIME_MAPPING_TABLE_H_ 197