blob: 391d597b832fe3d9ceea857680b1d91cb99b7d45 [file] [log] [blame]
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001/*
2 * Copyright (C) 2015 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#include "oat_file_manager.h"
18
19#include <memory>
20#include <queue>
21#include <vector>
David Brazdil35a3f6a2019-03-04 15:59:06 +000022#include <sys/stat.h>
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070023
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +010024#include "android-base/file.h"
Andreas Gampe46ee31b2016-12-14 10:11:49 -080025#include "android-base/stringprintf.h"
Nicolas Geoffray68bf3902017-09-07 14:40:48 +010026#include "android-base/strings.h"
Andreas Gampe46ee31b2016-12-14 10:11:49 -080027
Andreas Gampe90b936d2017-01-31 08:58:55 -080028#include "art_field-inl.h"
Jeff Hao8ec0a202017-03-07 21:56:31 -080029#include "base/bit_vector-inl.h"
David Sehr891a50e2017-10-27 17:01:07 -070030#include "base/file_utils.h"
Andreas Gampe57943812017-12-06 21:39:13 -080031#include "base/logging.h" // For VLOG.
Andreas Gampe7fbc4a52018-11-28 08:26:47 -080032#include "base/mutex-inl.h"
David Brazdil527072e2019-04-03 15:15:40 +010033#include "base/sdk_version.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070034#include "base/stl_util.h"
Mathieu Chartier32ce2ad2016-03-04 14:58:03 -080035#include "base/systrace.h"
Mathieu Chartierfbc31082016-01-24 11:59:56 -080036#include "class_linker.h"
Calin Juravle7b0648a2017-07-07 18:40:50 -070037#include "class_loader_context.h"
David Sehr013fd802018-01-11 22:55:24 -080038#include "dex/art_dex_file_loader.h"
David Sehr9e734c72018-01-04 17:56:19 -080039#include "dex/dex_file-inl.h"
40#include "dex/dex_file_loader.h"
41#include "dex/dex_file_tracking_registrar.h"
Mathieu Chartier61d2b2d2016-02-04 13:31:46 -080042#include "gc/scoped_gc_critical_section.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070043#include "gc/space/image_space.h"
Mathieu Chartierfbc31082016-01-24 11:59:56 -080044#include "handle_scope-inl.h"
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +010045#include "jit/jit.h"
David Brazdil331a5e12019-04-01 22:46:16 +000046#include "jni/java_vm_ext.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010047#include "jni/jni_internal.h"
Mathieu Chartierfbc31082016-01-24 11:59:56 -080048#include "mirror/class_loader.h"
Andreas Gampe90b936d2017-01-31 08:58:55 -080049#include "mirror/object-inl.h"
Alex Light2ce6fc82017-12-18 16:42:36 -080050#include "oat_file.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070051#include "oat_file_assistant.h"
Mathieu Chartier3398c782016-09-30 10:27:43 -070052#include "obj_ptr-inl.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070053#include "scoped_thread_state_change-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070054#include "thread-current-inl.h"
Mathieu Chartiera9d82fe2016-01-25 20:06:11 -080055#include "thread_list.h"
David Brazdil331a5e12019-04-01 22:46:16 +000056#include "thread_pool.h"
David Brazdil35a3f6a2019-03-04 15:59:06 +000057#include "vdex_file.h"
58#include "verifier/verifier_deps.h"
Andreas Gampe90b936d2017-01-31 08:58:55 -080059#include "well_known_classes.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070060
61namespace art {
62
Andreas Gampe46ee31b2016-12-14 10:11:49 -080063using android::base::StringPrintf;
64
Mathieu Chartier120aa282017-08-05 16:03:03 -070065// If true, we attempt to load the application image if it exists.
Mathieu Chartierfbc31082016-01-24 11:59:56 -080066static constexpr bool kEnableAppImage = true;
67
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070068const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file) {
Nicolas Geoffray1d4f0092020-08-07 14:01:05 +010069 // Use class_linker vlog to match the log for dex file registration.
70 VLOG(class_linker) << "Registered oat file " << oat_file->GetLocation();
Nicolas Geoffray4f6bb442021-06-02 18:05:51 +010071 PaletteNotifyOatFileLoaded(oat_file->GetLocation().c_str());
Nicolas Geoffray1d4f0092020-08-07 14:01:05 +010072
Mathieu Chartiere58991b2015-10-13 07:59:34 -070073 WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
Nicolas Geoffray29742602017-12-14 10:09:03 +000074 CHECK(!only_use_system_oat_files_ ||
Orion Hodson094b1cf2021-06-08 09:28:28 +010075 LocationIsTrusted(oat_file->GetLocation()) ||
Nicolas Geoffray29742602017-12-14 10:09:03 +000076 !oat_file->IsExecutable())
Nicolas Geoffray68bf3902017-09-07 14:40:48 +010077 << "Registering a non /system oat file: " << oat_file->GetLocation();
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070078 DCHECK(oat_file != nullptr);
79 if (kIsDebugBuild) {
Mathieu Chartiere58991b2015-10-13 07:59:34 -070080 CHECK(oat_files_.find(oat_file) == oat_files_.end());
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070081 for (const std::unique_ptr<const OatFile>& existing : oat_files_) {
82 CHECK_NE(oat_file.get(), existing.get()) << oat_file->GetLocation();
83 // Check that we don't have an oat file with the same address. Copies of the same oat file
84 // should be loaded at different addresses.
85 CHECK_NE(oat_file->Begin(), existing->Begin()) << "Oat file already mapped at that location";
86 }
87 }
Mathieu Chartiere58991b2015-10-13 07:59:34 -070088 const OatFile* ret = oat_file.get();
89 oat_files_.insert(std::move(oat_file));
90 return ret;
91}
92
93void OatFileManager::UnRegisterAndDeleteOatFile(const OatFile* oat_file) {
94 WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
95 DCHECK(oat_file != nullptr);
96 std::unique_ptr<const OatFile> compare(oat_file);
97 auto it = oat_files_.find(compare);
98 CHECK(it != oat_files_.end());
99 oat_files_.erase(it);
Andreas Gampeafaf7f82018-10-16 11:32:38 -0700100 compare.release(); // NOLINT b/117926937
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700101}
102
Calin Juravle0b791272016-04-18 16:38:27 +0100103const OatFile* OatFileManager::FindOpenedOatFileFromDexLocation(
104 const std::string& dex_base_location) const {
105 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
106 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
107 const std::vector<const OatDexFile*>& oat_dex_files = oat_file->GetOatDexFiles();
108 for (const OatDexFile* oat_dex_file : oat_dex_files) {
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700109 if (DexFileLoader::GetBaseLocation(oat_dex_file->GetDexFileLocation()) == dex_base_location) {
Calin Juravle0b791272016-04-18 16:38:27 +0100110 return oat_file.get();
111 }
112 }
113 }
114 return nullptr;
115}
116
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700117const OatFile* OatFileManager::FindOpenedOatFileFromOatLocation(const std::string& oat_location)
118 const {
119 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700120 return FindOpenedOatFileFromOatLocationLocked(oat_location);
121}
122
123const OatFile* OatFileManager::FindOpenedOatFileFromOatLocationLocked(
124 const std::string& oat_location) const {
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700125 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
126 if (oat_file->GetLocation() == oat_location) {
127 return oat_file.get();
128 }
129 }
130 return nullptr;
131}
132
Jeff Haodcdc85b2015-12-04 14:06:18 -0800133std::vector<const OatFile*> OatFileManager::GetBootOatFiles() const {
Jeff Haodcdc85b2015-12-04 14:06:18 -0800134 std::vector<gc::space::ImageSpace*> image_spaces =
135 Runtime::Current()->GetHeap()->GetBootImageSpaces();
Andreas Gampe2a487eb2018-11-19 11:41:22 -0800136 std::vector<const OatFile*> oat_files;
137 oat_files.reserve(image_spaces.size());
Jeff Haodcdc85b2015-12-04 14:06:18 -0800138 for (gc::space::ImageSpace* image_space : image_spaces) {
139 oat_files.push_back(image_space->GetOatFile());
140 }
141 return oat_files;
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700142}
143
Nicolas Geoffray0744d722021-04-19 08:46:32 +0100144bool OatFileManager::GetPrimaryOatFileInfo(std::string* compilation_reason,
145 CompilerFilter::Filter* compiler_filter) const {
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700146 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
Jeff Haodcdc85b2015-12-04 14:06:18 -0800147 std::vector<const OatFile*> boot_oat_files = GetBootOatFiles();
148 if (!boot_oat_files.empty()) {
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700149 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
Jeff Haodcdc85b2015-12-04 14:06:18 -0800150 if (std::find(boot_oat_files.begin(), boot_oat_files.end(), oat_file.get()) ==
151 boot_oat_files.end()) {
Nicolas Geoffray0744d722021-04-19 08:46:32 +0100152 const char* reason = oat_file->GetCompilationReason();
153 if (reason != nullptr) {
154 *compilation_reason = reason;
155 }
156 *compiler_filter = oat_file->GetCompilerFilter();
157 return true;
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700158 }
159 }
160 }
Nicolas Geoffray0744d722021-04-19 08:46:32 +0100161 return false;
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700162}
163
Vladimir Markob0b68cf2017-11-14 18:11:50 +0000164OatFileManager::OatFileManager()
Vladimir Markoe0669322018-09-03 15:44:54 +0100165 : only_use_system_oat_files_(false) {}
Vladimir Markob0b68cf2017-11-14 18:11:50 +0000166
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700167OatFileManager::~OatFileManager() {
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700168 // Explicitly clear oat_files_ since the OatFile destructor calls back into OatFileManager for
169 // UnRegisterOatFileLocation.
170 oat_files_.clear();
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700171}
172
Jeff Haodcdc85b2015-12-04 14:06:18 -0800173std::vector<const OatFile*> OatFileManager::RegisterImageOatFiles(
Stephen Hines48ba1972018-09-24 13:35:54 -0700174 const std::vector<gc::space::ImageSpace*>& spaces) {
Jeff Haodcdc85b2015-12-04 14:06:18 -0800175 std::vector<const OatFile*> oat_files;
Andreas Gampe2a487eb2018-11-19 11:41:22 -0800176 oat_files.reserve(spaces.size());
Jeff Haodcdc85b2015-12-04 14:06:18 -0800177 for (gc::space::ImageSpace* space : spaces) {
178 oat_files.push_back(RegisterOatFile(space->ReleaseOatFile()));
179 }
180 return oat_files;
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700181}
182
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100183bool OatFileManager::ShouldLoadAppImage(const OatFile* source_oat_file) const {
Mathieu Chartieradc90862018-05-11 13:03:06 -0700184 Runtime* const runtime = Runtime::Current();
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100185 return kEnableAppImage && (!runtime->IsJavaDebuggable() || source_oat_file->IsDebuggable());
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700186}
187
188std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
189 const char* dex_location,
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800190 jobject class_loader,
191 jobjectArray dex_elements,
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700192 const OatFile** out_oat_file,
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700193 std::vector<std::string>* error_msgs) {
Calin Juravle98071152021-01-27 18:41:58 -0800194 ScopedTrace trace(StringPrintf("%s(%s)", __FUNCTION__, dex_location));
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700195 CHECK(dex_location != nullptr);
196 CHECK(error_msgs != nullptr);
197
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100198 // Verify we aren't holding the mutator lock, which could starve GC when
199 // hitting the disk.
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800200 Thread* const self = Thread::Current();
201 Locks::mutator_lock_->AssertNotHeld(self);
202 Runtime* const runtime = Runtime::Current();
Calin Juravleb077e152016-02-18 18:47:37 +0000203
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100204 std::vector<std::unique_ptr<const DexFile>> dex_files;
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000205 std::unique_ptr<ClassLoaderContext> context(
206 ClassLoaderContext::CreateContextForClassLoader(class_loader, dex_elements));
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100207
Calin Juravle27e0d1f2017-07-26 00:16:07 -0700208 // If the class_loader is null there's not much we can do. This happens if a dex files is loaded
209 // directly with DexFile APIs instead of using class loaders.
210 if (class_loader == nullptr) {
211 LOG(WARNING) << "Opening an oat file without a class loader. "
212 << "Are you using the deprecated DexFile APIs?";
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000213 } else if (context != nullptr) {
Ulya Trafimovich5439f052020-07-29 10:03:46 +0100214 OatFileAssistant oat_file_assistant(dex_location,
215 kRuntimeISA,
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000216 context.get(),
Ulya Trafimovich5439f052020-07-29 10:03:46 +0100217 runtime->GetOatFilesExecutable(),
218 only_use_system_oat_files_);
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700219
Calin Juravle98071152021-01-27 18:41:58 -0800220 // Get the current optimization status for trace debugging.
221 // Implementation detail note: GetOptimizationStatus will select the same
222 // oat file as GetBestOatFile used below, and in doing so it already pre-populates
223 // some OatFileAssistant internal fields.
224 std::string odex_location;
225 std::string compilation_filter;
226 std::string compilation_reason;
227 std::string odex_status;
228 oat_file_assistant.GetOptimizationStatus(
229 &odex_location,
230 &compilation_filter,
231 &compilation_reason,
232 &odex_status);
233
234 ScopedTrace odex_loading(StringPrintf(
235 "location=%s status=%s filter=%s reason=%s",
236 odex_location.c_str(),
237 odex_status.c_str(),
238 compilation_filter.c_str(),
239 compilation_reason.c_str()));
240
241 // Proceed with oat file loading.
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100242 std::unique_ptr<const OatFile> oat_file(oat_file_assistant.GetBestOatFile().release());
243 VLOG(oat) << "OatFileAssistant(" << dex_location << ").GetBestOatFile()="
Nicolas Geoffray16f60dc2021-02-16 15:35:16 +0000244 << (oat_file != nullptr ? oat_file->GetLocation() : "")
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100245 << " (executable=" << (oat_file != nullptr ? oat_file->IsExecutable() : false) << ")";
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800246
Calin Juravle98071152021-01-27 18:41:58 -0800247 CHECK(oat_file == nullptr || odex_location == oat_file->GetLocation())
248 << "OatFileAssistant non-determinism in choosing best oat files. "
249 << "optimization-status-location=" << odex_location
250 << " best_oat_file-location=" << oat_file->GetLocation();
251
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000252 if (oat_file != nullptr) {
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100253 // Load the dex files from the oat file.
254 bool added_image_space = false;
255 if (oat_file->IsExecutable()) {
256 ScopedTrace app_image_timing("AppImage:Loading");
Narayan Kamath5c525742017-04-28 10:19:29 +0100257
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100258 // We need to throw away the image space if we are debuggable but the oat-file source of the
259 // image is not otherwise we might get classes with inlined methods or other such things.
260 std::unique_ptr<gc::space::ImageSpace> image_space;
Nicolas Geoffray982eced2021-03-29 08:49:38 +0100261 if (ShouldLoadAppImage(oat_file.get())) {
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100262 image_space = oat_file_assistant.OpenImageSpace(oat_file.get());
Narayan Kamath5c525742017-04-28 10:19:29 +0100263 }
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100264 if (image_space != nullptr) {
265 ScopedObjectAccess soa(self);
266 StackHandleScope<1> hs(self);
267 Handle<mirror::ClassLoader> h_loader(
268 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
269 // Can not load app image without class loader.
270 if (h_loader != nullptr) {
271 std::string temp_error_msg;
272 // Add image space has a race condition since other threads could be reading from the
273 // spaces array.
Mathieu Chartiera9d82fe2016-01-25 20:06:11 -0800274 {
275 ScopedThreadSuspension sts(self, kSuspended);
Mathieu Chartier61d2b2d2016-02-04 13:31:46 -0800276 gc::ScopedGCCriticalSection gcs(self,
277 gc::kGcCauseAddRemoveAppImageSpace,
278 gc::kCollectorTypeAddRemoveAppImageSpace);
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100279 ScopedSuspendAll ssa("Add image space");
280 runtime->GetHeap()->AddSpace(image_space.get());
Mathieu Chartiera9d82fe2016-01-25 20:06:11 -0800281 }
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100282 {
Calin Juravle98071152021-01-27 18:41:58 -0800283 ScopedTrace image_space_timing("Adding image space");
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100284 added_image_space = runtime->GetClassLinker()->AddImageSpace(image_space.get(),
285 h_loader,
286 /*out*/&dex_files,
287 /*out*/&temp_error_msg);
288 }
289 if (added_image_space) {
290 // Successfully added image space to heap, release the map so that it does not get
291 // freed.
292 image_space.release(); // NOLINT b/117926937
293
294 // Register for tracking.
295 for (const auto& dex_file : dex_files) {
296 dex::tracking::RegisterDexFile(dex_file.get());
297 }
298 } else {
299 LOG(INFO) << "Failed to add image file " << temp_error_msg;
300 dex_files.clear();
301 {
302 ScopedThreadSuspension sts(self, kSuspended);
303 gc::ScopedGCCriticalSection gcs(self,
304 gc::kGcCauseAddRemoveAppImageSpace,
305 gc::kCollectorTypeAddRemoveAppImageSpace);
306 ScopedSuspendAll ssa("Remove image space");
307 runtime->GetHeap()->RemoveSpace(image_space.get());
308 }
309 // Non-fatal, don't update error_msg.
310 }
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800311 }
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800312 }
313 }
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100314 if (!added_image_space) {
315 DCHECK(dex_files.empty());
Eric Holkbc89ed42020-04-29 19:59:24 +0000316
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100317 if (oat_file->RequiresImage()) {
Nicolas Geoffray107d22b2021-05-04 10:57:36 +0100318 LOG(WARNING) << "Loading "
319 << oat_file->GetLocation()
320 << "non-executable as it requires an image which we failed to load";
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100321 // file as non-executable.
322 OatFileAssistant nonexecutable_oat_file_assistant(dex_location,
323 kRuntimeISA,
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000324 context.get(),
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100325 /*load_executable=*/false,
326 only_use_system_oat_files_);
327 oat_file.reset(nonexecutable_oat_file_assistant.GetBestOatFile().release());
Nicolas Geoffray107d22b2021-05-04 10:57:36 +0100328
329 // The file could be deleted concurrently (for example background
330 // dexopt, or secondary oat file being deleted by the app).
331 if (oat_file == nullptr) {
332 LOG(WARNING) << "Failed to reload oat file non-executable " << dex_location;
333 }
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100334 }
335
Nicolas Geoffray107d22b2021-05-04 10:57:36 +0100336 if (oat_file != nullptr) {
337 dex_files = oat_file_assistant.LoadDexFiles(*oat_file.get(), dex_location);
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100338
Nicolas Geoffray107d22b2021-05-04 10:57:36 +0100339 // Register for tracking.
340 for (const auto& dex_file : dex_files) {
341 dex::tracking::RegisterDexFile(dex_file.get());
342 }
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100343 }
344 }
345 if (dex_files.empty()) {
Calin Juravle98071152021-01-27 18:41:58 -0800346 ScopedTrace failed_to_open_dex_files("FailedToOpenDexFilesFromOat");
Nicolas Geoffrayc07e8732021-05-18 14:26:42 +0100347 error_msgs->push_back("Failed to open dex files from " + odex_location);
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100348 } else {
349 // Opened dex files from an oat file, madvise them to their loaded state.
350 for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
351 OatDexFile::MadviseDexFile(*dex_file, MadviseState::kMadviseStateAtLoad);
352 }
Eric Holkbc89ed42020-04-29 19:59:24 +0000353 }
354
Nicolas Geoffray107d22b2021-05-04 10:57:36 +0100355 if (oat_file != nullptr) {
356 VLOG(class_linker) << "Registering " << oat_file->GetLocation();
357 *out_oat_file = RegisterOatFile(std::move(oat_file));
358 }
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000359 } else {
360 // oat_file == nullptr
361 // Verify if any of the dex files being loaded is already in the class path.
362 // If so, report an error with the current stack trace.
363 // Most likely the developer didn't intend to do this because it will waste
364 // performance and memory.
365 if (oat_file_assistant.GetBestStatus() == OatFileAssistant::kOatContextOutOfDate) {
366 std::set<const DexFile*> already_exists_in_classpath =
367 context->CheckForDuplicateDexFiles(MakeNonOwningPointerVector(dex_files));
368 if (!already_exists_in_classpath.empty()) {
369 ScopedTrace duplicate_dex_files("DuplicateDexFilesInContext");
370 auto duplicate_it = already_exists_in_classpath.begin();
371 std::string duplicates = (*duplicate_it)->GetLocation();
372 for (duplicate_it++ ; duplicate_it != already_exists_in_classpath.end(); duplicate_it++) {
373 duplicates += "," + (*duplicate_it)->GetLocation();
374 }
Bharadwaj Kalandhabhatta0bb40312017-06-01 10:47:00 -0700375
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000376 std::ostringstream out;
377 out << "Trying to load dex files which is already loaded in the same ClassLoader "
378 << "hierarchy.\n"
379 << "This is a strong indication of bad ClassLoader construct which leads to poor "
380 << "performance and wastes memory.\n"
381 << "The list of duplicate dex files is: " << duplicates << "\n"
382 << "The current class loader context is: "
383 << context->EncodeContextForOatFile("") << "\n"
384 << "Java stack trace:\n";
385
386 {
387 ScopedObjectAccess soa(self);
388 self->DumpJavaStack(out);
389 }
390
391 // We log this as an ERROR to stress the fact that this is most likely unintended.
392 // Note that ART cannot do anything about it. It is up to the app to fix their logic.
393 // Here we are trying to give a heads up on why the app might have performance issues.
394 LOG(ERROR) << out.str();
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100395 }
Bharadwaj Kalandhabhatta0bb40312017-06-01 10:47:00 -0700396 }
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800397 }
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700398 }
399
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100400 // If we arrive here with an empty dex files list, it means we fail to load
401 // it/them through an .oat file.
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700402 if (dex_files.empty()) {
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100403 std::string error_msg;
404 static constexpr bool kVerifyChecksum = true;
405 const ArtDexFileLoader dex_file_loader;
406 if (!dex_file_loader.Open(dex_location,
407 dex_location,
408 Runtime::Current()->IsVerificationEnabled(),
409 kVerifyChecksum,
410 /*out*/ &error_msg,
411 &dex_files)) {
Calin Juravle98071152021-01-27 18:41:58 -0800412 ScopedTrace fail_to_open_dex_from_apk("FailedToOpenDexFilesFromApk");
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100413 LOG(WARNING) << error_msg;
414 error_msgs->push_back("Failed to open dex files from " + std::string(dex_location)
415 + " because: " + error_msg);
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700416 }
417 }
Calin Juravlec90bc922016-02-24 10:13:09 +0000418
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +0100419 if (Runtime::Current()->GetJit() != nullptr) {
Nicolas Geoffray741a0702019-06-10 11:18:11 +0100420 Runtime::Current()->GetJit()->RegisterDexFiles(dex_files, class_loader);
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +0100421 }
422
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700423 return dex_files;
424}
425
David Brazdil7126c5b2019-03-05 00:02:51 +0000426static std::vector<const DexFile::Header*> GetDexFileHeaders(const std::vector<MemMap>& maps) {
427 std::vector<const DexFile::Header*> headers;
428 headers.reserve(maps.size());
429 for (const MemMap& map : maps) {
430 DCHECK(map.IsValid());
431 headers.push_back(reinterpret_cast<const DexFile::Header*>(map.Begin()));
432 }
433 return headers;
434}
435
David Brazdil7126c5b2019-03-05 00:02:51 +0000436std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
437 std::vector<MemMap>&& dex_mem_maps,
438 jobject class_loader,
439 jobjectArray dex_elements,
440 const OatFile** out_oat_file,
441 std::vector<std::string>* error_msgs) {
442 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenDexFilesFromOat_Impl(
443 std::move(dex_mem_maps),
444 class_loader,
445 dex_elements,
446 out_oat_file,
447 error_msgs);
448
449 if (error_msgs->empty()) {
450 // Remove write permission from DexFile pages. We do this at the end because
451 // OatFile assigns OatDexFile pointer in the DexFile objects.
452 for (std::unique_ptr<const DexFile>& dex_file : dex_files) {
453 if (!dex_file->DisableWrite()) {
454 error_msgs->push_back("Failed to make dex file " + dex_file->GetLocation() + " read-only");
455 }
456 }
457 }
458
459 if (!error_msgs->empty()) {
460 return std::vector<std::unique_ptr<const DexFile>>();
461 }
462
463 return dex_files;
464}
465
466std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat_Impl(
467 std::vector<MemMap>&& dex_mem_maps,
468 jobject class_loader,
469 jobjectArray dex_elements,
470 const OatFile** out_oat_file,
471 std::vector<std::string>* error_msgs) {
472 ScopedTrace trace(__FUNCTION__);
473 std::string error_msg;
474 DCHECK(error_msgs != nullptr);
475
476 // Extract dex file headers from `dex_mem_maps`.
477 const std::vector<const DexFile::Header*> dex_headers = GetDexFileHeaders(dex_mem_maps);
478
479 // Determine dex/vdex locations and the combined location checksum.
David Brazdil7126c5b2019-03-05 00:02:51 +0000480 std::string dex_location;
481 std::string vdex_path;
482 bool has_vdex = OatFileAssistant::AnonymousDexVdexLocation(dex_headers,
483 kRuntimeISA,
David Brazdil7126c5b2019-03-05 00:02:51 +0000484 &dex_location,
485 &vdex_path);
486
487 // Attempt to open an existing vdex and check dex file checksums match.
488 std::unique_ptr<VdexFile> vdex_file = nullptr;
489 if (has_vdex && OS::FileExists(vdex_path.c_str())) {
490 vdex_file = VdexFile::Open(vdex_path,
491 /* writable= */ false,
492 /* low_4gb= */ false,
493 /* unquicken= */ false,
494 &error_msg);
495 if (vdex_file == nullptr) {
496 LOG(WARNING) << "Failed to open vdex " << vdex_path << ": " << error_msg;
497 } else if (!vdex_file->MatchesDexFileChecksums(dex_headers)) {
498 LOG(WARNING) << "Failed to open vdex " << vdex_path << ": dex file checksum mismatch";
499 vdex_file.reset(nullptr);
500 }
501 }
502
503 // Load dex files. Skip structural dex file verification if vdex was found
504 // and dex checksums matched.
505 std::vector<std::unique_ptr<const DexFile>> dex_files;
506 for (size_t i = 0; i < dex_mem_maps.size(); ++i) {
507 static constexpr bool kVerifyChecksum = true;
508 const ArtDexFileLoader dex_file_loader;
509 std::unique_ptr<const DexFile> dex_file(dex_file_loader.Open(
510 DexFileLoader::GetMultiDexLocation(i, dex_location.c_str()),
Nicolas Geoffray88566952021-02-16 15:51:18 +0000511 dex_headers[i]->checksum_,
David Brazdil7126c5b2019-03-05 00:02:51 +0000512 std::move(dex_mem_maps[i]),
513 /* verify= */ (vdex_file == nullptr) && Runtime::Current()->IsVerificationEnabled(),
514 kVerifyChecksum,
515 &error_msg));
516 if (dex_file != nullptr) {
517 dex::tracking::RegisterDexFile(dex_file.get()); // Register for tracking.
518 dex_files.push_back(std::move(dex_file));
519 } else {
520 error_msgs->push_back("Failed to open dex files from memory: " + error_msg);
521 }
522 }
523
524 // Check if we should proceed to creating an OatFile instance backed by the vdex.
525 // We need: (a) an existing vdex, (b) class loader (can be null if invoked via reflection),
526 // and (c) no errors during dex file loading.
527 if (vdex_file == nullptr || class_loader == nullptr || !error_msgs->empty()) {
528 return dex_files;
529 }
530
531 // Attempt to create a class loader context, check OpenDexFiles succeeds (prerequisite
532 // for using the context later).
533 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::CreateContextForClassLoader(
534 class_loader,
535 dex_elements);
536 if (context == nullptr) {
537 LOG(ERROR) << "Could not create class loader context for " << vdex_path;
538 return dex_files;
539 }
Calin Juravle5ff23932020-12-11 18:26:14 -0800540 DCHECK(context->OpenDexFiles())
David Brazdil7126c5b2019-03-05 00:02:51 +0000541 << "Context created from already opened dex files should not attempt to open again";
542
David Brazdil7126c5b2019-03-05 00:02:51 +0000543 // Initialize an OatFile instance backed by the loaded vdex.
544 std::unique_ptr<OatFile> oat_file(OatFile::OpenFromVdex(MakeNonOwningPointerVector(dex_files),
545 std::move(vdex_file),
546 dex_location));
Vladimir Markoc3908792020-04-06 14:52:04 +0100547 if (oat_file != nullptr) {
548 VLOG(class_linker) << "Registering " << oat_file->GetLocation();
549 *out_oat_file = RegisterOatFile(std::move(oat_file));
550 }
David Brazdil7126c5b2019-03-05 00:02:51 +0000551 return dex_files;
552}
553
David Brazdil35a3f6a2019-03-04 15:59:06 +0000554// Check how many vdex files exist in the same directory as the vdex file we are about
555// to write. If more than or equal to kAnonymousVdexCacheSize, unlink the least
556// recently used one(s) (according to stat-reported atime).
557static bool UnlinkLeastRecentlyUsedVdexIfNeeded(const std::string& vdex_path_to_add,
558 std::string* error_msg) {
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100559 std::string basename = android::base::Basename(vdex_path_to_add);
560 if (!OatFileAssistant::IsAnonymousVdexBasename(basename)) {
561 // File is not for in memory dex files.
562 return true;
563 }
564
David Brazdil35a3f6a2019-03-04 15:59:06 +0000565 if (OS::FileExists(vdex_path_to_add.c_str())) {
566 // File already exists and will be overwritten.
567 // This will not change the number of entries in the cache.
568 return true;
569 }
570
571 auto last_slash = vdex_path_to_add.rfind('/');
572 CHECK(last_slash != std::string::npos);
573 std::string vdex_dir = vdex_path_to_add.substr(0, last_slash + 1);
574
575 if (!OS::DirectoryExists(vdex_dir.c_str())) {
576 // Folder does not exist yet. Cache has zero entries.
577 return true;
578 }
579
580 std::vector<std::pair<time_t, std::string>> cache;
581
582 DIR* c_dir = opendir(vdex_dir.c_str());
583 if (c_dir == nullptr) {
584 *error_msg = "Unable to open " + vdex_dir + " to delete unused vdex files";
585 return false;
586 }
587 for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) {
588 if (de->d_type != DT_REG) {
589 continue;
590 }
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100591 basename = de->d_name;
David Brazdil35a3f6a2019-03-04 15:59:06 +0000592 if (!OatFileAssistant::IsAnonymousVdexBasename(basename)) {
593 continue;
594 }
595 std::string fullname = vdex_dir + basename;
596
597 struct stat s;
598 int rc = TEMP_FAILURE_RETRY(stat(fullname.c_str(), &s));
599 if (rc == -1) {
600 *error_msg = "Failed to stat() anonymous vdex file " + fullname;
601 return false;
602 }
603
604 cache.push_back(std::make_pair(s.st_atime, fullname));
605 }
606 CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
607
608 if (cache.size() < OatFileManager::kAnonymousVdexCacheSize) {
609 return true;
610 }
611
612 std::sort(cache.begin(),
613 cache.end(),
614 [](const auto& a, const auto& b) { return a.first < b.first; });
615 for (size_t i = OatFileManager::kAnonymousVdexCacheSize - 1; i < cache.size(); ++i) {
616 if (unlink(cache[i].second.c_str()) != 0) {
617 *error_msg = "Could not unlink anonymous vdex file " + cache[i].second;
618 return false;
619 }
620 }
621
622 return true;
623}
624
David Brazdil331a5e12019-04-01 22:46:16 +0000625class BackgroundVerificationTask final : public Task {
626 public:
David Brazdil35a3f6a2019-03-04 15:59:06 +0000627 BackgroundVerificationTask(const std::vector<const DexFile*>& dex_files,
628 jobject class_loader,
David Brazdil35a3f6a2019-03-04 15:59:06 +0000629 const std::string& vdex_path)
630 : dex_files_(dex_files),
David Brazdil35a3f6a2019-03-04 15:59:06 +0000631 vdex_path_(vdex_path) {
David Brazdil331a5e12019-04-01 22:46:16 +0000632 Thread* const self = Thread::Current();
633 ScopedObjectAccess soa(self);
634 // Create a global ref for `class_loader` because it will be accessed from a different thread.
635 class_loader_ = soa.Vm()->AddGlobalRef(self, soa.Decode<mirror::ClassLoader>(class_loader));
636 CHECK(class_loader_ != nullptr);
637 }
638
639 ~BackgroundVerificationTask() {
640 Thread* const self = Thread::Current();
641 ScopedObjectAccess soa(self);
642 soa.Vm()->DeleteGlobalRef(self, class_loader_);
643 }
644
645 void Run(Thread* self) override {
David Brazdil35a3f6a2019-03-04 15:59:06 +0000646 std::string error_msg;
David Brazdil331a5e12019-04-01 22:46:16 +0000647 ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
David Brazdil35a3f6a2019-03-04 15:59:06 +0000648 verifier::VerifierDeps verifier_deps(dex_files_);
David Brazdil331a5e12019-04-01 22:46:16 +0000649
650 // Iterate over all classes and verify them.
651 for (const DexFile* dex_file : dex_files_) {
652 for (uint32_t cdef_idx = 0; cdef_idx < dex_file->NumClassDefs(); cdef_idx++) {
David Brazdil35a3f6a2019-03-04 15:59:06 +0000653 const dex::ClassDef& class_def = dex_file->GetClassDef(cdef_idx);
654
David Brazdil331a5e12019-04-01 22:46:16 +0000655 // Take handles inside the loop. The background verification is low priority
656 // and we want to minimize the risk of blocking anyone else.
657 ScopedObjectAccess soa(self);
658 StackHandleScope<2> hs(self);
659 Handle<mirror::ClassLoader> h_loader(hs.NewHandle(
660 soa.Decode<mirror::ClassLoader>(class_loader_)));
661 Handle<mirror::Class> h_class(hs.NewHandle<mirror::Class>(class_linker->FindClass(
662 self,
David Brazdil35a3f6a2019-03-04 15:59:06 +0000663 dex_file->GetClassDescriptor(class_def),
David Brazdil331a5e12019-04-01 22:46:16 +0000664 h_loader)));
665
666 if (h_class == nullptr) {
667 CHECK(self->IsExceptionPending());
668 self->ClearException();
669 continue;
670 }
671
672 if (&h_class->GetDexFile() != dex_file) {
673 // There is a different class in the class path or a parent class loader
674 // with the same descriptor. This `h_class` is not resolvable, skip it.
675 continue;
676 }
677
678 CHECK(h_class->IsResolved()) << h_class->PrettyDescriptor();
Nicolas Geoffray5b0b2e12021-03-19 14:48:40 +0000679 class_linker->VerifyClass(self, &verifier_deps, h_class);
David Brazdil331a5e12019-04-01 22:46:16 +0000680 if (h_class->IsErroneous()) {
681 // ClassLinker::VerifyClass throws, which isn't useful here.
682 CHECK(soa.Self()->IsExceptionPending());
683 soa.Self()->ClearException();
684 }
685
686 CHECK(h_class->IsVerified() || h_class->IsErroneous())
687 << h_class->PrettyDescriptor() << ": state=" << h_class->GetStatus();
David Brazdil35a3f6a2019-03-04 15:59:06 +0000688
689 if (h_class->IsVerified()) {
690 verifier_deps.RecordClassVerified(*dex_file, class_def);
691 }
David Brazdil331a5e12019-04-01 22:46:16 +0000692 }
693 }
David Brazdil35a3f6a2019-03-04 15:59:06 +0000694
695 // Delete old vdex files if there are too many in the folder.
696 if (!UnlinkLeastRecentlyUsedVdexIfNeeded(vdex_path_, &error_msg)) {
697 LOG(ERROR) << "Could not unlink old vdex files " << vdex_path_ << ": " << error_msg;
698 return;
699 }
700
701 // Construct a vdex file and write `verifier_deps` into it.
702 if (!VdexFile::WriteToDisk(vdex_path_,
703 dex_files_,
704 verifier_deps,
David Brazdil35a3f6a2019-03-04 15:59:06 +0000705 &error_msg)) {
706 LOG(ERROR) << "Could not write anonymous vdex " << vdex_path_ << ": " << error_msg;
707 return;
708 }
David Brazdil331a5e12019-04-01 22:46:16 +0000709 }
710
711 void Finalize() override {
712 delete this;
713 }
714
715 private:
716 const std::vector<const DexFile*> dex_files_;
717 jobject class_loader_;
David Brazdil35a3f6a2019-03-04 15:59:06 +0000718 const std::string vdex_path_;
David Brazdil331a5e12019-04-01 22:46:16 +0000719
720 DISALLOW_COPY_AND_ASSIGN(BackgroundVerificationTask);
721};
722
723void OatFileManager::RunBackgroundVerification(const std::vector<const DexFile*>& dex_files,
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100724 jobject class_loader) {
David Brazdil527072e2019-04-03 15:15:40 +0100725 Runtime* const runtime = Runtime::Current();
726 Thread* const self = Thread::Current();
727
728 if (runtime->IsJavaDebuggable()) {
David Brazdil331a5e12019-04-01 22:46:16 +0000729 // Threads created by ThreadPool ("runtime threads") are not allowed to load
730 // classes when debuggable to match class-initialization semantics
731 // expectations. Do not verify in the background.
732 return;
733 }
734
David Brazdil527072e2019-04-03 15:15:40 +0100735 if (!IsSdkVersionSetAndAtLeast(runtime->GetTargetSdkVersion(), SdkVersion::kQ)) {
736 // Do not run for legacy apps as they may depend on the previous class loader behaviour.
737 return;
738 }
739
740 if (runtime->IsShuttingDown(self)) {
David Brazdil331a5e12019-04-01 22:46:16 +0000741 // Not allowed to create new threads during runtime shutdown.
742 return;
743 }
744
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100745 if (dex_files.size() < 1) {
746 // Nothing to verify.
747 return;
David Brazdil331a5e12019-04-01 22:46:16 +0000748 }
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100749
750 std::string dex_location = dex_files[0]->GetLocation();
751 const std::string& data_dir = Runtime::Current()->GetProcessDataDirectory();
752 if (!android::base::StartsWith(dex_location, data_dir)) {
753 // For now, we only run background verification for secondary dex files.
754 // Running it for primary or split APKs could have some undesirable
755 // side-effects, like overloading the device on app startup.
756 return;
757 }
758
759 std::string error_msg;
760 std::string odex_filename;
761 if (!OatFileAssistant::DexLocationToOdexFilename(dex_location,
762 kRuntimeISA,
763 &odex_filename,
764 &error_msg)) {
765 LOG(WARNING) << "Could not get odex filename for " << dex_location << ": " << error_msg;
766 return;
767 }
768
Nicolas Geoffray30ba3a02021-03-31 14:11:58 +0100769 {
770 WriterMutexLock mu(self, *Locks::oat_file_manager_lock_);
771 if (verification_thread_pool_ == nullptr) {
772 verification_thread_pool_.reset(
773 new ThreadPool("Verification thread pool", /* num_threads= */ 1));
774 verification_thread_pool_->StartWorkers(self);
775 }
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100776 }
777 verification_thread_pool_->AddTask(self, new BackgroundVerificationTask(
778 dex_files,
779 class_loader,
Nicolas Geoffray30ba3a02021-03-31 14:11:58 +0100780 GetVdexFilename(odex_filename)));
David Brazdil331a5e12019-04-01 22:46:16 +0000781}
782
783void OatFileManager::WaitForWorkersToBeCreated() {
784 DCHECK(!Runtime::Current()->IsShuttingDown(Thread::Current()))
785 << "Cannot create new threads during runtime shutdown";
786 if (verification_thread_pool_ != nullptr) {
787 verification_thread_pool_->WaitForWorkersToBeCreated();
788 }
789}
790
791void OatFileManager::DeleteThreadPool() {
792 verification_thread_pool_.reset(nullptr);
793}
794
795void OatFileManager::WaitForBackgroundVerificationTasks() {
796 if (verification_thread_pool_ != nullptr) {
797 Thread* const self = Thread::Current();
798 verification_thread_pool_->WaitForWorkersToBeCreated();
799 verification_thread_pool_->Wait(self, /* do_work= */ true, /* may_hold_locks= */ false);
800 }
801}
802
Orion Hodson094b1cf2021-06-08 09:28:28 +0100803void OatFileManager::SetOnlyUseTrustedOatFiles() {
Nicolas Geoffray68bf3902017-09-07 14:40:48 +0100804 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
Nicolas Geoffray2e17cf42020-03-12 21:19:46 +0000805 // Make sure all files that were loaded up to this point are on /system.
806 // Skip the image files as they can encode locations that don't exist (eg not
807 // containing the arch in the path, or for JIT zygote /nonx/existent).
808 std::vector<const OatFile*> boot_vector = GetBootOatFiles();
809 std::unordered_set<const OatFile*> boot_set(boot_vector.begin(), boot_vector.end());
Andreas Gampe99c07952019-03-30 17:43:55 +0000810
Nicolas Geoffray2e17cf42020-03-12 21:19:46 +0000811 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
812 if (boot_set.find(oat_file.get()) == boot_set.end()) {
Orion Hodson094b1cf2021-06-08 09:28:28 +0100813 if (!LocationIsTrusted(oat_file->GetLocation())) {
814 // When the file is not in a trusted location, we check whether the oat file has any
Nicolas Geoffrayefe9a3d2021-03-30 16:59:17 +0100815 // AOT or DEX code. It is a fatal error if it has.
816 if (CompilerFilter::IsAotCompilationEnabled(oat_file->GetCompilerFilter()) ||
817 oat_file->ContainsDexCode()) {
818 LOG(FATAL) << "Executing untrusted code from " << oat_file->GetLocation();
819 }
820 }
Andreas Gampe99c07952019-03-30 17:43:55 +0000821 }
Andreas Gampe3383f9c2019-03-15 11:46:08 -0700822 }
Nicolas Geoffraye5c48f72020-03-11 11:28:43 +0000823 only_use_system_oat_files_ = true;
Nicolas Geoffray68bf3902017-09-07 14:40:48 +0100824}
825
Nicolas Geoffray04680f32016-03-17 11:56:54 +0000826void OatFileManager::DumpForSigQuit(std::ostream& os) {
827 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
828 std::vector<const OatFile*> boot_oat_files = GetBootOatFiles();
829 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
830 if (ContainsElement(boot_oat_files, oat_file.get())) {
831 continue;
832 }
Andreas Gampe29d38e72016-03-23 15:31:51 +0000833 os << oat_file->GetLocation() << ": " << oat_file->GetCompilerFilter() << "\n";
Nicolas Geoffray04680f32016-03-17 11:56:54 +0000834 }
835}
836
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700837} // namespace art