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