blob: da7d60ac2ff2d03f6138e9ebfb801683d1e9ce57 [file] [log] [blame]
Alex Light40528472017-03-28 09:07:36 -07001/* Copyright (C) 2017 The Android Open Source Project
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This file implements interfaces from the file jvmti.h. This implementation
5 * is licensed under the same terms as the file jvmti.h. The
6 * copyright and license information for the file jvmti.h follows.
7 *
8 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10 *
11 * This code is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 only, as
13 * published by the Free Software Foundation. Oracle designates this
14 * particular file as subject to the "Classpath" exception as provided
15 * by Oracle in the LICENSE file that accompanied this code.
16 *
17 * This code is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * version 2 for more details (a copy is included in the LICENSE file that
21 * accompanied this code).
22 *
23 * You should have received a copy of the GNU General Public License version
24 * 2 along with this work; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 *
27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28 * or visit www.oracle.com if you need additional information or have any
29 * questions.
30 */
31
32#include "fixed_up_dex_file.h"
David Sehr9e734c72018-01-04 17:56:19 -080033#include "dex/dex_file-inl.h"
34#include "dex/dex_file_loader.h"
Alex Light40528472017-03-28 09:07:36 -070035
Alex Light40528472017-03-28 09:07:36 -070036// Runtime includes.
Mathieu Chartier21cf2582018-01-08 17:09:48 -080037#include "dex/compact_dex_level.h"
Nicolas Geoffray4e868fa2017-04-21 17:16:44 +010038#include "dex_to_dex_decompiler.h"
Mathieu Chartier21cf2582018-01-08 17:09:48 -080039#include "dexlayout.h"
Alex Light40528472017-03-28 09:07:36 -070040#include "oat_file.h"
41#include "vdex_file.h"
42
43namespace openjdkjvmti {
44
45static void RecomputeDexChecksum(art::DexFile* dex_file)
46 REQUIRES_SHARED(art::Locks::mutator_lock_) {
47 reinterpret_cast<art::DexFile::Header*>(const_cast<uint8_t*>(dex_file->Begin()))->checksum_ =
48 dex_file->CalculateChecksum();
49}
50
Nicolas Geoffrayb02ba932017-07-13 15:53:54 +010051static void DoDexUnquicken(const art::DexFile& new_dex_file, const art::DexFile& original_dex_file)
Alex Light40528472017-03-28 09:07:36 -070052 REQUIRES_SHARED(art::Locks::mutator_lock_) {
53 const art::OatDexFile* oat_dex = original_dex_file.GetOatDexFile();
54 if (oat_dex == nullptr) {
55 return;
56 }
57 const art::OatFile* oat_file = oat_dex->GetOatFile();
58 if (oat_file == nullptr) {
59 return;
60 }
61 const art::VdexFile* vdex = oat_file->GetVdexFile();
Nicolas Geoffrayb02ba932017-07-13 15:53:54 +010062 if (vdex == nullptr) {
Alex Light40528472017-03-28 09:07:36 -070063 return;
64 }
Nicolas Geoffray67169412018-01-12 09:06:14 +000065 art::VdexFile::UnquickenDexFile(
66 new_dex_file, vdex->GetQuickeningInfo(), /* decompile_return_instruction */true);
Alex Light40528472017-03-28 09:07:36 -070067}
68
69std::unique_ptr<FixedUpDexFile> FixedUpDexFile::Create(const art::DexFile& original) {
70 // Copy the data into mutable memory.
71 std::vector<unsigned char> data;
72 data.resize(original.Size());
73 memcpy(data.data(), original.Begin(), original.Size());
74 std::string error;
Mathieu Chartier79c87da2017-10-10 11:54:29 -070075 std::unique_ptr<const art::DexFile> new_dex_file(art::DexFileLoader::Open(
Alex Light40528472017-03-28 09:07:36 -070076 data.data(),
77 data.size(),
78 /*location*/"Unquickening_dexfile.dex",
79 /*location_checksum*/0,
80 /*oat_dex_file*/nullptr,
81 /*verify*/false,
82 /*verify_checksum*/false,
83 &error));
84 if (new_dex_file.get() == nullptr) {
85 LOG(ERROR) << "Unable to open dex file from memory for unquickening! error: " << error;
86 return nullptr;
87 }
88
89 DoDexUnquicken(*new_dex_file, original);
Mathieu Chartier21cf2582018-01-08 17:09:48 -080090
91 if (original.IsCompactDexFile()) {
92 // Since we are supposed to return a standard dex, convert back using dexlayout.
93 art::Options options;
94 options.output_to_memmap_ = true;
95 options.compact_dex_level_ = art::CompactDexLevel::kCompactDexLevelNone;
96 options.update_checksum_ = true;
97 art::DexLayout dex_layout(options, nullptr, nullptr);
98 dex_layout.ProcessDexFile(new_dex_file->GetLocation().c_str(), new_dex_file.get(), 0);
99 std::unique_ptr<art::MemMap> mem_map(dex_layout.GetAndReleaseMemMap());
100
101 const uint32_t dex_file_size =
102 reinterpret_cast<const art::DexFile::Header*>(mem_map->Begin())->file_size_;
103 // Overwrite the dex file stored in data with the new result.
104 data.clear();
105 data.insert(data.end(), mem_map->Begin(), mem_map->Begin() + dex_file_size);
106 new_dex_file = art::DexFileLoader::Open(
107 data.data(),
108 data.size(),
109 /*location*/"Unquickening_dexfile.dex",
110 /*location_checksum*/0,
111 /*oat_dex_file*/nullptr,
112 /*verify*/false,
113 /*verify_checksum*/false,
114 &error);
115 }
116
Alex Light40528472017-03-28 09:07:36 -0700117 RecomputeDexChecksum(const_cast<art::DexFile*>(new_dex_file.get()));
118 std::unique_ptr<FixedUpDexFile> ret(new FixedUpDexFile(std::move(new_dex_file), std::move(data)));
119 return ret;
120}
121
122} // namespace openjdkjvmti