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