verifier_deps_->Encode(dex_files_, &buffer);
ASSERT_FALSE(buffer.empty());
- VerifierDeps decoded_deps(dex_files_, ArrayRef<uint8_t>(buffer));
+ VerifierDeps decoded_deps(dex_files_, ArrayRef<const uint8_t>(buffer));
ASSERT_TRUE(verifier_deps_->Equals(decoded_deps));
}
}
// Dump the new verifier deps to ensure it can properly read the data.
- VerifierDeps decoded_deps(dex_files, ArrayRef<uint8_t>(buffer));
+ VerifierDeps decoded_deps(dex_files, ArrayRef<const uint8_t>(buffer));
std::ostringstream stream;
VariableIndentationOutputStream os(&stream);
decoded_deps.Dump(&os);
#include "type_lookup_table.h"
#include "vdex_file.h"
#include "verifier/method_verifier.h"
+#include "verifier/verifier_deps.h"
#include "well_known_classes.h"
#include <sys/stat.h>
os << "\n";
if (!options_.dump_header_only_) {
+ VariableIndentationOutputStream vios(&os);
+ VdexFile::Header vdex_header = oat_file_.GetVdexFile()->GetHeader();
+ if (vdex_header.IsValid()) {
+ std::string error_msg;
+ std::vector<const DexFile*> dex_files;
+ for (size_t i = 0; i < oat_dex_files_.size(); i++) {
+ const DexFile* dex_file = OpenDexFile(oat_dex_files_[i], &error_msg);
+ if (dex_file == nullptr) {
+ os << "Error opening dex file: " << error_msg << std::endl;
+ return false;
+ }
+ dex_files.push_back(dex_file);
+ }
+ verifier::VerifierDeps deps(dex_files, oat_file_.GetVdexFile()->GetVerifierDepsData());
+ deps.Dump(&vios);
+ } else {
+ os << "UNRECOGNIZED vdex file, magic "
+ << vdex_header.GetMagic()
+ << ", version "
+ << vdex_header.GetVersion()
+ << "\n";
+ }
for (size_t i = 0; i < oat_dex_files_.size(); i++) {
const OatFile::OatDexFile* oat_dex_file = oat_dex_files_[i];
CHECK(oat_dex_file != nullptr);
#include <stdint.h>
#include <string>
+#include "base/array_ref.h"
#include "base/macros.h"
#include "mem_map.h"
#include "os.h"
public:
Header(uint32_t dex_size, uint32_t verifier_deps_size, uint32_t quickening_info_size);
+ const char* GetMagic() const { return reinterpret_cast<const char*>(magic_); }
+ const char* GetVersion() const { return reinterpret_cast<const char*>(version_); }
bool IsMagicValid() const;
bool IsVersionValid() const;
+ bool IsValid() const { return IsMagicValid() && IsVersionValid(); }
uint32_t GetDexSize() const { return dex_size_; }
uint32_t GetVerifierDepsSize() const { return verifier_deps_size_; }
const uint8_t* End() const { return mmap_->End(); }
size_t Size() const { return mmap_->Size(); }
+ const Header& GetHeader() const {
+ return *reinterpret_cast<const Header*>(Begin());
+ }
+
+ ArrayRef<const uint8_t> GetVerifierDepsData() const {
+ return ArrayRef<const uint8_t>(
+ Begin() + sizeof(Header) + GetHeader().GetDexSize(), GetHeader().GetVerifierDepsSize());
+ }
+
private:
explicit VdexFile(MemMap* mmap) : mmap_(mmap) {}
}
}
-VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files, ArrayRef<uint8_t> data)
+VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files,
+ ArrayRef<const uint8_t> data)
: VerifierDeps(dex_files) {
+ if (data.empty()) {
+ // Return eagerly, as the first thing we expect from VerifierDeps data is
+ // the number of created strings, even if there is no dependency.
+ // Currently, only the boot image does not have any VerifierDeps data.
+ return;
+ }
const uint8_t* data_start = data.data();
const uint8_t* data_end = data_start + data.size();
for (const DexFile* dex_file : dex_files) {
explicit VerifierDeps(const std::vector<const DexFile*>& dex_files)
REQUIRES(!Locks::verifier_deps_lock_);
+ VerifierDeps(const std::vector<const DexFile*>& dex_files,
+ ArrayRef<const uint8_t> data)
+ REQUIRES(!Locks::verifier_deps_lock_);
+
// Record the verification status of the class at `type_idx`.
static void MaybeRecordVerificationStatus(const DexFile& dex_file,
uint16_t type_idx,
private:
static constexpr uint16_t kUnresolvedMarker = static_cast<uint16_t>(-1);
- // Only used in tests to reconstruct the data structure from serialized data.
- VerifierDeps(const std::vector<const DexFile*>& dex_files, ArrayRef<uint8_t> data)
- REQUIRES(!Locks::verifier_deps_lock_);
-
using ClassResolutionBase = std::tuple<uint32_t, uint16_t>;
struct ClassResolution : public ClassResolutionBase {
ClassResolution() = default;