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