Home | History | Annotate | Download | only in dexlayout
      1 /*
      2  * Copyright (C) 2016 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  * Header file of an in-memory representation of DEX files.
     17  */
     18 
     19 #ifndef ART_DEXLAYOUT_DEX_IR_H_
     20 #define ART_DEXLAYOUT_DEX_IR_H_
     21 
     22 #include <stdint.h>
     23 
     24 #include <vector>
     25 
     26 #include "base/iteration_range.h"
     27 #include "base/leb128.h"
     28 #include "base/safe_map.h"
     29 #include "base/stl_util.h"
     30 #include "dex/dex_file-inl.h"
     31 #include "dex/dex_file_types.h"
     32 #include "dex/utf.h"
     33 
     34 namespace art {
     35 namespace dex_ir {
     36 
     37 // Forward declarations for classes used in containers or pointed to.
     38 class AnnotationItem;
     39 class AnnotationsDirectoryItem;
     40 class AnnotationSetItem;
     41 class AnnotationSetRefList;
     42 class CallSiteId;
     43 class ClassData;
     44 class ClassDef;
     45 class CodeItem;
     46 class DebugInfoItem;
     47 class EncodedAnnotation;
     48 class EncodedArrayItem;
     49 class EncodedValue;
     50 class FieldId;
     51 class FieldItem;
     52 class Header;
     53 class HiddenapiClassData;
     54 class MapList;
     55 class MapItem;
     56 class MethodHandleItem;
     57 class MethodId;
     58 class MethodItem;
     59 class ParameterAnnotation;
     60 class ProtoId;
     61 class StringData;
     62 class StringId;
     63 class TryItem;
     64 class TypeId;
     65 class TypeList;
     66 
     67 // Item size constants.
     68 static constexpr size_t kHeaderItemSize = 112;
     69 static constexpr size_t kStringIdItemSize = 4;
     70 static constexpr size_t kTypeIdItemSize = 4;
     71 static constexpr size_t kProtoIdItemSize = 12;
     72 static constexpr size_t kFieldIdItemSize = 8;
     73 static constexpr size_t kMethodIdItemSize = 8;
     74 static constexpr size_t kClassDefItemSize = 32;
     75 static constexpr size_t kCallSiteIdItemSize = 4;
     76 static constexpr size_t kMethodHandleItemSize = 8;
     77 
     78 // Visitor support
     79 class AbstractDispatcher {
     80  public:
     81   AbstractDispatcher() = default;
     82   virtual ~AbstractDispatcher() { }
     83 
     84   virtual void Dispatch(Header* header) = 0;
     85   virtual void Dispatch(const StringData* string_data) = 0;
     86   virtual void Dispatch(const StringId* string_id) = 0;
     87   virtual void Dispatch(const TypeId* type_id) = 0;
     88   virtual void Dispatch(const ProtoId* proto_id) = 0;
     89   virtual void Dispatch(const FieldId* field_id) = 0;
     90   virtual void Dispatch(const MethodId* method_id) = 0;
     91   virtual void Dispatch(const CallSiteId* call_site_id) = 0;
     92   virtual void Dispatch(const MethodHandleItem* method_handle_item) = 0;
     93   virtual void Dispatch(ClassData* class_data) = 0;
     94   virtual void Dispatch(ClassDef* class_def) = 0;
     95   virtual void Dispatch(FieldItem* field_item) = 0;
     96   virtual void Dispatch(MethodItem* method_item) = 0;
     97   virtual void Dispatch(EncodedArrayItem* array_item) = 0;
     98   virtual void Dispatch(CodeItem* code_item) = 0;
     99   virtual void Dispatch(TryItem* try_item) = 0;
    100   virtual void Dispatch(DebugInfoItem* debug_info_item) = 0;
    101   virtual void Dispatch(AnnotationItem* annotation_item) = 0;
    102   virtual void Dispatch(AnnotationSetItem* annotation_set_item) = 0;
    103   virtual void Dispatch(AnnotationSetRefList* annotation_set_ref_list) = 0;
    104   virtual void Dispatch(AnnotationsDirectoryItem* annotations_directory_item) = 0;
    105   virtual void Dispatch(HiddenapiClassData* hiddenapi_class_data) = 0;
    106   virtual void Dispatch(MapList* map_list) = 0;
    107   virtual void Dispatch(MapItem* map_item) = 0;
    108 
    109  private:
    110   DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher);
    111 };
    112 
    113 template<class T> class Iterator : public std::iterator<std::random_access_iterator_tag, T> {
    114  public:
    115   using value_type = typename std::iterator<std::random_access_iterator_tag, T>::value_type;
    116   using difference_type =
    117       typename std::iterator<std::random_access_iterator_tag, value_type>::difference_type;
    118   using pointer = typename std::iterator<std::random_access_iterator_tag, value_type>::pointer;
    119   using reference = typename std::iterator<std::random_access_iterator_tag, value_type>::reference;
    120 
    121   Iterator(const Iterator&) = default;
    122   Iterator(Iterator&&) = default;
    123   Iterator& operator=(const Iterator&) = default;
    124   Iterator& operator=(Iterator&&) = default;
    125 
    126   Iterator(const std::vector<T>& vector,
    127            uint32_t position,
    128            uint32_t iterator_end)
    129       : vector_(&vector),
    130         position_(position),
    131         iterator_end_(iterator_end) { }
    132   Iterator() : vector_(nullptr), position_(0U), iterator_end_(0U) { }
    133 
    134   bool IsValid() const { return position_ < iterator_end_; }
    135 
    136   bool operator==(const Iterator& rhs) const { return position_ == rhs.position_; }
    137   bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
    138   bool operator<(const Iterator& rhs) const { return position_ < rhs.position_; }
    139   bool operator>(const Iterator& rhs) const { return rhs < *this; }
    140   bool operator<=(const Iterator& rhs) const { return !(rhs < *this); }
    141   bool operator>=(const Iterator& rhs) const { return !(*this < rhs); }
    142 
    143   Iterator& operator++() {  // Value after modification.
    144     ++position_;
    145     return *this;
    146   }
    147 
    148   Iterator operator++(int) {
    149     Iterator temp = *this;
    150     ++position_;
    151     return temp;
    152   }
    153 
    154   Iterator& operator+=(difference_type delta) {
    155     position_ += delta;
    156     return *this;
    157   }
    158 
    159   Iterator operator+(difference_type delta) const {
    160     Iterator temp = *this;
    161     temp += delta;
    162     return temp;
    163   }
    164 
    165   Iterator& operator--() {  // Value after modification.
    166     --position_;
    167     return *this;
    168   }
    169 
    170   Iterator operator--(int) {
    171     Iterator temp = *this;
    172     --position_;
    173     return temp;
    174   }
    175 
    176   Iterator& operator-=(difference_type delta) {
    177     position_ -= delta;
    178     return *this;
    179   }
    180 
    181   Iterator operator-(difference_type delta) const {
    182     Iterator temp = *this;
    183     temp -= delta;
    184     return temp;
    185   }
    186 
    187   difference_type operator-(const Iterator& rhs) {
    188     return position_ - rhs.position_;
    189   }
    190 
    191   reference operator*() const {
    192     return const_cast<reference>((*vector_)[position_]);
    193   }
    194 
    195   pointer operator->() const {
    196     return const_cast<pointer>(&((*vector_)[position_]));
    197   }
    198 
    199   reference operator[](difference_type n) const {
    200     return (*vector_)[position_ + n];
    201   }
    202 
    203  private:
    204   const std::vector<T>* vector_;
    205   uint32_t position_;
    206   uint32_t iterator_end_;
    207 
    208   template <typename U>
    209   friend bool operator<(const Iterator<U>& lhs, const Iterator<U>& rhs);
    210 };
    211 
    212 // Collections become owners of the objects added by moving them into unique pointers.
    213 class CollectionBase {
    214  public:
    215   CollectionBase() = default;
    216   virtual ~CollectionBase() { }
    217 
    218   uint32_t GetOffset() const { return offset_; }
    219   void SetOffset(uint32_t new_offset) { offset_ = new_offset; }
    220   virtual uint32_t Size() const = 0;
    221   bool Empty() const { return Size() == 0u; }
    222 
    223  private:
    224   // Start out unassigned.
    225   uint32_t offset_ = 0u;
    226 
    227   DISALLOW_COPY_AND_ASSIGN(CollectionBase);
    228 };
    229 
    230 template<class T> class CollectionVector : public CollectionBase {
    231  public:
    232   using ElementType = std::unique_ptr<T>;
    233 
    234   CollectionVector() { }
    235   explicit CollectionVector(size_t size) {
    236     // Preallocate so that assignment does not invalidate pointers into the vector.
    237     collection_.reserve(size);
    238   }
    239   ~CollectionVector() override { }
    240 
    241   template<class... Args>
    242   T* CreateAndAddItem(Args&&... args) {
    243     T* object = new T(std::forward<Args>(args)...);
    244     collection_.push_back(std::unique_ptr<T>(object));
    245     return object;
    246   }
    247 
    248   uint32_t Size() const override { return collection_.size(); }
    249 
    250   Iterator<ElementType> begin() const { return Iterator<ElementType>(collection_, 0U, Size()); }
    251   Iterator<ElementType> end() const { return Iterator<ElementType>(collection_, Size(), Size()); }
    252 
    253   const ElementType& operator[](size_t index) const {
    254     DCHECK_LT(index, Size());
    255     return collection_[index];
    256   }
    257   ElementType& operator[](size_t index) {
    258     DCHECK_LT(index, Size());
    259     return collection_[index];
    260   }
    261 
    262   // Sort the vector by copying pointers over.
    263   template <typename MapType>
    264   void SortByMapOrder(const MapType& map) {
    265     auto it = map.begin();
    266     CHECK_EQ(map.size(), Size());
    267     for (size_t i = 0; i < Size(); ++i) {
    268       // There are times when the array will temporarily contain the same pointer twice, doing the
    269       // release here sure there is no double free errors.
    270       collection_[i].release();
    271       collection_[i].reset(it->second);
    272       ++it;
    273     }
    274   }
    275 
    276  protected:
    277   std::vector<ElementType> collection_;
    278 
    279  private:
    280   DISALLOW_COPY_AND_ASSIGN(CollectionVector);
    281 };
    282 
    283 template<class T> class IndexedCollectionVector : public CollectionVector<T> {
    284  public:
    285   using Vector = std::vector<std::unique_ptr<T>>;
    286   IndexedCollectionVector() = default;
    287   explicit IndexedCollectionVector(size_t size) : CollectionVector<T>(size) { }
    288 
    289   template <class... Args>
    290   T* CreateAndAddIndexedItem(uint32_t index, Args&&... args) {
    291     T* object = CollectionVector<T>::CreateAndAddItem(std::forward<Args>(args)...);
    292     object->SetIndex(index);
    293     return object;
    294   }
    295 
    296   T* operator[](size_t index) const {
    297     DCHECK_NE(CollectionVector<T>::collection_[index].get(), static_cast<T*>(nullptr));
    298     return CollectionVector<T>::collection_[index].get();
    299   }
    300 
    301  private:
    302   DISALLOW_COPY_AND_ASSIGN(IndexedCollectionVector);
    303 };
    304 
    305 class Item {
    306  public:
    307   Item() { }
    308   virtual ~Item() { }
    309 
    310   Item(Item&&) = default;
    311 
    312   // Return the assigned offset.
    313   uint32_t GetOffset() const WARN_UNUSED {
    314     CHECK(OffsetAssigned());
    315     return offset_;
    316   }
    317   uint32_t GetSize() const WARN_UNUSED { return size_; }
    318   void SetOffset(uint32_t offset) { offset_ = offset; }
    319   void SetSize(uint32_t size) { size_ = size; }
    320   bool OffsetAssigned() const {
    321     return offset_ != kOffsetUnassigned;
    322   }
    323 
    324  protected:
    325   Item(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
    326 
    327   // 0 is the dex file header and shouldn't be a valid offset for any part of the dex file.
    328   static constexpr uint32_t kOffsetUnassigned = 0u;
    329 
    330   // Start out unassigned.
    331   uint32_t offset_ = kOffsetUnassigned;
    332   uint32_t size_ = 0;
    333 };
    334 
    335 class IndexedItem : public Item {
    336  public:
    337   IndexedItem() { }
    338   virtual ~IndexedItem() { }
    339 
    340   uint32_t GetIndex() const { return index_; }
    341   void SetIndex(uint32_t index) { index_ = index; }
    342 
    343  protected:
    344   IndexedItem(uint32_t offset, uint32_t size, uint32_t index)
    345       : Item(offset, size), index_(index) { }
    346 
    347   uint32_t index_ = 0;
    348 };
    349 
    350 class Header : public Item {
    351  public:
    352   Header(const uint8_t* magic,
    353          uint32_t checksum,
    354          const uint8_t* signature,
    355          uint32_t endian_tag,
    356          uint32_t file_size,
    357          uint32_t header_size,
    358          uint32_t link_size,
    359          uint32_t link_offset,
    360          uint32_t data_size,
    361          uint32_t data_offset,
    362          bool support_default_methods)
    363       : Item(0, kHeaderItemSize), support_default_methods_(support_default_methods) {
    364     ConstructorHelper(magic,
    365                       checksum,
    366                       signature,
    367                       endian_tag,
    368                       file_size,
    369                       header_size,
    370                       link_size,
    371                       link_offset,
    372                       data_size,
    373                       data_offset);
    374   }
    375 
    376   Header(const uint8_t* magic,
    377          uint32_t checksum,
    378          const uint8_t* signature,
    379          uint32_t endian_tag,
    380          uint32_t file_size,
    381          uint32_t header_size,
    382          uint32_t link_size,
    383          uint32_t link_offset,
    384          uint32_t data_size,
    385          uint32_t data_offset,
    386          bool support_default_methods,
    387          uint32_t num_string_ids,
    388          uint32_t num_type_ids,
    389          uint32_t num_proto_ids,
    390          uint32_t num_field_ids,
    391          uint32_t num_method_ids,
    392          uint32_t num_class_defs)
    393       : Item(0, kHeaderItemSize),
    394         support_default_methods_(support_default_methods),
    395         string_ids_(num_string_ids),
    396         type_ids_(num_type_ids),
    397         proto_ids_(num_proto_ids),
    398         field_ids_(num_field_ids),
    399         method_ids_(num_method_ids),
    400         class_defs_(num_class_defs) {
    401     ConstructorHelper(magic,
    402                       checksum,
    403                       signature,
    404                       endian_tag,
    405                       file_size,
    406                       header_size,
    407                       link_size,
    408                       link_offset,
    409                       data_size,
    410                       data_offset);
    411   }
    412   ~Header() override { }
    413 
    414   static size_t ItemSize() { return kHeaderItemSize; }
    415 
    416   const uint8_t* Magic() const { return magic_; }
    417   uint32_t Checksum() const { return checksum_; }
    418   const uint8_t* Signature() const { return signature_; }
    419   uint32_t EndianTag() const { return endian_tag_; }
    420   uint32_t FileSize() const { return file_size_; }
    421   uint32_t HeaderSize() const { return header_size_; }
    422   uint32_t LinkSize() const { return link_size_; }
    423   uint32_t LinkOffset() const { return link_offset_; }
    424   uint32_t DataSize() const { return data_size_; }
    425   uint32_t DataOffset() const { return data_offset_; }
    426 
    427   void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
    428   void SetSignature(const uint8_t* new_signature) {
    429     memcpy(signature_, new_signature, sizeof(signature_));
    430   }
    431   void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
    432   void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
    433   void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
    434   void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
    435   void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
    436   void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
    437 
    438   IndexedCollectionVector<StringId>& StringIds() { return string_ids_; }
    439   const IndexedCollectionVector<StringId>& StringIds() const { return string_ids_; }
    440   IndexedCollectionVector<TypeId>& TypeIds() { return type_ids_; }
    441   const IndexedCollectionVector<TypeId>& TypeIds() const { return type_ids_; }
    442   IndexedCollectionVector<ProtoId>& ProtoIds() { return proto_ids_; }
    443   const IndexedCollectionVector<ProtoId>& ProtoIds() const { return proto_ids_; }
    444   IndexedCollectionVector<FieldId>& FieldIds() { return field_ids_; }
    445   const IndexedCollectionVector<FieldId>& FieldIds() const { return field_ids_; }
    446   IndexedCollectionVector<MethodId>& MethodIds() { return method_ids_; }
    447   const IndexedCollectionVector<MethodId>& MethodIds() const { return method_ids_; }
    448   IndexedCollectionVector<ClassDef>& ClassDefs() { return class_defs_; }
    449   const IndexedCollectionVector<ClassDef>& ClassDefs() const { return class_defs_; }
    450   IndexedCollectionVector<CallSiteId>& CallSiteIds() { return call_site_ids_; }
    451   const IndexedCollectionVector<CallSiteId>& CallSiteIds() const { return call_site_ids_; }
    452   IndexedCollectionVector<MethodHandleItem>& MethodHandleItems() { return method_handle_items_; }
    453   const IndexedCollectionVector<MethodHandleItem>& MethodHandleItems() const {
    454     return method_handle_items_;
    455   }
    456   CollectionVector<StringData>& StringDatas() { return string_datas_; }
    457   const CollectionVector<StringData>& StringDatas() const { return string_datas_; }
    458   CollectionVector<TypeList>& TypeLists() { return type_lists_; }
    459   const CollectionVector<TypeList>& TypeLists() const { return type_lists_; }
    460   CollectionVector<EncodedArrayItem>& EncodedArrayItems() { return encoded_array_items_; }
    461   const CollectionVector<EncodedArrayItem>& EncodedArrayItems() const {
    462     return encoded_array_items_;
    463   }
    464   CollectionVector<AnnotationItem>& AnnotationItems() { return annotation_items_; }
    465   const CollectionVector<AnnotationItem>& AnnotationItems() const { return annotation_items_; }
    466   CollectionVector<AnnotationSetItem>& AnnotationSetItems() { return annotation_set_items_; }
    467   const CollectionVector<AnnotationSetItem>& AnnotationSetItems() const {
    468     return annotation_set_items_;
    469   }
    470   CollectionVector<AnnotationSetRefList>& AnnotationSetRefLists() {
    471     return annotation_set_ref_lists_;
    472   }
    473   const CollectionVector<AnnotationSetRefList>& AnnotationSetRefLists() const {
    474     return annotation_set_ref_lists_;
    475   }
    476   CollectionVector<AnnotationsDirectoryItem>& AnnotationsDirectoryItems() {
    477     return annotations_directory_items_;
    478   }
    479   const CollectionVector<AnnotationsDirectoryItem>& AnnotationsDirectoryItems() const {
    480     return annotations_directory_items_;
    481   }
    482   IndexedCollectionVector<HiddenapiClassData>& HiddenapiClassDatas() {
    483     return hiddenapi_class_datas_;
    484   }
    485   const IndexedCollectionVector<HiddenapiClassData>& HiddenapiClassDatas() const {
    486     return hiddenapi_class_datas_;
    487   }
    488   CollectionVector<DebugInfoItem>& DebugInfoItems() { return debug_info_items_; }
    489   const CollectionVector<DebugInfoItem>& DebugInfoItems() const { return debug_info_items_; }
    490   CollectionVector<CodeItem>& CodeItems() { return code_items_; }
    491   const CollectionVector<CodeItem>& CodeItems() const { return code_items_; }
    492   CollectionVector<ClassData>& ClassDatas() { return class_datas_; }
    493   const CollectionVector<ClassData>& ClassDatas() const { return class_datas_; }
    494 
    495   StringId* GetStringIdOrNullPtr(uint32_t index) {
    496     return index == dex::kDexNoIndex ? nullptr : StringIds()[index];
    497   }
    498   TypeId* GetTypeIdOrNullPtr(uint16_t index) {
    499     return index == DexFile::kDexNoIndex16 ? nullptr : TypeIds()[index];
    500   }
    501 
    502   uint32_t MapListOffset() const { return map_list_offset_; }
    503   void SetMapListOffset(uint32_t new_offset) { map_list_offset_ = new_offset; }
    504 
    505   const std::vector<uint8_t>& LinkData() const { return link_data_; }
    506   void SetLinkData(std::vector<uint8_t>&& link_data) { link_data_ = std::move(link_data); }
    507 
    508   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
    509 
    510   bool SupportDefaultMethods() const {
    511     return support_default_methods_;
    512   }
    513 
    514  private:
    515   uint8_t magic_[8];
    516   uint32_t checksum_;
    517   uint8_t signature_[DexFile::kSha1DigestSize];
    518   uint32_t endian_tag_;
    519   uint32_t file_size_;
    520   uint32_t header_size_;
    521   uint32_t link_size_;
    522   uint32_t link_offset_;
    523   uint32_t data_size_;
    524   uint32_t data_offset_;
    525   const bool support_default_methods_;
    526 
    527   void ConstructorHelper(const uint8_t* magic,
    528                          uint32_t checksum,
    529                          const uint8_t* signature,
    530                          uint32_t endian_tag,
    531                          uint32_t file_size,
    532                          uint32_t header_size,
    533                          uint32_t link_size,
    534                          uint32_t link_offset,
    535                          uint32_t data_size,
    536                          uint32_t data_offset) {
    537     checksum_ = checksum;
    538     endian_tag_ = endian_tag;
    539     file_size_ = file_size;
    540     header_size_ = header_size;
    541     link_size_ = link_size;
    542     link_offset_ = link_offset;
    543     data_size_ = data_size;
    544     data_offset_ = data_offset;
    545     memcpy(magic_, magic, sizeof(magic_));
    546     memcpy(signature_, signature, sizeof(signature_));
    547   }
    548 
    549   // Collection vectors own the IR data.
    550   IndexedCollectionVector<StringId> string_ids_;
    551   IndexedCollectionVector<TypeId> type_ids_;
    552   IndexedCollectionVector<ProtoId> proto_ids_;
    553   IndexedCollectionVector<FieldId> field_ids_;
    554   IndexedCollectionVector<MethodId> method_ids_;
    555   IndexedCollectionVector<ClassDef> class_defs_;
    556   IndexedCollectionVector<CallSiteId> call_site_ids_;
    557   IndexedCollectionVector<MethodHandleItem> method_handle_items_;
    558   IndexedCollectionVector<StringData> string_datas_;
    559   IndexedCollectionVector<TypeList> type_lists_;
    560   IndexedCollectionVector<EncodedArrayItem> encoded_array_items_;
    561   IndexedCollectionVector<AnnotationItem> annotation_items_;
    562   IndexedCollectionVector<AnnotationSetItem> annotation_set_items_;
    563   IndexedCollectionVector<AnnotationSetRefList> annotation_set_ref_lists_;
    564   IndexedCollectionVector<AnnotationsDirectoryItem> annotations_directory_items_;
    565   IndexedCollectionVector<HiddenapiClassData> hiddenapi_class_datas_;
    566   // The order of the vectors controls the layout of the output file by index order, to change the
    567   // layout just sort the vector. Note that you may only change the order of the non indexed vectors
    568   // below. Indexed vectors are accessed by indices in other places, changing the sorting order will
    569   // invalidate the existing indices and is not currently supported.
    570   CollectionVector<DebugInfoItem> debug_info_items_;
    571   CollectionVector<CodeItem> code_items_;
    572   CollectionVector<ClassData> class_datas_;
    573 
    574   uint32_t map_list_offset_ = 0;
    575 
    576   // Link data.
    577   std::vector<uint8_t> link_data_;
    578 
    579   DISALLOW_COPY_AND_ASSIGN(Header);
    580 };
    581 
    582 class StringData : public Item {
    583  public:
    584   explicit StringData(const char* data) : data_(strdup(data)) {
    585     size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data);
    586   }
    587 
    588   const char* Data() const { return data_.get(); }
    589 
    590   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    591 
    592  private:
    593   UniqueCPtr<const char> data_;
    594 
    595   DISALLOW_COPY_AND_ASSIGN(StringData);
    596 };
    597 
    598 class StringId : public IndexedItem {
    599  public:
    600   explicit StringId(StringData* string_data) : string_data_(string_data) {
    601     size_ = kStringIdItemSize;
    602   }
    603   ~StringId() override { }
    604 
    605   static size_t ItemSize() { return kStringIdItemSize; }
    606 
    607   const char* Data() const { return string_data_->Data(); }
    608   StringData* DataItem() const { return string_data_; }
    609 
    610   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    611 
    612  private:
    613   StringData* string_data_;
    614 
    615   DISALLOW_COPY_AND_ASSIGN(StringId);
    616 };
    617 
    618 class TypeId : public IndexedItem {
    619  public:
    620   explicit TypeId(StringId* string_id) : string_id_(string_id) { size_ = kTypeIdItemSize; }
    621   ~TypeId() override { }
    622 
    623   static size_t ItemSize() { return kTypeIdItemSize; }
    624 
    625   StringId* GetStringId() const { return string_id_; }
    626 
    627   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    628 
    629  private:
    630   StringId* string_id_;
    631 
    632   DISALLOW_COPY_AND_ASSIGN(TypeId);
    633 };
    634 
    635 using TypeIdVector = std::vector<const TypeId*>;
    636 
    637 class TypeList : public Item {
    638  public:
    639   explicit TypeList(TypeIdVector* type_list) : type_list_(type_list) {
    640     size_ = sizeof(uint32_t) + (type_list->size() * sizeof(uint16_t));
    641   }
    642   ~TypeList() override { }
    643 
    644   const TypeIdVector* GetTypeList() const { return type_list_.get(); }
    645 
    646  private:
    647   std::unique_ptr<TypeIdVector> type_list_;
    648 
    649   DISALLOW_COPY_AND_ASSIGN(TypeList);
    650 };
    651 
    652 class ProtoId : public IndexedItem {
    653  public:
    654   ProtoId(const StringId* shorty, const TypeId* return_type, TypeList* parameters)
    655       : shorty_(shorty), return_type_(return_type), parameters_(parameters)
    656       { size_ = kProtoIdItemSize; }
    657   ~ProtoId() override { }
    658 
    659   static size_t ItemSize() { return kProtoIdItemSize; }
    660 
    661   const StringId* Shorty() const { return shorty_; }
    662   const TypeId* ReturnType() const { return return_type_; }
    663   const TypeList* Parameters() const { return parameters_; }
    664 
    665   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    666 
    667  private:
    668   const StringId* shorty_;
    669   const TypeId* return_type_;
    670   TypeList* parameters_;  // This can be nullptr.
    671 
    672   DISALLOW_COPY_AND_ASSIGN(ProtoId);
    673 };
    674 
    675 class FieldId : public IndexedItem {
    676  public:
    677   FieldId(const TypeId* klass, const TypeId* type, const StringId* name)
    678       : class_(klass), type_(type), name_(name) { size_ = kFieldIdItemSize; }
    679   ~FieldId() override { }
    680 
    681   static size_t ItemSize() { return kFieldIdItemSize; }
    682 
    683   const TypeId* Class() const { return class_; }
    684   const TypeId* Type() const { return type_; }
    685   const StringId* Name() const { return name_; }
    686 
    687   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    688 
    689  private:
    690   const TypeId* class_;
    691   const TypeId* type_;
    692   const StringId* name_;
    693 
    694   DISALLOW_COPY_AND_ASSIGN(FieldId);
    695 };
    696 
    697 class MethodId : public IndexedItem {
    698  public:
    699   MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name)
    700       : class_(klass), proto_(proto), name_(name) { size_ = kMethodIdItemSize; }
    701   ~MethodId() override { }
    702 
    703   static size_t ItemSize() { return kMethodIdItemSize; }
    704 
    705   const TypeId* Class() const { return class_; }
    706   const ProtoId* Proto() const { return proto_; }
    707   const StringId* Name() const { return name_; }
    708 
    709   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    710 
    711  private:
    712   const TypeId* class_;
    713   const ProtoId* proto_;
    714   const StringId* name_;
    715 
    716   DISALLOW_COPY_AND_ASSIGN(MethodId);
    717 };
    718 
    719 class FieldItem : public Item {
    720  public:
    721   FieldItem(uint32_t access_flags, const FieldId* field_id)
    722       : access_flags_(access_flags), field_id_(field_id) { }
    723   ~FieldItem() override { }
    724 
    725   FieldItem(FieldItem&&) = default;
    726 
    727   uint32_t GetAccessFlags() const { return access_flags_; }
    728   const FieldId* GetFieldId() const { return field_id_; }
    729 
    730   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
    731 
    732  private:
    733   uint32_t access_flags_;
    734   const FieldId* field_id_;
    735 
    736   DISALLOW_COPY_AND_ASSIGN(FieldItem);
    737 };
    738 
    739 using FieldItemVector = std::vector<FieldItem>;
    740 
    741 class MethodItem : public Item {
    742  public:
    743   MethodItem(uint32_t access_flags, const MethodId* method_id, CodeItem* code)
    744       : access_flags_(access_flags), method_id_(method_id), code_(code) { }
    745   ~MethodItem() override { }
    746 
    747   MethodItem(MethodItem&&) = default;
    748 
    749   uint32_t GetAccessFlags() const { return access_flags_; }
    750   const MethodId* GetMethodId() const { return method_id_; }
    751   CodeItem* GetCodeItem() { return code_; }
    752 
    753   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
    754 
    755  private:
    756   uint32_t access_flags_;
    757   const MethodId* method_id_;
    758   CodeItem* code_;  // This can be nullptr.
    759 
    760   DISALLOW_COPY_AND_ASSIGN(MethodItem);
    761 };
    762 
    763 using MethodItemVector = std::vector<MethodItem>;
    764 
    765 class EncodedValue {
    766  public:
    767   explicit EncodedValue(uint8_t type) : type_(type) { }
    768 
    769   int8_t Type() const { return type_; }
    770 
    771   void SetBoolean(bool z) { u_.bool_val_ = z; }
    772   void SetByte(int8_t b) { u_.byte_val_ = b; }
    773   void SetShort(int16_t s) { u_.short_val_ = s; }
    774   void SetChar(uint16_t c) { u_.char_val_ = c; }
    775   void SetInt(int32_t i) { u_.int_val_ = i; }
    776   void SetLong(int64_t l) { u_.long_val_ = l; }
    777   void SetFloat(float f) { u_.float_val_ = f; }
    778   void SetDouble(double d) { u_.double_val_ = d; }
    779   void SetStringId(StringId* string_id) { u_.string_val_ = string_id; }
    780   void SetTypeId(TypeId* type_id) { u_.type_val_ = type_id; }
    781   void SetProtoId(ProtoId* proto_id) { u_.proto_val_ = proto_id; }
    782   void SetFieldId(FieldId* field_id) { u_.field_val_ = field_id; }
    783   void SetMethodId(MethodId* method_id) { u_.method_val_ = method_id; }
    784   void SetMethodHandle(MethodHandleItem* method_handle) { u_.method_handle_val_ = method_handle; }
    785   void SetEncodedArray(EncodedArrayItem* encoded_array) { encoded_array_.reset(encoded_array); }
    786   void SetEncodedAnnotation(EncodedAnnotation* encoded_annotation)
    787       { encoded_annotation_.reset(encoded_annotation); }
    788 
    789   bool GetBoolean() const { return u_.bool_val_; }
    790   int8_t GetByte() const { return u_.byte_val_; }
    791   int16_t GetShort() const { return u_.short_val_; }
    792   uint16_t GetChar() const { return u_.char_val_; }
    793   int32_t GetInt() const { return u_.int_val_; }
    794   int64_t GetLong() const { return u_.long_val_; }
    795   float GetFloat() const { return u_.float_val_; }
    796   double GetDouble() const { return u_.double_val_; }
    797   StringId* GetStringId() const { return u_.string_val_; }
    798   TypeId* GetTypeId() const { return u_.type_val_; }
    799   ProtoId* GetProtoId() const { return u_.proto_val_; }
    800   FieldId* GetFieldId() const { return u_.field_val_; }
    801   MethodId* GetMethodId() const { return u_.method_val_; }
    802   MethodHandleItem* GetMethodHandle() const { return u_.method_handle_val_; }
    803   EncodedArrayItem* GetEncodedArray() const { return encoded_array_.get(); }
    804   EncodedAnnotation* GetEncodedAnnotation() const { return encoded_annotation_.get(); }
    805 
    806   EncodedAnnotation* ReleaseEncodedAnnotation() { return encoded_annotation_.release(); }
    807 
    808  private:
    809   uint8_t type_;
    810   union {
    811     bool bool_val_;
    812     int8_t byte_val_;
    813     int16_t short_val_;
    814     uint16_t char_val_;
    815     int32_t int_val_;
    816     int64_t long_val_;
    817     float float_val_;
    818     double double_val_;
    819     StringId* string_val_;
    820     TypeId* type_val_;
    821     ProtoId* proto_val_;
    822     FieldId* field_val_;
    823     MethodId* method_val_;
    824     MethodHandleItem* method_handle_val_;
    825   } u_;
    826   std::unique_ptr<EncodedArrayItem> encoded_array_;
    827   std::unique_ptr<EncodedAnnotation> encoded_annotation_;
    828 
    829   DISALLOW_COPY_AND_ASSIGN(EncodedValue);
    830 };
    831 
    832 using EncodedValueVector = std::vector<std::unique_ptr<EncodedValue>>;
    833 
    834 class AnnotationElement {
    835  public:
    836   AnnotationElement(StringId* name, EncodedValue* value) : name_(name), value_(value) { }
    837 
    838   StringId* GetName() const { return name_; }
    839   EncodedValue* GetValue() const { return value_.get(); }
    840 
    841  private:
    842   StringId* name_;
    843   std::unique_ptr<EncodedValue> value_;
    844 
    845   DISALLOW_COPY_AND_ASSIGN(AnnotationElement);
    846 };
    847 
    848 using AnnotationElementVector = std::vector<std::unique_ptr<AnnotationElement>>;
    849 
    850 class EncodedAnnotation {
    851  public:
    852   EncodedAnnotation(TypeId* type, AnnotationElementVector* elements)
    853       : type_(type), elements_(elements) { }
    854 
    855   TypeId* GetType() const { return type_; }
    856   AnnotationElementVector* GetAnnotationElements() const { return elements_.get(); }
    857 
    858  private:
    859   TypeId* type_;
    860   std::unique_ptr<AnnotationElementVector> elements_;
    861 
    862   DISALLOW_COPY_AND_ASSIGN(EncodedAnnotation);
    863 };
    864 
    865 class EncodedArrayItem : public Item {
    866  public:
    867   explicit EncodedArrayItem(EncodedValueVector* encoded_values)
    868       : encoded_values_(encoded_values) { }
    869 
    870   EncodedValueVector* GetEncodedValues() const { return encoded_values_.get(); }
    871 
    872  private:
    873   std::unique_ptr<EncodedValueVector> encoded_values_;
    874 
    875   DISALLOW_COPY_AND_ASSIGN(EncodedArrayItem);
    876 };
    877 
    878 class ClassData : public Item {
    879  public:
    880   ClassData(FieldItemVector* static_fields,
    881             FieldItemVector* instance_fields,
    882             MethodItemVector* direct_methods,
    883             MethodItemVector* virtual_methods)
    884       : static_fields_(static_fields),
    885         instance_fields_(instance_fields),
    886         direct_methods_(direct_methods),
    887         virtual_methods_(virtual_methods) { }
    888 
    889   ~ClassData() override = default;
    890   FieldItemVector* StaticFields() { return static_fields_.get(); }
    891   FieldItemVector* InstanceFields() { return instance_fields_.get(); }
    892   MethodItemVector* DirectMethods() { return direct_methods_.get(); }
    893   MethodItemVector* VirtualMethods() { return virtual_methods_.get(); }
    894 
    895   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
    896 
    897  private:
    898   std::unique_ptr<FieldItemVector> static_fields_;
    899   std::unique_ptr<FieldItemVector> instance_fields_;
    900   std::unique_ptr<MethodItemVector> direct_methods_;
    901   std::unique_ptr<MethodItemVector> virtual_methods_;
    902 
    903   DISALLOW_COPY_AND_ASSIGN(ClassData);
    904 };
    905 
    906 class ClassDef : public IndexedItem {
    907  public:
    908   ClassDef(const TypeId* class_type,
    909            uint32_t access_flags,
    910            const TypeId* superclass,
    911            TypeList* interfaces,
    912            const StringId* source_file,
    913            AnnotationsDirectoryItem* annotations,
    914            EncodedArrayItem* static_values,
    915            ClassData* class_data)
    916       : class_type_(class_type),
    917         access_flags_(access_flags),
    918         superclass_(superclass),
    919         interfaces_(interfaces),
    920         source_file_(source_file),
    921         annotations_(annotations),
    922         class_data_(class_data),
    923         static_values_(static_values) { size_ = kClassDefItemSize; }
    924 
    925   ~ClassDef() override { }
    926 
    927   static size_t ItemSize() { return kClassDefItemSize; }
    928 
    929   const TypeId* ClassType() const { return class_type_; }
    930   uint32_t GetAccessFlags() const { return access_flags_; }
    931   const TypeId* Superclass() const { return superclass_; }
    932   const TypeList* Interfaces() { return interfaces_; }
    933   uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); }
    934   const StringId* SourceFile() const { return source_file_; }
    935   AnnotationsDirectoryItem* Annotations() const { return annotations_; }
    936   ClassData* GetClassData() { return class_data_; }
    937   EncodedArrayItem* StaticValues() { return static_values_; }
    938 
    939   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
    940 
    941  private:
    942   const TypeId* class_type_;
    943   uint32_t access_flags_;
    944   const TypeId* superclass_;  // This can be nullptr.
    945   TypeList* interfaces_;  // This can be nullptr.
    946   const StringId* source_file_;  // This can be nullptr.
    947   AnnotationsDirectoryItem* annotations_;  // This can be nullptr.
    948   ClassData* class_data_;  // This can be nullptr.
    949   EncodedArrayItem* static_values_;  // This can be nullptr.
    950 
    951   DISALLOW_COPY_AND_ASSIGN(ClassDef);
    952 };
    953 
    954 class TypeAddrPair {
    955  public:
    956   TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
    957 
    958   const TypeId* GetTypeId() const { return type_id_; }
    959   uint32_t GetAddress() const { return address_; }
    960 
    961  private:
    962   const TypeId* type_id_;  // This can be nullptr.
    963   uint32_t address_;
    964 
    965   DISALLOW_COPY_AND_ASSIGN(TypeAddrPair);
    966 };
    967 
    968 using TypeAddrPairVector = std::vector<std::unique_ptr<const TypeAddrPair>>;
    969 
    970 class CatchHandler {
    971  public:
    972   explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers)
    973       : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { }
    974 
    975   bool HasCatchAll() const { return catch_all_; }
    976   uint16_t GetListOffset() const { return list_offset_; }
    977   TypeAddrPairVector* GetHandlers() const { return handlers_.get(); }
    978 
    979  private:
    980   bool catch_all_;
    981   uint16_t list_offset_;
    982   std::unique_ptr<TypeAddrPairVector> handlers_;
    983 
    984   DISALLOW_COPY_AND_ASSIGN(CatchHandler);
    985 };
    986 
    987 using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>;
    988 
    989 class TryItem : public Item {
    990  public:
    991   TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers)
    992       : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
    993   ~TryItem() override { }
    994 
    995   uint32_t StartAddr() const { return start_addr_; }
    996   uint16_t InsnCount() const { return insn_count_; }
    997   const CatchHandler* GetHandlers() const { return handlers_; }
    998 
    999   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1000 
   1001  private:
   1002   uint32_t start_addr_;
   1003   uint16_t insn_count_;
   1004   const CatchHandler* handlers_;
   1005 
   1006   DISALLOW_COPY_AND_ASSIGN(TryItem);
   1007 };
   1008 
   1009 using TryItemVector = std::vector<std::unique_ptr<const TryItem>>;
   1010 
   1011 class CodeFixups {
   1012  public:
   1013   CodeFixups(std::vector<TypeId*> type_ids,
   1014              std::vector<StringId*> string_ids,
   1015              std::vector<MethodId*> method_ids,
   1016              std::vector<FieldId*> field_ids)
   1017       : type_ids_(std::move(type_ids)),
   1018         string_ids_(std::move(string_ids)),
   1019         method_ids_(std::move(method_ids)),
   1020         field_ids_(std::move(field_ids)) { }
   1021 
   1022   const std::vector<TypeId*>& TypeIds() const { return type_ids_; }
   1023   const std::vector<StringId*>& StringIds() const { return string_ids_; }
   1024   const std::vector<MethodId*>& MethodIds() const { return method_ids_; }
   1025   const std::vector<FieldId*>& FieldIds() const { return field_ids_; }
   1026 
   1027  private:
   1028   std::vector<TypeId*> type_ids_;
   1029   std::vector<StringId*> string_ids_;
   1030   std::vector<MethodId*> method_ids_;
   1031   std::vector<FieldId*> field_ids_;
   1032 
   1033   DISALLOW_COPY_AND_ASSIGN(CodeFixups);
   1034 };
   1035 
   1036 class CodeItem : public Item {
   1037  public:
   1038   CodeItem(uint16_t registers_size,
   1039            uint16_t ins_size,
   1040            uint16_t outs_size,
   1041            DebugInfoItem* debug_info,
   1042            uint32_t insns_size,
   1043            uint16_t* insns,
   1044            TryItemVector* tries,
   1045            CatchHandlerVector* handlers)
   1046       : registers_size_(registers_size),
   1047         ins_size_(ins_size),
   1048         outs_size_(outs_size),
   1049         debug_info_(debug_info),
   1050         insns_size_(insns_size),
   1051         insns_(insns),
   1052         tries_(tries),
   1053         handlers_(handlers) { }
   1054 
   1055   ~CodeItem() override { }
   1056 
   1057   uint16_t RegistersSize() const { return registers_size_; }
   1058   uint16_t InsSize() const { return ins_size_; }
   1059   uint16_t OutsSize() const { return outs_size_; }
   1060   uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); }
   1061   DebugInfoItem* DebugInfo() const { return debug_info_; }
   1062   uint32_t InsnsSize() const { return insns_size_; }
   1063   uint16_t* Insns() const { return insns_.get(); }
   1064   TryItemVector* Tries() const { return tries_.get(); }
   1065   CatchHandlerVector* Handlers() const { return handlers_.get(); }
   1066 
   1067   void SetCodeFixups(CodeFixups* fixups) { fixups_.reset(fixups); }
   1068   CodeFixups* GetCodeFixups() const { return fixups_.get(); }
   1069 
   1070   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1071 
   1072   IterationRange<DexInstructionIterator> Instructions() const {
   1073     return MakeIterationRange(DexInstructionIterator(Insns(), 0u),
   1074                               DexInstructionIterator(Insns(), InsnsSize()));
   1075   }
   1076 
   1077  private:
   1078   uint16_t registers_size_;
   1079   uint16_t ins_size_;
   1080   uint16_t outs_size_;
   1081   DebugInfoItem* debug_info_;  // This can be nullptr.
   1082   uint32_t insns_size_;
   1083   std::unique_ptr<uint16_t[]> insns_;
   1084   std::unique_ptr<TryItemVector> tries_;  // This can be nullptr.
   1085   std::unique_ptr<CatchHandlerVector> handlers_;  // This can be nullptr.
   1086   std::unique_ptr<CodeFixups> fixups_;  // This can be nullptr.
   1087 
   1088   DISALLOW_COPY_AND_ASSIGN(CodeItem);
   1089 };
   1090 
   1091 class DebugInfoItem : public Item {
   1092  public:
   1093   DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info)
   1094      : debug_info_size_(debug_info_size), debug_info_(debug_info) { }
   1095 
   1096   uint32_t GetDebugInfoSize() const { return debug_info_size_; }
   1097   uint8_t* GetDebugInfo() const { return debug_info_.get(); }
   1098 
   1099  private:
   1100   uint32_t debug_info_size_;
   1101   std::unique_ptr<uint8_t[]> debug_info_;
   1102 
   1103   DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
   1104 };
   1105 
   1106 class AnnotationItem : public Item {
   1107  public:
   1108   AnnotationItem(uint8_t visibility, EncodedAnnotation* annotation)
   1109       : visibility_(visibility), annotation_(annotation) { }
   1110 
   1111   uint8_t GetVisibility() const { return visibility_; }
   1112   EncodedAnnotation* GetAnnotation() const { return annotation_.get(); }
   1113 
   1114   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1115 
   1116  private:
   1117   uint8_t visibility_;
   1118   std::unique_ptr<EncodedAnnotation> annotation_;
   1119 
   1120   DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
   1121 };
   1122 
   1123 class AnnotationSetItem : public Item {
   1124  public:
   1125   explicit AnnotationSetItem(std::vector<AnnotationItem*>* items) : items_(items) {
   1126     size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
   1127   }
   1128   ~AnnotationSetItem() override { }
   1129 
   1130   std::vector<AnnotationItem*>* GetItems() { return items_.get(); }
   1131 
   1132   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1133 
   1134  private:
   1135   std::unique_ptr<std::vector<AnnotationItem*>> items_;
   1136 
   1137   DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
   1138 };
   1139 
   1140 class AnnotationSetRefList : public Item {
   1141  public:
   1142   explicit AnnotationSetRefList(std::vector<AnnotationSetItem*>* items) : items_(items) {
   1143     size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
   1144   }
   1145   ~AnnotationSetRefList() override { }
   1146 
   1147   std::vector<AnnotationSetItem*>* GetItems() { return items_.get(); }
   1148 
   1149   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1150 
   1151  private:
   1152   std::unique_ptr<std::vector<AnnotationSetItem*>> items_;  // Elements of vector can be nullptr.
   1153 
   1154   DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
   1155 };
   1156 
   1157 class FieldAnnotation {
   1158  public:
   1159   FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item)
   1160       : field_id_(field_id), annotation_set_item_(annotation_set_item) { }
   1161 
   1162   FieldId* GetFieldId() const { return field_id_; }
   1163   AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
   1164 
   1165  private:
   1166   FieldId* field_id_;
   1167   AnnotationSetItem* annotation_set_item_;
   1168 
   1169   DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
   1170 };
   1171 
   1172 using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>;
   1173 
   1174 class MethodAnnotation {
   1175  public:
   1176   MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item)
   1177       : method_id_(method_id), annotation_set_item_(annotation_set_item) { }
   1178 
   1179   MethodId* GetMethodId() const { return method_id_; }
   1180   AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
   1181 
   1182  private:
   1183   MethodId* method_id_;
   1184   AnnotationSetItem* annotation_set_item_;
   1185 
   1186   DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
   1187 };
   1188 
   1189 using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>;
   1190 
   1191 class ParameterAnnotation {
   1192  public:
   1193   ParameterAnnotation(MethodId* method_id, AnnotationSetRefList* annotations)
   1194       : method_id_(method_id), annotations_(annotations) { }
   1195 
   1196   MethodId* GetMethodId() const { return method_id_; }
   1197   AnnotationSetRefList* GetAnnotations() { return annotations_; }
   1198 
   1199  private:
   1200   MethodId* method_id_;
   1201   AnnotationSetRefList* annotations_;
   1202 
   1203   DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
   1204 };
   1205 
   1206 using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>;
   1207 
   1208 class AnnotationsDirectoryItem : public Item {
   1209  public:
   1210   AnnotationsDirectoryItem(AnnotationSetItem* class_annotation,
   1211                            FieldAnnotationVector* field_annotations,
   1212                            MethodAnnotationVector* method_annotations,
   1213                            ParameterAnnotationVector* parameter_annotations)
   1214       : class_annotation_(class_annotation),
   1215         field_annotations_(field_annotations),
   1216         method_annotations_(method_annotations),
   1217         parameter_annotations_(parameter_annotations) { }
   1218 
   1219   AnnotationSetItem* GetClassAnnotation() const { return class_annotation_; }
   1220   FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); }
   1221   MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); }
   1222   ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); }
   1223 
   1224   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1225 
   1226  private:
   1227   AnnotationSetItem* class_annotation_;  // This can be nullptr.
   1228   std::unique_ptr<FieldAnnotationVector> field_annotations_;  // This can be nullptr.
   1229   std::unique_ptr<MethodAnnotationVector> method_annotations_;  // This can be nullptr.
   1230   std::unique_ptr<ParameterAnnotationVector> parameter_annotations_;  // This can be nullptr.
   1231 
   1232   DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
   1233 };
   1234 
   1235 class CallSiteId : public IndexedItem {
   1236  public:
   1237   explicit CallSiteId(EncodedArrayItem* call_site_item) : call_site_item_(call_site_item) {
   1238     size_ = kCallSiteIdItemSize;
   1239   }
   1240   ~CallSiteId() override { }
   1241 
   1242   static size_t ItemSize() { return kCallSiteIdItemSize; }
   1243 
   1244   EncodedArrayItem* CallSiteItem() const { return call_site_item_; }
   1245 
   1246   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
   1247 
   1248  private:
   1249   EncodedArrayItem* call_site_item_;
   1250 
   1251   DISALLOW_COPY_AND_ASSIGN(CallSiteId);
   1252 };
   1253 
   1254 class MethodHandleItem : public IndexedItem {
   1255  public:
   1256   MethodHandleItem(DexFile::MethodHandleType method_handle_type, IndexedItem* field_or_method_id)
   1257       : method_handle_type_(method_handle_type),
   1258         field_or_method_id_(field_or_method_id) {
   1259     size_ = kMethodHandleItemSize;
   1260   }
   1261   ~MethodHandleItem() override { }
   1262 
   1263   static size_t ItemSize() { return kMethodHandleItemSize; }
   1264 
   1265   DexFile::MethodHandleType GetMethodHandleType() const { return method_handle_type_; }
   1266   IndexedItem* GetFieldOrMethodId() const { return field_or_method_id_; }
   1267 
   1268   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
   1269 
   1270  private:
   1271   DexFile::MethodHandleType method_handle_type_;
   1272   IndexedItem* field_or_method_id_;
   1273 
   1274   DISALLOW_COPY_AND_ASSIGN(MethodHandleItem);
   1275 };
   1276 
   1277 using HiddenapiFlagsMap = SafeMap<const Item*, uint32_t>;
   1278 
   1279 class HiddenapiClassData : public IndexedItem {
   1280  public:
   1281   HiddenapiClassData(const ClassDef* class_def, std::unique_ptr<HiddenapiFlagsMap> flags)
   1282       : class_def_(class_def), flags_(std::move(flags)) { }
   1283   ~HiddenapiClassData() override { }
   1284 
   1285   const ClassDef* GetClassDef() const { return class_def_; }
   1286 
   1287   uint32_t GetFlags(const Item* field_or_method_item) const {
   1288     return (flags_ == nullptr) ? 0u : flags_->Get(field_or_method_item);
   1289   }
   1290 
   1291   static uint32_t GetFlags(Header* header, ClassDef* class_def, const Item* field_or_method_item) {
   1292     DCHECK(header != nullptr);
   1293     DCHECK(class_def != nullptr);
   1294     return (header->HiddenapiClassDatas().Empty())
   1295         ? 0u
   1296         : header->HiddenapiClassDatas()[class_def->GetIndex()]->GetFlags(field_or_method_item);
   1297   }
   1298 
   1299   uint32_t ItemSize() const {
   1300     uint32_t size = 0u;
   1301     bool has_non_zero_entries = false;
   1302     if (flags_ != nullptr) {
   1303       for (const auto& entry : *flags_) {
   1304         size += UnsignedLeb128Size(entry.second);
   1305         has_non_zero_entries |= (entry.second != 0u);
   1306       }
   1307     }
   1308     return has_non_zero_entries ? size : 0u;
   1309   }
   1310 
   1311   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1312 
   1313  private:
   1314   const ClassDef* class_def_;
   1315   std::unique_ptr<HiddenapiFlagsMap> flags_;
   1316 
   1317   DISALLOW_COPY_AND_ASSIGN(HiddenapiClassData);
   1318 };
   1319 
   1320 // TODO(sehr): implement MapList.
   1321 class MapList : public Item {
   1322  public:
   1323   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1324 
   1325  private:
   1326   DISALLOW_COPY_AND_ASSIGN(MapList);
   1327 };
   1328 
   1329 class MapItem : public Item {
   1330  public:
   1331   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1332 
   1333  private:
   1334   DISALLOW_COPY_AND_ASSIGN(MapItem);
   1335 };
   1336 
   1337 // Interface for building a vector of file sections for use by other clients.
   1338 struct DexFileSection {
   1339  public:
   1340   DexFileSection(const std::string& name, uint16_t type, uint32_t size, uint32_t offset)
   1341       : name(name), type(type), size(size), offset(offset) { }
   1342   std::string name;
   1343   // The type (DexFile::MapItemType).
   1344   uint16_t type;
   1345   // The size (in elements, not bytes).
   1346   uint32_t size;
   1347   // The byte offset from the start of the file.
   1348   uint32_t offset;
   1349 };
   1350 
   1351 enum class SortDirection {
   1352   kSortAscending,
   1353   kSortDescending
   1354 };
   1355 
   1356 std::vector<DexFileSection> GetSortedDexFileSections(dex_ir::Header* header,
   1357                                                      SortDirection direction);
   1358 
   1359 }  // namespace dex_ir
   1360 }  // namespace art
   1361 
   1362 #endif  // ART_DEXLAYOUT_DEX_IR_H_
   1363