class BitVector; class ClassLinker; class ClassLoaderContext; class DexProfileMetadata; class ElfFile; template <class MirrorType> class GcRoot; class MemMap; class OatDexFile; class OatHeader; class OatMethodOffsets; class OatQuickMethodHeader; class VdexFile;
// A special compilation reason to indicate that only the VDEX file is usable. static constexpr constchar* kReasonVdex = "vdex"; // A special compilation reason to indicate that only the VDEX file in the DM file is usable. static constexpr constchar* kReasonVdexDm = "vdex-dm";
// OatMethodOffsets are currently 5x32-bits=160-bits long, so if we can // save even one OatMethodOffsets struct, the more complicated encoding // using a bitmap pays for itself since few classes will have 160 // methods. enumclass OatClassType : uint8_t {
kAllCompiled = 0, // OatClass is followed by an OatMethodOffsets for each method.
kSomeCompiled = 1, // A bitmap of OatMethodOffsets that are present follows the OatClass.
kNoneCompiled = 2, // All methods are interpreted so no OatMethodOffsets are necessary.
kLast = kNoneCompiled
};
// Runtime representation of the OAT file format which holds compiler output. // The class opens an OAT file from storage and maps it to memory, typically with // dlopen and provides access to its internal data structures (see OatWriter for // for more details about the OAT format). // In the process of loading OAT, the class also loads the associated VDEX file // with the input DEX files (see VdexFile for details about the VDEX format). // The raw DEX data are accessible transparently through the OatDexFile objects.
class OatFile { public: // The zip separator. This has to be the one that Bionic's dlopen recognizes because oat files are // opened through dlopen in `DlOpenOatFile`. This is different from the ART's zip separator for // MultiDex. static constexpr constchar* kZipSeparator = "!/";
// Open an oat file. Returns null on failure. // The `dex_filenames` argument, if provided, overrides the dex locations // from oat file when opening the dex files if they are not embedded in the // vdex file. These may differ for cross-compilation (the dex file name is // the host path and dex location is the future path on target) and testing.
EXPORT static OatFile* Open(int zip_fd, const std::string& filename, const std::string& location, bool executable, bool low_4gb,
ArrayRef<const std::string> dex_filenames,
ArrayRef<File> dex_files, /*inout*/ MemMap* reservation, // Where to load if not null. /*out*/ std::string* error_msg); // Helper overload that takes a single dex filename and no reservation.
EXPORT static OatFile* Open(int zip_fd, const std::string& filename, const std::string& location, bool executable, bool low_4gb, const std::string& dex_filename, /*out*/ std::string* error_msg) { return Open(zip_fd,
filename,
location,
executable,
low_4gb,
ArrayRef<const std::string>(&dex_filename, /*size=*/1u), /*dex_files=*/{}, // not currently supported /*reservation=*/nullptr,
error_msg);
} // Helper overload that takes no dex filename and no reservation. static OatFile* Open(int zip_fd, const std::string& filename, const std::string& location, bool executable, bool low_4gb, /*out*/std::string* error_msg) { return Open(zip_fd,
filename,
location,
executable,
low_4gb, /*dex_filenames=*/{}, /*dex_files=*/{}, // not currently supported /*reservation=*/nullptr,
error_msg);
}
// Similar to OatFile::Open(const std::string...), but accepts input vdex and // odex files as file descriptors. We also take zip_fd in case the vdex does not // contain the dex code, and we need to read it from the zip file. static OatFile* Open(int zip_fd, int vdex_fd, int oat_fd, const std::string& oat_location, bool executable, bool low_4gb,
ArrayRef<const std::string> dex_filenames,
ArrayRef<File> dex_files, /*inout*/ MemMap* reservation, // Where to load if not null. /*out*/ std::string* error_msg);
// Initialize OatFile instance from an already loaded VdexFile. This assumes // the vdex does not have a dex section and accepts a vector of DexFiles separately. static OatFile* OpenFromVdex(const std::vector<const DexFile*>& dex_files,
std::unique_ptr<VdexFile>&& vdex_file, const std::string& location,
ClassLoaderContext* context);
// Initialize OatFile instance from an already loaded VdexFile. The dex files // will be opened through `zip_fd` or `dex_location` if `zip_fd` is -1. static OatFile* OpenFromVdex(int zip_fd,
std::unique_ptr<VdexFile>&& vdex_file, const std::string& location,
ClassLoaderContext* context, constchar* reason,
std::string* error_msg);
class OatMethod final { public:
uint32_t GetCodeOffset() const { return code_offset_; }
constvoid* GetQuickCode() const;
// Returns size of quick code.
uint32_t GetQuickCodeSize() const;
// Returns OatQuickMethodHeader for debugging. Most callers should // use more specific methods such as GetQuickCodeSize. const OatQuickMethodHeader* GetOatQuickMethodHeader() const;
uint32_t GetOatQuickMethodHeaderOffset() const;
// Create an OatMethod with offsets relative to the given base address
OatMethod(const uint8_t* base, const uint32_t code_offset)
: begin_(base), code_offset_(code_offset) {
}
OatMethod(const OatMethod&) = default;
~OatMethod() {}
OatMethod& operator=(const OatMethod&) = default;
// A representation of an invalid OatMethod, used when an OatMethod or OatClass can't be found. // See ClassLinker::FindOatMethodFor. staticconst OatMethod Invalid() { return OatMethod(nullptr, -1);
}
class OatClass final { public:
ClassStatus GetStatus() const { return status_;
}
OatClassType GetType() const { return type_;
}
// Get the OatMethod entry based on its index into the class // defintion. Direct methods come first, followed by virtual // methods. Note that runtime created methods such as miranda // methods are not included.
EXPORT const OatMethod GetOatMethod(uint32_t method_index) const;
// Return a pointer to the OatMethodOffsets for the requested // method_index, or null if none is present. Note that most // callers should use GetOatMethod.
EXPORT const OatMethodOffsets* GetOatMethodOffsets(uint32_t method_index) const;
// Return the offset from the start of the OatFile to the // OatMethodOffsets for the requested method_index, or 0 if none // is present. Note that most callers should use GetOatMethod.
EXPORT uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const;
// A representation of an invalid OatClass, used when an OatClass can't be found. // See FindOatClass(). static OatClass Invalid() { return OatClass(/* oat_file= */ nullptr,
ClassStatus::kErrorUnresolved,
OatClassType::kNoneCompiled, /* num_methods= */ 0, /* bitmap_pointer= */ nullptr, /* methods_pointer= */ nullptr);
}
// Get the OatDexFile for the given dex_location within this oat file. // If dex_location_checksum is non-null, the OatDexFile will only be // returned if it has a matching checksum. // If error_msg is non-null and no OatDexFile is returned, error_msg will // be updated with a description of why no OatDexFile was returned. const OatDexFile* GetOatDexFile(constchar* dex_location, /*out*/ std::string* error_msg = nullptr) const
REQUIRES(!secondary_lookup_lock_);
size_t BssMethodsOffset() const { // Note: This is used only for symbolizer and needs to return a valid .bss offset. return (bss_methods_ != nullptr) ? bss_methods_ - BssBegin() : BssRootsOffset();
}
size_t BssRootsOffset() const { // Note: This is used only for symbolizer and needs to return a valid .bss offset. return (bss_roots_ != nullptr) ? bss_roots_ - BssBegin() : BssSize();
}
size_t BssStringsOffset() const { // Note: This is used only for symbolizer and needs to return a valid .bss offset. return (bss_strings_ != nullptr) ? bss_strings_ - BssBegin() : BssSize();
}
// Returns the base address of the ELF file, or nullptr if the oat file is not backed by an ELF // file or an error occurred. virtualconst uint8_t* ComputeElfBegin(std::string* error_msg) const = 0;
// Finds the associated oat class for a dex_file and descriptor. Returns an invalid OatClass on // error and sets found to false.
EXPORT static OatClass FindOatClass(const DexFile& dex_file, uint16_t class_def_idx, bool* found);
// Returns the mapping info of `dex_file` if found in the BcpBssInfo, or nullptr otherwise. const BssMappingInfo* FindBcpMappingInfo(const DexFile* dex_file) const;
private: // The oat file name. // // The image will embed this to link its associated oat file. const std::string location_;
// Pointer to the Vdex file with the Dex files for this Oat file.
std::unique_ptr<VdexFile> vdex_;
// Pointer to OatHeader. const uint8_t* begin_;
// Pointer to end of oat region for bounds checking. const uint8_t* end_;
// Pointer to the .data.img.rel.ro section, if present, otherwise null. const uint8_t* data_img_rel_ro_begin_;
// Pointer to the end of the .data.img.rel.ro section, if present, otherwise null. const uint8_t* data_img_rel_ro_end_;
// Pointer to the beginning of the app image relocations in the .data.img.rel.ro section, // if present, otherwise null. const uint8_t* data_img_rel_ro_app_image_;
// Pointer to the .bss section, if present, otherwise null.
uint8_t* bss_begin_;
// Pointer to the end of the .bss section, if present, otherwise null.
uint8_t* bss_end_;
// Pointer to the beginning of the ArtMethod*s in the .bss section, if present, otherwise null.
uint8_t* bss_methods_;
// Pointer to the beginning of the GC roots in the .bss section, if present, otherwise null.
uint8_t* bss_roots_;
// Pointer to the beginning of the strings in the .bss section, if present, otherwise null.
uint8_t* bss_strings_;
// Was this oat_file loaded executable? constbool is_executable_;
// Owning storage for the OatDexFile objects.
std::vector<const OatDexFile*> oat_dex_files_storage_;
// Mapping info for DexFiles in the BCP.
std::vector<BssMappingInfo> bcp_bss_info_;
// NOTE: We use a std::string_view as the key type to avoid a memory allocation on every // lookup with a const char* key. The std::string_view doesn't own its backing storage, // therefore we're using the OatFile's stored dex location as the backing storage // for keys in oat_dex_files_ and the string_cache_ entries for the backing storage // of keys in secondary_oat_dex_files_ and oat_dex_files_by_canonical_location_. using Table =
AllocationTrackingSafeMap<std::string_view, const OatDexFile*, kAllocatorTagOatFile>;
// Map each location and canonical location (if different) retrieved from the // oat file to its OatDexFile. This map doesn't change after it's constructed in Setup() // and therefore doesn't need any locking and provides the cheapest dex file lookup // for GetOatDexFile() for a very frequent use case. Never contains a null value.
Table oat_dex_files_;
// Lock guarding all members needed for secondary lookup in GetOatDexFile(). mutable Mutex secondary_lookup_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
// If the primary oat_dex_files_ lookup fails, use a secondary map. This map stores // the results of all previous secondary lookups, whether successful (non-null) or // failed (null). If it doesn't contain an entry we need to calculate the canonical // location and use oat_dex_files_by_canonical_location_. mutable Table secondary_oat_dex_files_ GUARDED_BY(secondary_lookup_lock_);
// Cache of strings. Contains the backing storage for keys in the secondary_oat_dex_files_ // and the lazily initialized oat_dex_files_by_canonical_location_. // NOTE: We're keeping references to contained strings in form of std::string_view and adding // new strings to the end. The adding of a new element must not touch any previously stored // elements. std::list<> and std::deque<> satisfy this requirement, std::vector<> doesn't. mutable std::list<std::string> string_cache_ GUARDED_BY(secondary_lookup_lock_);
// Dex files opened directly from a file referenced from the oat file or specifed // by the `dex_filenames` parameter, in case the OatFile does not embed the dex code.
std::vector<std::unique_ptr<const DexFile>> external_dex_files_;
// If set, overrides the APEX versions in the header.
std::optional<std::string> override_apex_versions_ = std::nullopt;
friendclass gc::collector::FakeOatFile; // For modifying begin_ and end_. friendclass OatClass; friendclass art::OatDexFile; friendclass OatDumper; // For GetBase and GetLimit friendclass OatFileBackedByVdex; friendclass OatFileBase;
DISALLOW_COPY_AND_ASSIGN(OatFile);
};
// OatDexFile should be an inner class of OatFile. Unfortunately, C++ doesn't // support forward declarations of inner classes, and we want to // forward-declare OatDexFile so that we can store an opaque pointer to an // OatDexFile in DexFile. class OatDexFile final { public: // Opens the DexFile referred to by this OatDexFile from within the containing OatFile.
EXPORT std::unique_ptr<const DexFile> OpenDexFile(std::string* error_msg) const;
// May return null if the OatDexFile only contains a type lookup table. This case only happens // for the compiler to speed up compilation, or in jitzygote. const OatFile* GetOatFile() const { return oat_file_;
}
// Returns the size of the DexFile refered to by this OatDexFile.
EXPORT size_t FileSize() const;
// Returns original path of DexFile that was the source of this OatDexFile. const std::string& GetDexFileLocation() const { return dex_file_location_;
}
// Returns original path of DexFile that was the source of this OatDexFile. const std::string& GetLocation() const { return dex_file_location_; }
// Returns the canonical location of DexFile that was the source of this OatDexFile. const std::string& GetCanonicalDexFileLocation() const { return canonical_dex_file_location_;
}
// Returns checksum of original DexFile that was the source of this OatDexFile;
uint32_t GetDexFileLocationChecksum() const { return dex_file_location_checksum_;
}
// Returns checksum of original DexFile that was the source of this OatDexFile;
uint32_t GetLocationChecksum() const { return dex_file_location_checksum_; }
// Returns the OatClass for the class specified by the given DexFile class_def_index.
EXPORT OatFile::OatClass GetOatClass(uint16_t class_def_index) const;
// Returns the offset to the OatClass information. Most callers should use GetOatClass.
EXPORT uint32_t GetOatClassOffset(uint16_t class_def_index) const;
// Looks up a class definition by its class descriptor. Hash must be // ComputeModifiedUtf8Hash(descriptor).
EXPORT staticconst dex::ClassDef* FindClassDef(const DexFile& dex_file,
std::string_view descriptor,
size_t hash);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.