1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ART_LIBDEXFILE_DEX_STANDARD_DEX_FILE_H_
#define ART_LIBDEXFILE_DEX_STANDARD_DEX_FILE_H_
#include <iosfwd>
#include "dex_file.h"
namespace art {
class OatDexFile;
// Standard dex file. This is the format that is packaged in APKs and produced by tools.
class StandardDexFile : public DexFile {
public:
class Header : public DexFile::Header {
// Same for now.
};
struct CodeItem : public dex::CodeItem {
static constexpr size_t kAlignment = 4;
static constexpr size_t InsSizeOffset() {
return OFFSETOF_MEMBER(CodeItem, ins_size_);
}
static constexpr size_t OutsSizeOffset() {
return OFFSETOF_MEMBER(CodeItem, outs_size_);
}
static constexpr size_t RegistersSizeOffset() {
return OFFSETOF_MEMBER(CodeItem, registers_size_);
}
static constexpr size_t InsnsOffset() {
return OFFSETOF_MEMBER(CodeItem, insns_);
}
private:
CodeItem() = default;
uint16_t registers_size_; // the number of registers used by this code
// (locals + parameters)
uint16_t ins_size_; // the number of words of incoming arguments to the method
// that this code is for
uint16_t outs_size_; // the number of words of outgoing argument space required
// by this code for method invocation
uint16_t tries_size_; // the number of try_items for this instance. If non-zero,
// then these appear as the tries array just after the
// insns in this instance.
uint32_t debug_info_off_; // Holds file offset to debug info stream.
uint32_t insns_size_in_code_units_; // size of the insns array, in 2 byte code units
uint16_t insns_[1]; // actual array of bytecode.
ART_FRIEND_TEST(CodeItemAccessorsTest, TestDexInstructionsAccessor);
friend class CodeItemDataAccessor;
friend class CodeItemDebugInfoAccessor;
friend class CodeItemInstructionAccessor;
friend class DexWriter;
friend class StandardDexFile;
DISALLOW_COPY_AND_ASSIGN(CodeItem);
};
// Write the standard dex specific magic.
static void WriteMagic(uint8_t* magic);
// Write the current version, note that the input is the address of the magic.
static void WriteCurrentVersion(uint8_t* magic);
// Write the last version before default method support,
// note that the input is the address of the magic.
static void WriteVersionBeforeDefaultMethods(uint8_t* magic);
static const uint8_t kDexMagic[kDexMagicSize];
static constexpr size_t kNumDexVersions = 5;
static const uint8_t kDexMagicVersions[kNumDexVersions][kDexVersionLen];
// Returns true if the byte string points to the magic value.
static bool IsMagicValid(const uint8_t* magic);
bool IsMagicValid() const override;
// Returns true if the byte string after the magic is the correct value.
static bool IsVersionValid(const uint8_t* magic);
bool IsVersionValid() const override;
bool SupportsDefaultMethods() const override;
uint32_t GetCodeItemSize(const dex::CodeItem& item) const override;
size_t GetDequickenedSize() const override {
// JVMTI will run dex layout on standard dex files that have hidden API data,
// in order to remove that data. As dexlayout may increase the size of the dex file,
// be (very) conservative and add one MB to the size.
return Size() + (HasHiddenapiClassData() ? 1 * MB : 0);
}
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)
: DexFile(base,
size,
/*data_begin*/ base,
/*data_size*/ size,
location,
location_checksum,
oat_dex_file,
std::move(container),
/*is_compact_dex*/ false) {}
friend class DexFileLoader;
friend class DexFileVerifierTest;
ART_FRIEND_TEST(ClassLinkerTest, RegisterDexFileName); // for constructor
friend class OptimizingUnitTestHelper; // for constructor
DISALLOW_COPY_AND_ASSIGN(StandardDexFile);
};
} // namespace art
#endif // ART_LIBDEXFILE_DEX_STANDARD_DEX_FILE_H_
|