• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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_LIBDEXFILE_DEX_STANDARD_DEX_FILE_H_
18 #define ART_LIBDEXFILE_DEX_STANDARD_DEX_FILE_H_
19 
20 #include <iosfwd>
21 #include <memory>
22 
23 #include "dex_file.h"
24 
25 namespace art {
26 
27 class OatDexFile;
28 
29 // Standard dex file. This is the format that is packaged in APKs and produced by tools.
30 class StandardDexFile : public DexFile {
31  public:
32   class Header : public DexFile::Header {
33     // Same for now.
34   };
35 
36   struct CodeItem : public dex::CodeItem {
37     static constexpr size_t kAlignment = 4;
38 
InsSizeOffsetCodeItem39     static constexpr size_t InsSizeOffset() {
40       return OFFSETOF_MEMBER(CodeItem, ins_size_);
41     }
42 
OutsSizeOffsetCodeItem43     static constexpr size_t OutsSizeOffset() {
44       return OFFSETOF_MEMBER(CodeItem, outs_size_);
45     }
46 
RegistersSizeOffsetCodeItem47     static constexpr size_t RegistersSizeOffset() {
48       return OFFSETOF_MEMBER(CodeItem, registers_size_);
49     }
50 
InsnsOffsetCodeItem51     static constexpr size_t InsnsOffset() {
52       return OFFSETOF_MEMBER(CodeItem, insns_);
53     }
54 
55    private:
56     CodeItem() = default;
57 
58     uint16_t registers_size_;            // the number of registers used by this code
59                                          //   (locals + parameters)
60     uint16_t ins_size_;                  // the number of words of incoming arguments to the method
61                                          //   that this code is for
62     uint16_t outs_size_;                 // the number of words of outgoing argument space required
63                                          //   by this code for method invocation
64     uint16_t tries_size_;                // the number of try_items for this instance. If non-zero,
65                                          //   then these appear as the tries array just after the
66                                          //   insns in this instance.
67     uint32_t debug_info_off_;            // Holds file offset to debug info stream.
68 
69     uint32_t insns_size_in_code_units_;  // size of the insns array, in 2 byte code units
70     uint16_t insns_[1];                  // actual array of bytecode.
71 
72     ART_FRIEND_TEST(CodeItemAccessorsTest, TestDexInstructionsAccessor);
73     friend class CodeItemDataAccessor;
74     friend class CodeItemDebugInfoAccessor;
75     friend class CodeItemInstructionAccessor;
76     friend class DexWriter;
77     friend class StandardDexFile;
78     DISALLOW_COPY_AND_ASSIGN(CodeItem);
79   };
80 
81   // Write the standard dex specific magic.
82   static void WriteMagic(uint8_t* magic);
83 
84   // Write the current version, note that the input is the address of the magic.
85   static void WriteCurrentVersion(uint8_t* magic);
86 
87   // Write the last version before default method support,
88   // note that the input is the address of the magic.
89   static void WriteVersionBeforeDefaultMethods(uint8_t* magic);
90 
91   static const uint8_t kDexMagic[kDexMagicSize];
92   static constexpr size_t kNumDexVersions = 5;
93   static const uint8_t kDexMagicVersions[kNumDexVersions][kDexVersionLen];
94 
95   // Returns true if the byte string points to the magic value.
96   static bool IsMagicValid(const uint8_t* magic);
97   bool IsMagicValid() const override;
98 
99   // Returns true if the byte string after the magic is the correct value.
100   static bool IsVersionValid(const uint8_t* magic);
101   bool IsVersionValid() const override;
102 
103   bool SupportsDefaultMethods() const override;
104 
105   uint32_t GetCodeItemSize(const dex::CodeItem& item) const override;
106 
GetDequickenedSize()107   size_t GetDequickenedSize() const override {
108     // JVMTI will run dex layout on standard dex files that have hidden API data,
109     // in order to remove that data. As dexlayout may increase the size of the dex file,
110     // be (very) conservative and add one MB to the size.
111     return Size() + (HasHiddenapiClassData() ? 1 * MB : 0);
112   }
113 
114  private:
StandardDexFile(const uint8_t * base,size_t size,const std::string & location,uint32_t location_checksum,const OatDexFile * oat_dex_file,std::shared_ptr<DexFileContainer> container)115   StandardDexFile(const uint8_t* base,
116                   size_t size,
117                   const std::string& location,
118                   uint32_t location_checksum,
119                   const OatDexFile* oat_dex_file,
120                   // Shared since several dex files may be stored in the same logical container.
121                   std::shared_ptr<DexFileContainer> container)
122       : DexFile(base,
123                 size,
124                 location,
125                 location_checksum,
126                 oat_dex_file,
127                 std::move(container),
128                 /*is_compact_dex*/ false) {}
129 
130   friend class DexFileLoader;
131   friend class DexFileVerifierTest;
132 
133   ART_FRIEND_TEST(ClassLinkerTest, RegisterDexFileName);  // for constructor
134   friend class OptimizingUnitTestHelper;  // for constructor
135 
136   DISALLOW_COPY_AND_ASSIGN(StandardDexFile);
137 };
138 
139 }  // namespace art
140 
141 #endif  // ART_LIBDEXFILE_DEX_STANDARD_DEX_FILE_H_
142