1 /*
2  * Copyright (C) 2011 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 <inttypes.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <sys/stat.h>
21 #include "base/memory_tool.h"
22 
23 #include <forward_list>
24 #include <fstream>
25 #include <iostream>
26 #include <limits>
27 #include <log/log.h>
28 #include <sstream>
29 #include <string>
30 #include <type_traits>
31 #include <vector>
32 
33 #if defined(__linux__)
34 #include <sched.h>
35 #if defined(__arm__)
36 #include <sys/personality.h>
37 #include <sys/utsname.h>
38 #endif  // __arm__
39 #endif
40 
41 #include "android-base/parseint.h"
42 #include "android-base/stringprintf.h"
43 #include "android-base/strings.h"
44 #include "android-base/unique_fd.h"
45 
46 #include "aot_class_linker.h"
47 #include "arch/instruction_set_features.h"
48 #include "art_method-inl.h"
49 #include "base/callee_save_type.h"
50 #include "base/dumpable.h"
51 #include "base/file_utils.h"
52 #include "base/leb128.h"
53 #include "base/macros.h"
54 #include "base/mutex.h"
55 #include "base/os.h"
56 #include "base/fast_exit.h"
57 #include "base/scoped_flock.h"
58 #include "base/stl_util.h"
59 #include "base/time_utils.h"
60 #include "base/timing_logger.h"
61 #include "base/unix_file/fd_file.h"
62 #include "base/utils.h"
63 #include "base/zip_archive.h"
64 #include "class_linker.h"
65 #include "class_loader_context.h"
66 #include "cmdline_parser.h"
67 #include "compiler.h"
68 #include "compiler_callbacks.h"
69 #include "debug/elf_debug_writer.h"
70 #include "debug/method_debug_info.h"
71 #include "dex/descriptors_names.h"
72 #include "dex/dex_file-inl.h"
73 #include "dex/dex_file_loader.h"
74 #include "dex/quick_compiler_callbacks.h"
75 #include "dex/verification_results.h"
76 #include "dex2oat_options.h"
77 #include "dexlayout.h"
78 #include "driver/compiler_driver.h"
79 #include "driver/compiler_options.h"
80 #include "driver/compiler_options_map-inl.h"
81 #include "elf_file.h"
82 #include "gc/space/image_space.h"
83 #include "gc/space/space-inl.h"
84 #include "gc/verification.h"
85 #include "interpreter/unstarted_runtime.h"
86 #include "jni/java_vm_ext.h"
87 #include "linker/elf_writer.h"
88 #include "linker/elf_writer_quick.h"
89 #include "linker/image_writer.h"
90 #include "linker/multi_oat_relative_patcher.h"
91 #include "linker/oat_writer.h"
92 #include "mirror/class-alloc-inl.h"
93 #include "mirror/class_loader.h"
94 #include "mirror/object-inl.h"
95 #include "mirror/object_array-inl.h"
96 #include "oat.h"
97 #include "oat_file.h"
98 #include "oat_file_assistant.h"
99 #include "palette/palette.h"
100 #include "profile/profile_compilation_info.h"
101 #include "runtime.h"
102 #include "runtime_options.h"
103 #include "scoped_thread_state_change-inl.h"
104 #include "stream/buffered_output_stream.h"
105 #include "stream/file_output_stream.h"
106 #include "vdex_file.h"
107 #include "verifier/verifier_deps.h"
108 #include "well_known_classes.h"
109 
110 namespace art {
111 
112 namespace dex2oat {
113   enum class ReturnCode : int {
114     kNoFailure = 0,          // No failure, execution completed successfully.
115     kOther = 1,              // Some other not closer specified error occurred.
116     kCreateRuntime = 2,      // Dex2oat failed creating a runtime.
117   };
118 }  // namespace dex2oat
119 
120 using android::base::StringAppendV;
121 using android::base::StringPrintf;
122 using gc::space::ImageSpace;
123 
124 static constexpr size_t kDefaultMinDexFilesForSwap = 2;
125 static constexpr size_t kDefaultMinDexFileCumulativeSizeForSwap = 20 * MB;
126 
127 // Compiler filter override for very large apps.
128 static constexpr CompilerFilter::Filter kLargeAppFilter = CompilerFilter::kVerify;
129 
130 static int original_argc;
131 static char** original_argv;
132 
CommandLine()133 static std::string CommandLine() {
134   std::vector<std::string> command;
135   command.reserve(original_argc);
136   for (int i = 0; i < original_argc; ++i) {
137     command.push_back(original_argv[i]);
138   }
139   return android::base::Join(command, ' ');
140 }
141 
142 // A stripped version. Remove some less essential parameters. If we see a "--zip-fd=" parameter, be
143 // even more aggressive. There won't be much reasonable data here for us in that case anyways (the
144 // locations are all staged).
StrippedCommandLine()145 static std::string StrippedCommandLine() {
146   std::vector<std::string> command;
147 
148   // Do a pre-pass to look for zip-fd and the compiler filter.
149   bool saw_zip_fd = false;
150   bool saw_compiler_filter = false;
151   for (int i = 0; i < original_argc; ++i) {
152     if (android::base::StartsWith(original_argv[i], "--zip-fd=")) {
153       saw_zip_fd = true;
154     }
155     if (android::base::StartsWith(original_argv[i], "--compiler-filter=")) {
156       saw_compiler_filter = true;
157     }
158   }
159 
160   // Now filter out things.
161   for (int i = 0; i < original_argc; ++i) {
162     // All runtime-arg parameters are dropped.
163     if (strcmp(original_argv[i], "--runtime-arg") == 0) {
164       i++;  // Drop the next part, too.
165       continue;
166     }
167 
168     // Any instruction-setXXX is dropped.
169     if (android::base::StartsWith(original_argv[i], "--instruction-set")) {
170       continue;
171     }
172 
173     // The boot image is dropped.
174     if (android::base::StartsWith(original_argv[i], "--boot-image=")) {
175       continue;
176     }
177 
178     // The image format is dropped.
179     if (android::base::StartsWith(original_argv[i], "--image-format=")) {
180       continue;
181     }
182 
183     // This should leave any dex-file and oat-file options, describing what we compiled.
184 
185     // However, we prefer to drop this when we saw --zip-fd.
186     if (saw_zip_fd) {
187       // Drop anything --zip-X, --dex-X, --oat-X, --swap-X, or --app-image-X
188       if (android::base::StartsWith(original_argv[i], "--zip-") ||
189           android::base::StartsWith(original_argv[i], "--dex-") ||
190           android::base::StartsWith(original_argv[i], "--oat-") ||
191           android::base::StartsWith(original_argv[i], "--swap-") ||
192           android::base::StartsWith(original_argv[i], "--app-image-")) {
193         continue;
194       }
195     }
196 
197     command.push_back(original_argv[i]);
198   }
199 
200   if (!saw_compiler_filter) {
201     command.push_back("--compiler-filter=" +
202         CompilerFilter::NameOfFilter(CompilerFilter::kDefaultCompilerFilter));
203   }
204 
205   // Construct the final output.
206   if (command.size() <= 1U) {
207     // It seems only "/apex/com.android.art/bin/dex2oat" is left, or not
208     // even that. Use a pretty line.
209     return "Starting dex2oat.";
210   }
211   return android::base::Join(command, ' ');
212 }
213 
UsageErrorV(const char * fmt,va_list ap)214 static void UsageErrorV(const char* fmt, va_list ap) {
215   std::string error;
216   StringAppendV(&error, fmt, ap);
217   LOG(ERROR) << error;
218 }
219 
UsageError(const char * fmt,...)220 static void UsageError(const char* fmt, ...) {
221   va_list ap;
222   va_start(ap, fmt);
223   UsageErrorV(fmt, ap);
224   va_end(ap);
225 }
226 
Usage(const char * fmt,...)227 NO_RETURN static void Usage(const char* fmt, ...) {
228   va_list ap;
229   va_start(ap, fmt);
230   UsageErrorV(fmt, ap);
231   va_end(ap);
232 
233   UsageError("Command: %s", CommandLine().c_str());
234 
235   UsageError("Usage: dex2oat [options]...");
236   UsageError("");
237 
238   std::stringstream oss;
239   VariableIndentationOutputStream vios(&oss);
240   auto parser = CreateDex2oatArgumentParser();
241   parser.DumpHelp(vios);
242   UsageError(oss.str().c_str());
243   std::cerr << "See log for usage error information\n";
244   exit(EXIT_FAILURE);
245 }
246 
247 
248 // Set CPU affinity from a string containing a comma-separated list of numeric CPU identifiers.
SetCpuAffinity(const std::vector<int32_t> & cpu_list)249 static void SetCpuAffinity(const std::vector<int32_t>& cpu_list) {
250 #ifdef __linux__
251   int cpu_count = sysconf(_SC_NPROCESSORS_CONF);
252   cpu_set_t target_cpu_set;
253   CPU_ZERO(&target_cpu_set);
254 
255   for (int32_t cpu : cpu_list) {
256     if (cpu >= 0 && cpu < cpu_count) {
257       CPU_SET(cpu, &target_cpu_set);
258     } else {
259       // Argument error is considered fatal, suggests misconfigured system properties.
260       Usage("Invalid cpu \"d\" specified in --cpu-set argument (nprocessors = %d)",
261             cpu, cpu_count);
262     }
263   }
264 
265   if (sched_setaffinity(getpid(), sizeof(target_cpu_set), &target_cpu_set) == -1) {
266     // Failure to set affinity may be outside control of requestor, log warning rather than
267     // treating as fatal.
268     PLOG(WARNING) << "Failed to set CPU affinity.";
269   }
270 #else
271   LOG(WARNING) << "--cpu-set not supported on this platform.";
272 #endif  // __linux__
273 }
274 
275 
276 
277 // The primary goal of the watchdog is to prevent stuck build servers
278 // during development when fatal aborts lead to a cascade of failures
279 // that result in a deadlock.
280 class WatchDog {
281 // WatchDog defines its own CHECK_PTHREAD_CALL to avoid using LOG which uses locks
282 #undef CHECK_PTHREAD_CALL
283 #define CHECK_WATCH_DOG_PTHREAD_CALL(call, args, what) \
284   do { \
285     int rc = call args; \
286     if (rc != 0) { \
287       errno = rc; \
288       std::string message(# call); \
289       message += " failed for "; \
290       message += reason; \
291       Fatal(message); \
292     } \
293   } while (false)
294 
295  public:
WatchDog(int64_t timeout_in_milliseconds)296   explicit WatchDog(int64_t timeout_in_milliseconds)
297       : timeout_in_milliseconds_(timeout_in_milliseconds),
298         shutting_down_(false) {
299     const char* reason = "dex2oat watch dog thread startup";
300     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_init, (&mutex_, nullptr), reason);
301 #ifndef __APPLE__
302     pthread_condattr_t condattr;
303     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_condattr_init, (&condattr), reason);
304     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_condattr_setclock, (&condattr, CLOCK_MONOTONIC), reason);
305     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_init, (&cond_, &condattr), reason);
306     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_condattr_destroy, (&condattr), reason);
307 #endif
308     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_init, (&attr_), reason);
309     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_create, (&pthread_, &attr_, &CallBack, this), reason);
310     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_destroy, (&attr_), reason);
311   }
~WatchDog()312   ~WatchDog() {
313     const char* reason = "dex2oat watch dog thread shutdown";
314     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
315     shutting_down_ = true;
316     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_signal, (&cond_), reason);
317     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
318 
319     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_join, (pthread_, nullptr), reason);
320 
321     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_destroy, (&cond_), reason);
322     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_destroy, (&mutex_), reason);
323   }
324 
SetRuntime(Runtime * runtime)325   static void SetRuntime(Runtime* runtime) {
326     const char* reason = "dex2oat watch dog set runtime";
327     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&runtime_mutex_), reason);
328     runtime_ = runtime;
329     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&runtime_mutex_), reason);
330   }
331 
332   // TODO: tune the multiplier for GC verification, the following is just to make the timeout
333   //       large.
334   static constexpr int64_t kWatchdogVerifyMultiplier =
335       kVerifyObjectSupport > kVerifyObjectModeFast ? 100 : 1;
336 
337   // When setting timeouts, keep in mind that the build server may not be as fast as your
338   // desktop. Debug builds are slower so they have larger timeouts.
339   static constexpr int64_t kWatchdogSlowdownFactor = kIsDebugBuild ? 5U : 1U;
340 
341   // 9.5 minutes scaled by kSlowdownFactor. This is slightly smaller than the Package Manager
342   // watchdog (PackageManagerService.WATCHDOG_TIMEOUT, 10 minutes), so that dex2oat will abort
343   // itself before that watchdog would take down the system server.
344   static constexpr int64_t kWatchDogTimeoutSeconds = kWatchdogSlowdownFactor * (9 * 60 + 30);
345 
346   static constexpr int64_t kDefaultWatchdogTimeoutInMS =
347       kWatchdogVerifyMultiplier * kWatchDogTimeoutSeconds * 1000;
348 
349  private:
CallBack(void * arg)350   static void* CallBack(void* arg) {
351     WatchDog* self = reinterpret_cast<WatchDog*>(arg);
352     ::art::SetThreadName("dex2oat watch dog");
353     self->Wait();
354     return nullptr;
355   }
356 
Fatal(const std::string & message)357   NO_RETURN static void Fatal(const std::string& message) {
358     // TODO: When we can guarantee it won't prevent shutdown in error cases, move to LOG. However,
359     //       it's rather easy to hang in unwinding.
360     //       LogLine also avoids ART logging lock issues, as it's really only a wrapper around
361     //       logcat logging or stderr output.
362     LogHelper::LogLineLowStack(__FILE__, __LINE__, LogSeverity::FATAL, message.c_str());
363 
364     // If we're on the host, try to dump all threads to get a sense of what's going on. This is
365     // restricted to the host as the dump may itself go bad.
366     // TODO: Use a double watchdog timeout, so we can enable this on-device.
367     Runtime* runtime = GetRuntime();
368     if (!kIsTargetBuild && runtime != nullptr) {
369       runtime->AttachCurrentThread("Watchdog thread attached for dumping",
370                                    true,
371                                    nullptr,
372                                    false);
373       runtime->DumpForSigQuit(std::cerr);
374     }
375     exit(1);
376   }
377 
Wait()378   void Wait() {
379     timespec timeout_ts;
380 #if defined(__APPLE__)
381     InitTimeSpec(true, CLOCK_REALTIME, timeout_in_milliseconds_, 0, &timeout_ts);
382 #else
383     InitTimeSpec(true, CLOCK_MONOTONIC, timeout_in_milliseconds_, 0, &timeout_ts);
384 #endif
385     const char* reason = "dex2oat watch dog thread waiting";
386     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
387     while (!shutting_down_) {
388       int rc = pthread_cond_timedwait(&cond_, &mutex_, &timeout_ts);
389       if (rc == EINTR) {
390         continue;
391       } else if (rc == ETIMEDOUT) {
392         Fatal(StringPrintf("dex2oat did not finish after %" PRId64 " seconds",
393                            timeout_in_milliseconds_/1000));
394       } else if (rc != 0) {
395         std::string message(StringPrintf("pthread_cond_timedwait failed: %s", strerror(rc)));
396         Fatal(message);
397       }
398     }
399     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
400   }
401 
GetRuntime()402   static Runtime* GetRuntime() {
403     const char* reason = "dex2oat watch dog get runtime";
404     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&runtime_mutex_), reason);
405     Runtime* runtime = runtime_;
406     CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&runtime_mutex_), reason);
407     return runtime;
408   }
409 
410   static pthread_mutex_t runtime_mutex_;
411   static Runtime* runtime_;
412 
413   // TODO: Switch to Mutex when we can guarantee it won't prevent shutdown in error cases.
414   pthread_mutex_t mutex_;
415   pthread_cond_t cond_;
416   pthread_attr_t attr_;
417   pthread_t pthread_;
418 
419   const int64_t timeout_in_milliseconds_;
420   bool shutting_down_;
421 };
422 
423 pthread_mutex_t WatchDog::runtime_mutex_ = PTHREAD_MUTEX_INITIALIZER;
424 Runtime* WatchDog::runtime_ = nullptr;
425 
426 // Helper class for overriding `java.lang.ThreadLocal.nextHashCode`.
427 //
428 // The class ThreadLocal has a static field nextHashCode used for assigning hash codes to
429 // new ThreadLocal objects. Since the class and the object referenced by the field are
430 // in the boot image, they cannot be modified under normal rules for AOT compilation.
431 // However, since this is a private detail that's used only for assigning hash codes and
432 // everything should work fine with different hash codes, we override the field for the
433 // compilation, providing another object that the AOT class initialization can modify.
434 class ThreadLocalHashOverride {
435  public:
ThreadLocalHashOverride(bool apply,int32_t initial_value)436   ThreadLocalHashOverride(bool apply, int32_t initial_value) {
437     Thread* self = Thread::Current();
438     ScopedObjectAccess soa(self);
439     hs_.emplace(self);  // While holding the mutator lock.
440     Runtime* runtime = Runtime::Current();
441     klass_ = hs_->NewHandle(apply
442         ? runtime->GetClassLinker()->LookupClass(self,
443                                                  "Ljava/lang/ThreadLocal;",
444                                                  /*class_loader=*/ nullptr)
445         : nullptr);
446     field_ = ((klass_ != nullptr) && klass_->IsVisiblyInitialized())
447         ? klass_->FindDeclaredStaticField("nextHashCode",
448                                           "Ljava/util/concurrent/atomic/AtomicInteger;")
449         : nullptr;
450     old_field_value_ =
451         hs_->NewHandle(field_ != nullptr ? field_->GetObject(klass_.Get()) : nullptr);
452     if (old_field_value_ != nullptr) {
453       gc::AllocatorType allocator_type = runtime->GetHeap()->GetCurrentAllocator();
454       StackHandleScope<1u> hs2(self);
455       Handle<mirror::Object> new_field_value = hs2.NewHandle(
456           old_field_value_->GetClass()->Alloc(self, allocator_type));
457       PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
458       ArtMethod* constructor = old_field_value_->GetClass()->FindConstructor("(I)V", pointer_size);
459       CHECK(constructor != nullptr);
460       uint32_t args[] = {
461           reinterpret_cast32<uint32_t>(new_field_value.Get()),
462           static_cast<uint32_t>(initial_value)
463       };
464       JValue result;
465       constructor->Invoke(self, args, sizeof(args), &result, /*shorty=*/ "VI");
466       CHECK(!self->IsExceptionPending());
467       field_->SetObject</*kTransactionActive=*/ false>(klass_.Get(), new_field_value.Get());
468     }
469     if (apply && old_field_value_ == nullptr) {
470       if ((klass_ != nullptr) && klass_->IsVisiblyInitialized()) {
471         // This would mean that the implementation of ThreadLocal has changed
472         // and the code above is no longer applicable.
473         LOG(ERROR) << "Failed to override ThreadLocal.nextHashCode";
474       } else {
475         VLOG(compiler) << "ThreadLocal is not initialized in the primary boot image.";
476       }
477     }
478   }
479 
~ThreadLocalHashOverride()480   ~ThreadLocalHashOverride() {
481     ScopedObjectAccess soa(hs_->Self());
482     if (old_field_value_ != nullptr) {
483       // Allow the overriding object to be collected.
484       field_->SetObject</*kTransactionActive=*/ false>(klass_.Get(), old_field_value_.Get());
485     }
486     hs_.reset();  // While holding the mutator lock.
487   }
488 
489  private:
490   std::optional<StackHandleScope<2u>> hs_;
491   Handle<mirror::Class> klass_;
492   ArtField* field_;
493   Handle<mirror::Object> old_field_value_;
494 };
495 
496 class OatKeyValueStore : public SafeMap<std::string, std::string> {
497  public:
498   using SafeMap::Put;
499 
Put(const std::string & k,bool v)500   iterator Put(const std::string& k, bool v) {
501     return SafeMap::Put(k, v ? OatHeader::kTrueValue : OatHeader::kFalseValue);
502   }
503 };
504 
505 class Dex2Oat final {
506  public:
Dex2Oat(TimingLogger * timings)507   explicit Dex2Oat(TimingLogger* timings) :
508       compiler_kind_(Compiler::kOptimizing),
509       // Take the default set of instruction features from the build.
510       key_value_store_(nullptr),
511       verification_results_(nullptr),
512       runtime_(nullptr),
513       thread_count_(sysconf(_SC_NPROCESSORS_CONF)),
514       start_ns_(NanoTime()),
515       start_cputime_ns_(ProcessCpuNanoTime()),
516       strip_(false),
517       oat_fd_(-1),
518       input_vdex_fd_(-1),
519       output_vdex_fd_(-1),
520       input_vdex_file_(nullptr),
521       dm_fd_(-1),
522       zip_fd_(-1),
523       image_fd_(-1),
524       have_multi_image_arg_(false),
525       multi_image_(false),
526       image_base_(0U),
527       image_storage_mode_(ImageHeader::kStorageModeUncompressed),
528       passes_to_run_filename_(nullptr),
529       dirty_image_objects_filename_(nullptr),
530       updatable_bcp_packages_filename_(nullptr),
531       is_host_(false),
532       elf_writers_(),
533       oat_writers_(),
534       rodata_(),
535       image_writer_(nullptr),
536       driver_(nullptr),
537       opened_dex_files_maps_(),
538       opened_dex_files_(),
539       avoid_storing_invocation_(false),
540       swap_fd_(File::kInvalidFd),
541       app_image_fd_(File::kInvalidFd),
542       profile_file_fd_(File::kInvalidFd),
543       timings_(timings),
544       force_determinism_(false),
545       check_linkage_conditions_(false),
546       crash_on_linkage_violation_(false),
547       compile_individually_(false),
548       profile_load_attempted_(false)
549       {}
550 
~Dex2Oat()551   ~Dex2Oat() {
552     // Log completion time before deleting the runtime_, because this accesses
553     // the runtime.
554     LogCompletionTime();
555 
556     if (!kIsDebugBuild && !(kRunningOnMemoryTool && kMemoryToolDetectsLeaks)) {
557       // We want to just exit on non-debug builds, not bringing the runtime down
558       // in an orderly fashion. So release the following fields.
559       driver_.release();                // NOLINT
560       image_writer_.release();          // NOLINT
561       for (std::unique_ptr<const DexFile>& dex_file : opened_dex_files_) {
562         dex_file.release();             // NOLINT
563       }
564       new std::vector<MemMap>(std::move(opened_dex_files_maps_));  // Leak MemMaps.
565       for (std::unique_ptr<File>& vdex_file : vdex_files_) {
566         vdex_file.release();            // NOLINT
567       }
568       for (std::unique_ptr<File>& oat_file : oat_files_) {
569         oat_file.release();             // NOLINT
570       }
571       runtime_.release();               // NOLINT
572       verification_results_.release();  // NOLINT
573       key_value_store_.release();       // NOLINT
574     }
575 
576     // Remind the user if they passed testing only flags.
577     if (!kIsTargetBuild && force_allow_oj_inlines_) {
578       LOG(ERROR) << "Inlines allowed from core-oj! FOR TESTING USE ONLY! DO NOT DISTRIBUTE"
579                   << " BINARIES BUILT WITH THIS OPTION!";
580     }
581   }
582 
583   struct ParserOptions {
584     std::vector<std::string> oat_symbols;
585     std::string boot_image_filename;
586     int64_t watch_dog_timeout_in_ms = -1;
587     bool watch_dog_enabled = true;
588     bool requested_specific_compiler = false;
589     std::string error_msg;
590   };
591 
ParseBase(const std::string & option)592   void ParseBase(const std::string& option) {
593     char* end;
594     image_base_ = strtoul(option.c_str(), &end, 16);
595     if (end == option.c_str() || *end != '\0') {
596       Usage("Failed to parse hexadecimal value for option %s", option.data());
597     }
598   }
599 
VerifyProfileData()600   bool VerifyProfileData() {
601     return profile_compilation_info_->VerifyProfileData(compiler_options_->dex_files_for_oat_file_);
602   }
603 
ParseInstructionSetVariant(const std::string & option,ParserOptions * parser_options)604   void ParseInstructionSetVariant(const std::string& option, ParserOptions* parser_options) {
605     compiler_options_->instruction_set_features_ = InstructionSetFeatures::FromVariant(
606         compiler_options_->instruction_set_, option, &parser_options->error_msg);
607     if (compiler_options_->instruction_set_features_ == nullptr) {
608       Usage("%s", parser_options->error_msg.c_str());
609     }
610   }
611 
ParseInstructionSetFeatures(const std::string & option,ParserOptions * parser_options)612   void ParseInstructionSetFeatures(const std::string& option, ParserOptions* parser_options) {
613     if (compiler_options_->instruction_set_features_ == nullptr) {
614       compiler_options_->instruction_set_features_ = InstructionSetFeatures::FromVariant(
615           compiler_options_->instruction_set_, "default", &parser_options->error_msg);
616       if (compiler_options_->instruction_set_features_ == nullptr) {
617         Usage("Problem initializing default instruction set features variant: %s",
618               parser_options->error_msg.c_str());
619       }
620     }
621     compiler_options_->instruction_set_features_ =
622         compiler_options_->instruction_set_features_->AddFeaturesFromString(
623             option, &parser_options->error_msg);
624     if (compiler_options_->instruction_set_features_ == nullptr) {
625       Usage("Error parsing '%s': %s", option.c_str(), parser_options->error_msg.c_str());
626     }
627   }
628 
ProcessOptions(ParserOptions * parser_options)629   void ProcessOptions(ParserOptions* parser_options) {
630     compiler_options_->compiler_type_ = CompilerOptions::CompilerType::kAotCompiler;
631     compiler_options_->compile_pic_ = true;  // All AOT compilation is PIC.
632 
633     if (android_root_.empty()) {
634       const char* android_root_env_var = getenv("ANDROID_ROOT");
635       if (android_root_env_var == nullptr) {
636         Usage("--android-root unspecified and ANDROID_ROOT not set");
637       }
638       android_root_ += android_root_env_var;
639     }
640 
641     if (!parser_options->boot_image_filename.empty()) {
642       boot_image_filename_ = parser_options->boot_image_filename;
643     }
644 
645     DCHECK(compiler_options_->image_type_ == CompilerOptions::ImageType::kNone);
646     if (!image_filenames_.empty() || image_fd_ != -1) {
647       // If no boot image is provided, then dex2oat is compiling the primary boot image,
648       // otherwise it is compiling the boot image extension.
649       compiler_options_->image_type_ = boot_image_filename_.empty()
650           ? CompilerOptions::ImageType::kBootImage
651           : CompilerOptions::ImageType::kBootImageExtension;
652     }
653     if (app_image_fd_ != -1 || !app_image_file_name_.empty()) {
654       if (compiler_options_->IsBootImage() || compiler_options_->IsBootImageExtension()) {
655         Usage("Can't have both (--image or --image-fd) and (--app-image-fd or --app-image-file)");
656       }
657       compiler_options_->image_type_ = CompilerOptions::ImageType::kAppImage;
658     }
659 
660     if (!image_filenames_.empty() && image_fd_ != -1) {
661       Usage("Can't have both --image and --image-fd");
662     }
663 
664     if (oat_filenames_.empty() && oat_fd_ == -1) {
665       Usage("Output must be supplied with either --oat-file or --oat-fd");
666     }
667 
668     if (input_vdex_fd_ != -1 && !input_vdex_.empty()) {
669       Usage("Can't have both --input-vdex-fd and --input-vdex");
670     }
671 
672     if (output_vdex_fd_ != -1 && !output_vdex_.empty()) {
673       Usage("Can't have both --output-vdex-fd and --output-vdex");
674     }
675 
676     if (!oat_filenames_.empty() && oat_fd_ != -1) {
677       Usage("--oat-file should not be used with --oat-fd");
678     }
679 
680     if ((output_vdex_fd_ == -1) != (oat_fd_ == -1)) {
681       Usage("VDEX and OAT output must be specified either with one --oat-file "
682             "or with --oat-fd and --output-vdex-fd file descriptors");
683     }
684 
685     if ((image_fd_ != -1) && (oat_fd_ == -1)) {
686       Usage("--image-fd must be used with --oat_fd and --output_vdex_fd");
687     }
688 
689     if (!parser_options->oat_symbols.empty() && oat_fd_ != -1) {
690       Usage("--oat-symbols should not be used with --oat-fd");
691     }
692 
693     if (!parser_options->oat_symbols.empty() && is_host_) {
694       Usage("--oat-symbols should not be used with --host");
695     }
696 
697     if (output_vdex_fd_ != -1 && !image_filenames_.empty()) {
698       Usage("--output-vdex-fd should not be used with --image");
699     }
700 
701     if (oat_fd_ != -1 && !image_filenames_.empty()) {
702       Usage("--oat-fd should not be used with --image");
703     }
704 
705     if ((input_vdex_fd_ != -1 || !input_vdex_.empty()) &&
706         (dm_fd_ != -1 || !dm_file_location_.empty())) {
707       Usage("An input vdex should not be passed with a .dm file");
708     }
709 
710     if (!parser_options->oat_symbols.empty() &&
711         parser_options->oat_symbols.size() != oat_filenames_.size()) {
712       Usage("--oat-file arguments do not match --oat-symbols arguments");
713     }
714 
715     if (!image_filenames_.empty() && image_filenames_.size() != oat_filenames_.size()) {
716       Usage("--oat-file arguments do not match --image arguments");
717     }
718 
719     if (!IsBootImage() && boot_image_filename_.empty()) {
720       DCHECK(!IsBootImageExtension());
721       boot_image_filename_ =
722           GetDefaultBootImageLocation(android_root_, /*deny_art_apex_data_files=*/false);
723     }
724 
725     if (dex_filenames_.empty() && zip_fd_ == -1) {
726       Usage("Input must be supplied with either --dex-file or --zip-fd");
727     }
728 
729     if (!dex_filenames_.empty() && zip_fd_ != -1) {
730       Usage("--dex-file should not be used with --zip-fd");
731     }
732 
733     if (!dex_filenames_.empty() && !zip_location_.empty()) {
734       Usage("--dex-file should not be used with --zip-location");
735     }
736 
737     if (dex_locations_.empty()) {
738       dex_locations_ = dex_filenames_;
739     } else if (dex_locations_.size() != dex_filenames_.size()) {
740       Usage("--dex-location arguments do not match --dex-file arguments");
741     }
742 
743     if (!dex_filenames_.empty() && !oat_filenames_.empty()) {
744       if (oat_filenames_.size() != 1 && oat_filenames_.size() != dex_filenames_.size()) {
745         Usage("--oat-file arguments must be singular or match --dex-file arguments");
746       }
747     }
748 
749     if (zip_fd_ != -1 && zip_location_.empty()) {
750       Usage("--zip-location should be supplied with --zip-fd");
751     }
752 
753     if (boot_image_filename_.empty()) {
754       if (image_base_ == 0) {
755         Usage("Non-zero --base not specified for boot image");
756       }
757     } else {
758       if (image_base_ != 0) {
759         Usage("Non-zero --base specified for app image or boot image extension");
760       }
761     }
762 
763     if (have_multi_image_arg_) {
764       if (!IsImage()) {
765         Usage("--multi-image or --single-image specified for non-image compilation");
766       }
767     } else {
768       // Use the default, i.e. multi-image for boot image and boot image extension.
769       multi_image_ = IsBootImage() || IsBootImageExtension();  // Shall pass checks below.
770     }
771     if (IsBootImage() && !multi_image_) {
772       Usage("--single-image specified for primary boot image");
773     }
774     if (IsAppImage() && multi_image_) {
775       Usage("--multi-image specified for app image");
776     }
777 
778     if (image_fd_ != -1 && multi_image_) {
779       Usage("--single-image not specified for --image-fd");
780     }
781 
782     const bool have_profile_file = !profile_file_.empty();
783     const bool have_profile_fd = profile_file_fd_ != File::kInvalidFd;
784     if (have_profile_file && have_profile_fd) {
785       Usage("Profile file should not be specified with both --profile-file-fd and --profile-file");
786     }
787 
788     if (!parser_options->oat_symbols.empty()) {
789       oat_unstripped_ = std::move(parser_options->oat_symbols);
790     }
791 
792     if (compiler_options_->instruction_set_features_ == nullptr) {
793       // '--instruction-set-features/--instruction-set-variant' were not used.
794       // Use features for the 'default' variant.
795       compiler_options_->instruction_set_features_ = InstructionSetFeatures::FromVariant(
796           compiler_options_->instruction_set_, "default", &parser_options->error_msg);
797       if (compiler_options_->instruction_set_features_ == nullptr) {
798         Usage("Problem initializing default instruction set features variant: %s",
799               parser_options->error_msg.c_str());
800       }
801     }
802 
803     if (compiler_options_->instruction_set_ == kRuntimeISA) {
804       std::unique_ptr<const InstructionSetFeatures> runtime_features(
805           InstructionSetFeatures::FromCppDefines());
806       if (!compiler_options_->GetInstructionSetFeatures()->Equals(runtime_features.get())) {
807         LOG(WARNING) << "Mismatch between dex2oat instruction set features to use ("
808             << *compiler_options_->GetInstructionSetFeatures()
809             << ") and those from CPP defines (" << *runtime_features
810             << ") for the command line:\n" << CommandLine();
811       }
812     }
813 
814     if ((IsBootImage() || IsBootImageExtension()) && updatable_bcp_packages_filename_ != nullptr) {
815       Usage("Do not specify --updatable-bcp-packages-file for boot image compilation.");
816     }
817 
818     if (!cpu_set_.empty()) {
819       SetCpuAffinity(cpu_set_);
820     }
821 
822     if (compiler_options_->inline_max_code_units_ == CompilerOptions::kUnsetInlineMaxCodeUnits) {
823       compiler_options_->inline_max_code_units_ = CompilerOptions::kDefaultInlineMaxCodeUnits;
824     }
825 
826     // Checks are all explicit until we know the architecture.
827     // Set the compilation target's implicit checks options.
828     switch (compiler_options_->GetInstructionSet()) {
829       case InstructionSet::kArm:
830       case InstructionSet::kThumb2:
831       case InstructionSet::kArm64:
832       case InstructionSet::kX86:
833       case InstructionSet::kX86_64:
834         compiler_options_->implicit_null_checks_ = true;
835         compiler_options_->implicit_so_checks_ = true;
836         break;
837 
838       default:
839         // Defaults are correct.
840         break;
841     }
842 
843     // Done with usage checks, enable watchdog if requested
844     if (parser_options->watch_dog_enabled) {
845       int64_t timeout = parser_options->watch_dog_timeout_in_ms > 0
846                             ? parser_options->watch_dog_timeout_in_ms
847                             : WatchDog::kDefaultWatchdogTimeoutInMS;
848       watchdog_.reset(new WatchDog(timeout));
849     }
850 
851     // Fill some values into the key-value store for the oat header.
852     key_value_store_.reset(new OatKeyValueStore());
853 
854     // Automatically force determinism for the boot image and boot image extensions in a host build.
855     if (!kIsTargetBuild && (IsBootImage() || IsBootImageExtension())) {
856       force_determinism_ = true;
857     }
858     compiler_options_->force_determinism_ = force_determinism_;
859 
860     compiler_options_->check_linkage_conditions_ = check_linkage_conditions_;
861     compiler_options_->crash_on_linkage_violation_ = crash_on_linkage_violation_;
862 
863     if (passes_to_run_filename_ != nullptr) {
864       passes_to_run_ = ReadCommentedInputFromFile<std::vector<std::string>>(
865           passes_to_run_filename_,
866           nullptr);         // No post-processing.
867       if (passes_to_run_.get() == nullptr) {
868         Usage("Failed to read list of passes to run.");
869       }
870     }
871 
872     // Trim the boot image location to not include any specified profile. Note
873     // that the logic below will include the first boot image extension, but not
874     // the ones that could be listed after the profile of that extension. This
875     // works for our current top use case:
876     // boot.art:/system/framework/boot-framework.art
877     // But this would need to be adjusted if we had to support different use
878     // cases.
879     size_t profile_separator_pos = boot_image_filename_.find(ImageSpace::kProfileSeparator);
880     if (profile_separator_pos != std::string::npos) {
881       DCHECK(!IsBootImage());  // For primary boot image the boot_image_filename_ is empty.
882       if (IsBootImageExtension()) {
883         Usage("Unsupported profile specification in boot image location (%s) for extension.",
884               boot_image_filename_.c_str());
885       }
886       VLOG(compiler)
887           << "Truncating boot image location " << boot_image_filename_
888           << " because it contains profile specification. Truncated: "
889           << boot_image_filename_.substr(/*pos*/ 0u, /*length*/ profile_separator_pos);
890       boot_image_filename_.resize(profile_separator_pos);
891     }
892 
893     compiler_options_->passes_to_run_ = passes_to_run_.get();
894   }
895 
ExpandOatAndImageFilenames()896   void ExpandOatAndImageFilenames() {
897     ArrayRef<const std::string> locations(dex_locations_);
898     if (!multi_image_) {
899       locations = locations.SubArray(/*pos=*/ 0u, /*length=*/ 1u);
900     }
901     if (image_fd_ == -1) {
902       if (image_filenames_[0].rfind('/') == std::string::npos) {
903         Usage("Unusable boot image filename %s", image_filenames_[0].c_str());
904       }
905       image_filenames_ = ImageSpace::ExpandMultiImageLocations(
906           locations, image_filenames_[0], IsBootImageExtension());
907 
908       if (oat_filenames_[0].rfind('/') == std::string::npos) {
909         Usage("Unusable boot image oat filename %s", oat_filenames_[0].c_str());
910       }
911       oat_filenames_ = ImageSpace::ExpandMultiImageLocations(
912           locations, oat_filenames_[0], IsBootImageExtension());
913     } else {
914       DCHECK(!multi_image_);
915       std::vector<std::string> oat_locations = ImageSpace::ExpandMultiImageLocations(
916           locations, oat_location_, IsBootImageExtension());
917       DCHECK_EQ(1u, oat_locations.size());
918       oat_location_ = oat_locations[0];
919     }
920 
921     if (!oat_unstripped_.empty()) {
922       if (oat_unstripped_[0].rfind('/') == std::string::npos) {
923         Usage("Unusable boot image symbol filename %s", oat_unstripped_[0].c_str());
924       }
925       oat_unstripped_ = ImageSpace::ExpandMultiImageLocations(
926            locations, oat_unstripped_[0], IsBootImageExtension());
927     }
928   }
929 
InsertCompileOptions(int argc,char ** argv)930   void InsertCompileOptions(int argc, char** argv) {
931     if (!avoid_storing_invocation_) {
932       std::ostringstream oss;
933       for (int i = 0; i < argc; ++i) {
934         if (i > 0) {
935           oss << ' ';
936         }
937         oss << argv[i];
938       }
939       key_value_store_->Put(OatHeader::kDex2OatCmdLineKey, oss.str());
940     }
941     key_value_store_->Put(OatHeader::kDebuggableKey, compiler_options_->debuggable_);
942     key_value_store_->Put(OatHeader::kNativeDebuggableKey,
943                           compiler_options_->GetNativeDebuggable());
944     key_value_store_->Put(OatHeader::kCompilerFilter,
945                           CompilerFilter::NameOfFilter(compiler_options_->GetCompilerFilter()));
946     key_value_store_->Put(OatHeader::kConcurrentCopying, kUseReadBarrier);
947     key_value_store_->Put(OatHeader::kRequiresImage, compiler_options_->IsGeneratingImage());
948     if (invocation_file_.get() != -1) {
949       std::ostringstream oss;
950       for (int i = 0; i < argc; ++i) {
951         if (i > 0) {
952           oss << std::endl;
953         }
954         oss << argv[i];
955       }
956       std::string invocation(oss.str());
957       if (TEMP_FAILURE_RETRY(write(invocation_file_.get(),
958                                    invocation.c_str(),
959                                    invocation.size())) == -1) {
960         Usage("Unable to write invocation file");
961       }
962     }
963   }
964 
965   // This simple forward is here so the string specializations below don't look out of place.
966   template <typename T, typename U>
AssignIfExists(Dex2oatArgumentMap & map,const Dex2oatArgumentMap::Key<T> & key,U * out)967   void AssignIfExists(Dex2oatArgumentMap& map,
968                       const Dex2oatArgumentMap::Key<T>& key,
969                       U* out) {
970     map.AssignIfExists(key, out);
971   }
972 
973   // Specializations to handle const char* vs std::string.
AssignIfExists(Dex2oatArgumentMap & map,const Dex2oatArgumentMap::Key<std::string> & key,const char ** out)974   void AssignIfExists(Dex2oatArgumentMap& map,
975                       const Dex2oatArgumentMap::Key<std::string>& key,
976                       const char** out) {
977     if (map.Exists(key)) {
978       char_backing_storage_.push_front(std::move(*map.Get(key)));
979       *out = char_backing_storage_.front().c_str();
980     }
981   }
AssignIfExists(Dex2oatArgumentMap & map,const Dex2oatArgumentMap::Key<std::vector<std::string>> & key,std::vector<const char * > * out)982   void AssignIfExists(Dex2oatArgumentMap& map,
983                       const Dex2oatArgumentMap::Key<std::vector<std::string>>& key,
984                       std::vector<const char*>* out) {
985     if (map.Exists(key)) {
986       for (auto& val : *map.Get(key)) {
987         char_backing_storage_.push_front(std::move(val));
988         out->push_back(char_backing_storage_.front().c_str());
989       }
990     }
991   }
992 
993   template <typename T>
AssignTrueIfExists(Dex2oatArgumentMap & map,const Dex2oatArgumentMap::Key<T> & key,bool * out)994   void AssignTrueIfExists(Dex2oatArgumentMap& map,
995                           const Dex2oatArgumentMap::Key<T>& key,
996                           bool* out) {
997     if (map.Exists(key)) {
998       *out = true;
999     }
1000   }
1001 
AssignIfExists(Dex2oatArgumentMap & map,const Dex2oatArgumentMap::Key<std::string> & key,std::vector<std::string> * out)1002   void AssignIfExists(Dex2oatArgumentMap& map,
1003                       const Dex2oatArgumentMap::Key<std::string>& key,
1004                       std::vector<std::string>* out) {
1005     DCHECK(out->empty());
1006     if (map.Exists(key)) {
1007       out->push_back(*map.Get(key));
1008     }
1009   }
1010 
1011   // Parse the arguments from the command line. In case of an unrecognized option or impossible
1012   // values/combinations, a usage error will be displayed and exit() is called. Thus, if the method
1013   // returns, arguments have been successfully parsed.
ParseArgs(int argc,char ** argv)1014   void ParseArgs(int argc, char** argv) {
1015     original_argc = argc;
1016     original_argv = argv;
1017 
1018     Locks::Init();
1019     InitLogging(argv, Runtime::Abort);
1020 
1021     compiler_options_.reset(new CompilerOptions());
1022 
1023     using M = Dex2oatArgumentMap;
1024     std::string error_msg;
1025     std::unique_ptr<M> args_uptr = M::Parse(argc, const_cast<const char**>(argv), &error_msg);
1026     if (args_uptr == nullptr) {
1027       Usage("Failed to parse command line: %s", error_msg.c_str());
1028       UNREACHABLE();
1029     }
1030 
1031     M& args = *args_uptr;
1032 
1033     std::unique_ptr<ParserOptions> parser_options(new ParserOptions());
1034 
1035     AssignIfExists(args, M::CompactDexLevel, &compact_dex_level_);
1036     AssignIfExists(args, M::DexFiles, &dex_filenames_);
1037     AssignIfExists(args, M::DexLocations, &dex_locations_);
1038     AssignIfExists(args, M::OatFile, &oat_filenames_);
1039     AssignIfExists(args, M::OatSymbols, &parser_options->oat_symbols);
1040     AssignTrueIfExists(args, M::Strip, &strip_);
1041     AssignIfExists(args, M::ImageFilename, &image_filenames_);
1042     AssignIfExists(args, M::ImageFd, &image_fd_);
1043     AssignIfExists(args, M::ZipFd, &zip_fd_);
1044     AssignIfExists(args, M::ZipLocation, &zip_location_);
1045     AssignIfExists(args, M::InputVdexFd, &input_vdex_fd_);
1046     AssignIfExists(args, M::OutputVdexFd, &output_vdex_fd_);
1047     AssignIfExists(args, M::InputVdex, &input_vdex_);
1048     AssignIfExists(args, M::OutputVdex, &output_vdex_);
1049     AssignIfExists(args, M::DmFd, &dm_fd_);
1050     AssignIfExists(args, M::DmFile, &dm_file_location_);
1051     AssignIfExists(args, M::OatFd, &oat_fd_);
1052     AssignIfExists(args, M::OatLocation, &oat_location_);
1053     AssignIfExists(args, M::Watchdog, &parser_options->watch_dog_enabled);
1054     AssignIfExists(args, M::WatchdogTimeout, &parser_options->watch_dog_timeout_in_ms);
1055     AssignIfExists(args, M::Threads, &thread_count_);
1056     AssignIfExists(args, M::CpuSet, &cpu_set_);
1057     AssignIfExists(args, M::Passes, &passes_to_run_filename_);
1058     AssignIfExists(args, M::BootImage, &parser_options->boot_image_filename);
1059     AssignIfExists(args, M::AndroidRoot, &android_root_);
1060     AssignIfExists(args, M::Profile, &profile_file_);
1061     AssignIfExists(args, M::ProfileFd, &profile_file_fd_);
1062     AssignIfExists(args, M::RuntimeOptions, &runtime_args_);
1063     AssignIfExists(args, M::SwapFile, &swap_file_name_);
1064     AssignIfExists(args, M::SwapFileFd, &swap_fd_);
1065     AssignIfExists(args, M::SwapDexSizeThreshold, &min_dex_file_cumulative_size_for_swap_);
1066     AssignIfExists(args, M::SwapDexCountThreshold, &min_dex_files_for_swap_);
1067     AssignIfExists(args, M::VeryLargeAppThreshold, &very_large_threshold_);
1068     AssignIfExists(args, M::AppImageFile, &app_image_file_name_);
1069     AssignIfExists(args, M::AppImageFileFd, &app_image_fd_);
1070     AssignIfExists(args, M::NoInlineFrom, &no_inline_from_string_);
1071     AssignIfExists(args, M::ClasspathDir, &classpath_dir_);
1072     AssignIfExists(args, M::DirtyImageObjects, &dirty_image_objects_filename_);
1073     AssignIfExists(args, M::UpdatableBcpPackagesFile, &updatable_bcp_packages_filename_);
1074     AssignIfExists(args, M::ImageFormat, &image_storage_mode_);
1075     AssignIfExists(args, M::CompilationReason, &compilation_reason_);
1076     AssignTrueIfExists(args, M::CheckLinkageConditions, &check_linkage_conditions_);
1077     AssignTrueIfExists(args, M::CrashOnLinkageViolation, &crash_on_linkage_violation_);
1078     AssignTrueIfExists(args, M::ForceAllowOjInlines, &force_allow_oj_inlines_);
1079     AssignIfExists(args, M::PublicSdk, &public_sdk_);
1080     AssignIfExists(args, M::ApexVersions, &apex_versions_argument_);
1081 
1082     AssignIfExists(args, M::Backend, &compiler_kind_);
1083     parser_options->requested_specific_compiler = args.Exists(M::Backend);
1084 
1085     AssignIfExists(args, M::TargetInstructionSet, &compiler_options_->instruction_set_);
1086     // arm actually means thumb2.
1087     if (compiler_options_->instruction_set_ == InstructionSet::kArm) {
1088       compiler_options_->instruction_set_ = InstructionSet::kThumb2;
1089     }
1090 
1091     AssignTrueIfExists(args, M::Host, &is_host_);
1092     AssignTrueIfExists(args, M::AvoidStoringInvocation, &avoid_storing_invocation_);
1093     if (args.Exists(M::InvocationFile)) {
1094       invocation_file_.reset(open(args.Get(M::InvocationFile)->c_str(),
1095                                   O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC,
1096                                   S_IRUSR|S_IWUSR));
1097       if (invocation_file_.get() == -1) {
1098         int err = errno;
1099         Usage("Unable to open invocation file '%s' for writing due to %s.",
1100               args.Get(M::InvocationFile)->c_str(), strerror(err));
1101       }
1102     }
1103     AssignIfExists(args, M::CopyDexFiles, &copy_dex_files_);
1104 
1105     AssignTrueIfExists(args, M::MultiImage, &have_multi_image_arg_);
1106     AssignIfExists(args, M::MultiImage, &multi_image_);
1107 
1108     if (args.Exists(M::ForceDeterminism)) {
1109       force_determinism_ = true;
1110     }
1111     AssignTrueIfExists(args, M::CompileIndividually, &compile_individually_);
1112 
1113     if (args.Exists(M::Base)) {
1114       ParseBase(*args.Get(M::Base));
1115     }
1116     if (args.Exists(M::TargetInstructionSetVariant)) {
1117       ParseInstructionSetVariant(*args.Get(M::TargetInstructionSetVariant), parser_options.get());
1118     }
1119     if (args.Exists(M::TargetInstructionSetFeatures)) {
1120       ParseInstructionSetFeatures(*args.Get(M::TargetInstructionSetFeatures), parser_options.get());
1121     }
1122     if (args.Exists(M::ClassLoaderContext)) {
1123       std::string class_loader_context_arg = *args.Get(M::ClassLoaderContext);
1124       class_loader_context_ = ClassLoaderContext::Create(class_loader_context_arg);
1125       if (class_loader_context_ == nullptr) {
1126         Usage("Option --class-loader-context has an incorrect format: %s",
1127               class_loader_context_arg.c_str());
1128       }
1129       if (args.Exists(M::ClassLoaderContextFds)) {
1130         std::string str_fds_arg = *args.Get(M::ClassLoaderContextFds);
1131         std::vector<std::string> str_fds = android::base::Split(str_fds_arg, ":");
1132         for (const std::string& str_fd : str_fds) {
1133           class_loader_context_fds_.push_back(std::stoi(str_fd, nullptr, 0));
1134           if (class_loader_context_fds_.back() < 0) {
1135             Usage("Option --class-loader-context-fds has incorrect format: %s",
1136                 str_fds_arg.c_str());
1137           }
1138         }
1139       }
1140       if (args.Exists(M::StoredClassLoaderContext)) {
1141         const std::string stored_context_arg = *args.Get(M::StoredClassLoaderContext);
1142         stored_class_loader_context_ = ClassLoaderContext::Create(stored_context_arg);
1143         if (stored_class_loader_context_ == nullptr) {
1144           Usage("Option --stored-class-loader-context has an incorrect format: %s",
1145                 stored_context_arg.c_str());
1146         } else if (class_loader_context_->VerifyClassLoaderContextMatch(
1147             stored_context_arg,
1148             /*verify_names*/ false,
1149             /*verify_checksums*/ false) != ClassLoaderContext::VerificationResult::kVerifies) {
1150           Usage(
1151               "Option --stored-class-loader-context '%s' mismatches --class-loader-context '%s'",
1152               stored_context_arg.c_str(),
1153               class_loader_context_arg.c_str());
1154         }
1155       }
1156     } else if (args.Exists(M::StoredClassLoaderContext)) {
1157       Usage("Option --stored-class-loader-context should only be used if "
1158             "--class-loader-context is also specified");
1159     }
1160 
1161     // If we have a profile, change the default compiler filter to speed-profile
1162     // before reading compiler options.
1163     static_assert(CompilerFilter::kDefaultCompilerFilter == CompilerFilter::kSpeed);
1164     DCHECK_EQ(compiler_options_->GetCompilerFilter(), CompilerFilter::kSpeed);
1165     if (HasProfileInput()) {
1166       compiler_options_->SetCompilerFilter(CompilerFilter::kSpeedProfile);
1167     }
1168 
1169     if (!ReadCompilerOptions(args, compiler_options_.get(), &error_msg)) {
1170       Usage(error_msg.c_str());
1171     }
1172 
1173     ProcessOptions(parser_options.get());
1174   }
1175 
1176   // Check whether the oat output files are writable, and open them for later. Also open a swap
1177   // file, if a name is given.
OpenFile()1178   bool OpenFile() {
1179     // Prune non-existent dex files now so that we don't create empty oat files for multi-image.
1180     PruneNonExistentDexFiles();
1181 
1182     // Expand oat and image filenames for boot image and boot image extension.
1183     // This is mostly for multi-image but single-image also needs some processing.
1184     if (IsBootImage() || IsBootImageExtension()) {
1185       ExpandOatAndImageFilenames();
1186     }
1187 
1188     // OAT and VDEX file handling
1189     if (oat_fd_ == -1) {
1190       DCHECK(!oat_filenames_.empty());
1191       for (const std::string& oat_filename : oat_filenames_) {
1192         std::unique_ptr<File> oat_file(OS::CreateEmptyFile(oat_filename.c_str()));
1193         if (oat_file == nullptr) {
1194           PLOG(ERROR) << "Failed to create oat file: " << oat_filename;
1195           return false;
1196         }
1197         if (fchmod(oat_file->Fd(), 0644) != 0) {
1198           PLOG(ERROR) << "Failed to make oat file world readable: " << oat_filename;
1199           oat_file->Erase();
1200           return false;
1201         }
1202         oat_files_.push_back(std::move(oat_file));
1203         DCHECK_EQ(input_vdex_fd_, -1);
1204         if (!input_vdex_.empty()) {
1205           std::string error_msg;
1206           input_vdex_file_ = VdexFile::Open(input_vdex_,
1207                                             /* writable */ false,
1208                                             /* low_4gb */ false,
1209                                             DoEagerUnquickeningOfVdex(),
1210                                             &error_msg);
1211         }
1212 
1213         DCHECK_EQ(output_vdex_fd_, -1);
1214         std::string vdex_filename = output_vdex_.empty()
1215             ? ReplaceFileExtension(oat_filename, "vdex")
1216             : output_vdex_;
1217         if (vdex_filename == input_vdex_ && output_vdex_.empty()) {
1218           update_input_vdex_ = true;
1219           std::unique_ptr<File> vdex_file(OS::OpenFileReadWrite(vdex_filename.c_str()));
1220           vdex_files_.push_back(std::move(vdex_file));
1221         } else {
1222           std::unique_ptr<File> vdex_file(OS::CreateEmptyFile(vdex_filename.c_str()));
1223           if (vdex_file == nullptr) {
1224             PLOG(ERROR) << "Failed to open vdex file: " << vdex_filename;
1225             return false;
1226           }
1227           if (fchmod(vdex_file->Fd(), 0644) != 0) {
1228             PLOG(ERROR) << "Failed to make vdex file world readable: " << vdex_filename;
1229             vdex_file->Erase();
1230             return false;
1231           }
1232           vdex_files_.push_back(std::move(vdex_file));
1233         }
1234       }
1235     } else {
1236       std::unique_ptr<File> oat_file(
1237           new File(DupCloexec(oat_fd_), oat_location_, /* check_usage */ true));
1238       if (!oat_file->IsOpened()) {
1239         PLOG(ERROR) << "Failed to create oat file: " << oat_location_;
1240         return false;
1241       }
1242       if (oat_file->SetLength(0) != 0) {
1243         PLOG(WARNING) << "Truncating oat file " << oat_location_ << " failed.";
1244         oat_file->Erase();
1245         return false;
1246       }
1247       oat_files_.push_back(std::move(oat_file));
1248 
1249       if (input_vdex_fd_ != -1) {
1250         struct stat s;
1251         int rc = TEMP_FAILURE_RETRY(fstat(input_vdex_fd_, &s));
1252         if (rc == -1) {
1253           PLOG(WARNING) << "Failed getting length of vdex file";
1254         } else {
1255           std::string error_msg;
1256           input_vdex_file_ = VdexFile::Open(input_vdex_fd_,
1257                                             s.st_size,
1258                                             "vdex",
1259                                             /* writable */ false,
1260                                             /* low_4gb */ false,
1261                                             DoEagerUnquickeningOfVdex(),
1262                                             &error_msg);
1263           // If there's any problem with the passed vdex, just warn and proceed
1264           // without it.
1265           if (input_vdex_file_ == nullptr) {
1266             PLOG(WARNING) << "Failed opening vdex file: " << error_msg;
1267           }
1268         }
1269       }
1270 
1271       DCHECK_NE(output_vdex_fd_, -1);
1272       std::string vdex_location = ReplaceFileExtension(oat_location_, "vdex");
1273       std::unique_ptr<File> vdex_file(new File(
1274           DupCloexec(output_vdex_fd_), vdex_location, /* check_usage */ true));
1275       if (!vdex_file->IsOpened()) {
1276         PLOG(ERROR) << "Failed to create vdex file: " << vdex_location;
1277         return false;
1278       }
1279       if (input_vdex_file_ != nullptr && output_vdex_fd_ == input_vdex_fd_) {
1280         update_input_vdex_ = true;
1281       } else {
1282         if (vdex_file->SetLength(0) != 0) {
1283           PLOG(ERROR) << "Truncating vdex file " << vdex_location << " failed.";
1284           vdex_file->Erase();
1285           return false;
1286         }
1287       }
1288       vdex_files_.push_back(std::move(vdex_file));
1289 
1290       oat_filenames_.push_back(oat_location_);
1291     }
1292 
1293     // If we're updating in place a vdex file, be defensive and put an invalid vdex magic in case
1294     // dex2oat gets killed.
1295     // Note: we're only invalidating the magic data in the file, as dex2oat needs the rest of
1296     // the information to remain valid.
1297     if (update_input_vdex_) {
1298       File* vdex_file = vdex_files_.back().get();
1299       if (!vdex_file->PwriteFully(&VdexFile::VdexFileHeader::kVdexInvalidMagic,
1300                                   arraysize(VdexFile::VdexFileHeader::kVdexInvalidMagic),
1301                                   /*offset=*/ 0u)) {
1302         PLOG(ERROR) << "Failed to invalidate vdex header. File: " << vdex_file->GetPath();
1303         return false;
1304       }
1305 
1306       if (vdex_file->Flush() != 0) {
1307         PLOG(ERROR) << "Failed to flush stream after invalidating header of vdex file."
1308                     << " File: " << vdex_file->GetPath();
1309         return false;
1310       }
1311     }
1312 
1313     if (dm_fd_ != -1 || !dm_file_location_.empty()) {
1314       std::string error_msg;
1315       if (dm_fd_ != -1) {
1316         dm_file_.reset(ZipArchive::OpenFromFd(dm_fd_, "DexMetadata", &error_msg));
1317       } else {
1318         dm_file_.reset(ZipArchive::Open(dm_file_location_.c_str(), &error_msg));
1319       }
1320       if (dm_file_ == nullptr) {
1321         LOG(WARNING) << "Could not open DexMetadata archive " << error_msg;
1322       }
1323     }
1324 
1325     if (dm_file_ != nullptr) {
1326       DCHECK(input_vdex_file_ == nullptr);
1327       std::string error_msg;
1328       static const char* kDexMetadata = "DexMetadata";
1329       std::unique_ptr<ZipEntry> zip_entry(dm_file_->Find(VdexFile::kVdexNameInDmFile, &error_msg));
1330       if (zip_entry == nullptr) {
1331         LOG(INFO) << "No " << VdexFile::kVdexNameInDmFile << " file in DexMetadata archive. "
1332                   << "Not doing fast verification.";
1333       } else {
1334         MemMap input_file = zip_entry->MapDirectlyOrExtract(
1335             VdexFile::kVdexNameInDmFile,
1336             kDexMetadata,
1337             &error_msg,
1338             alignof(VdexFile));
1339         if (!input_file.IsValid()) {
1340           LOG(WARNING) << "Could not open vdex file in DexMetadata archive: " << error_msg;
1341         } else {
1342           input_vdex_file_ = std::make_unique<VdexFile>(std::move(input_file));
1343           if (!input_vdex_file_->IsValid()) {
1344             // Ideally we would do this validation at the framework level but the framework
1345             // has not knowledge of the .vdex format and adding new APIs just for it is
1346             // overkill.
1347             // TODO(calin): include this in dex2oat metrics.
1348             LOG(WARNING) << "The dex metadata .vdex is not valid. Ignoring it.";
1349             input_vdex_file_ = nullptr;
1350           } else {
1351             if (input_vdex_file_->HasDexSection()) {
1352               LOG(ERROR) << "The dex metadata is not allowed to contain dex files";
1353               android_errorWriteLog(0x534e4554, "178055795");  // Report to SafetyNet.
1354               return false;
1355             }
1356             VLOG(verifier) << "Doing fast verification with vdex from DexMetadata archive";
1357           }
1358         }
1359       }
1360     }
1361 
1362     // Swap file handling
1363     //
1364     // If the swap fd is not -1, we assume this is the file descriptor of an open but unlinked file
1365     // that we can use for swap.
1366     //
1367     // If the swap fd is -1 and we have a swap-file string, open the given file as a swap file. We
1368     // will immediately unlink to satisfy the swap fd assumption.
1369     if (swap_fd_ == -1 && !swap_file_name_.empty()) {
1370       std::unique_ptr<File> swap_file(OS::CreateEmptyFile(swap_file_name_.c_str()));
1371       if (swap_file.get() == nullptr) {
1372         PLOG(ERROR) << "Failed to create swap file: " << swap_file_name_;
1373         return false;
1374       }
1375       swap_fd_ = swap_file->Release();
1376       unlink(swap_file_name_.c_str());
1377     }
1378 
1379     return true;
1380   }
1381 
EraseOutputFiles()1382   void EraseOutputFiles() {
1383     for (auto& files : { &vdex_files_, &oat_files_ }) {
1384       for (size_t i = 0; i < files->size(); ++i) {
1385         if ((*files)[i].get() != nullptr) {
1386           (*files)[i]->Erase();
1387           (*files)[i].reset();
1388         }
1389       }
1390     }
1391   }
1392 
LoadClassProfileDescriptors()1393   void LoadClassProfileDescriptors() {
1394     if (!IsImage()) {
1395       return;
1396     }
1397     if (DoProfileGuidedOptimizations()) {
1398       // TODO: The following comment looks outdated or misplaced.
1399       // Filter out class path classes since we don't want to include these in the image.
1400       HashSet<std::string> image_classes = profile_compilation_info_->GetClassDescriptors(
1401           compiler_options_->dex_files_for_oat_file_);
1402       VLOG(compiler) << "Loaded " << image_classes.size()
1403                      << " image class descriptors from profile";
1404       if (VLOG_IS_ON(compiler)) {
1405         for (const std::string& s : image_classes) {
1406           LOG(INFO) << "Image class " << s;
1407         }
1408       }
1409       compiler_options_->image_classes_.swap(image_classes);
1410     }
1411   }
1412 
1413   // Set up the environment for compilation. Includes starting the runtime and loading/opening the
1414   // boot class path.
Setup()1415   dex2oat::ReturnCode Setup() {
1416     TimingLogger::ScopedTiming t("dex2oat Setup", timings_);
1417 
1418     if (!PrepareDirtyObjects()) {
1419       return dex2oat::ReturnCode::kOther;
1420     }
1421 
1422     // Verification results are null since we don't know if we will need them yet as the compiler
1423     // filter may change.
1424     callbacks_.reset(new QuickCompilerCallbacks(
1425         // For class verification purposes, boot image extension is the same as boot image.
1426         (IsBootImage() || IsBootImageExtension())
1427             ? CompilerCallbacks::CallbackMode::kCompileBootImage
1428             : CompilerCallbacks::CallbackMode::kCompileApp));
1429 
1430     RuntimeArgumentMap runtime_options;
1431     if (!PrepareRuntimeOptions(&runtime_options, callbacks_.get())) {
1432       return dex2oat::ReturnCode::kOther;
1433     }
1434 
1435     CreateOatWriters();
1436     if (!AddDexFileSources()) {
1437       return dex2oat::ReturnCode::kOther;
1438     }
1439 
1440     {
1441       TimingLogger::ScopedTiming t_dex("Writing and opening dex files", timings_);
1442       for (size_t i = 0, size = oat_writers_.size(); i != size; ++i) {
1443         // Unzip or copy dex files straight to the oat file.
1444         std::vector<MemMap> opened_dex_files_map;
1445         std::vector<std::unique_ptr<const DexFile>> opened_dex_files;
1446         // No need to verify the dex file when we have a vdex file, which means it was already
1447         // verified.
1448         const bool verify =
1449             (input_vdex_file_ == nullptr) && !compiler_options_->AssumeDexFilesAreVerified();
1450         if (!oat_writers_[i]->WriteAndOpenDexFiles(
1451             vdex_files_[i].get(),
1452             verify,
1453             update_input_vdex_,
1454             copy_dex_files_,
1455             &opened_dex_files_map,
1456             &opened_dex_files)) {
1457           return dex2oat::ReturnCode::kOther;
1458         }
1459         dex_files_per_oat_file_.push_back(MakeNonOwningPointerVector(opened_dex_files));
1460         if (opened_dex_files_map.empty()) {
1461           DCHECK(opened_dex_files.empty());
1462         } else {
1463           for (MemMap& map : opened_dex_files_map) {
1464             opened_dex_files_maps_.push_back(std::move(map));
1465           }
1466           for (std::unique_ptr<const DexFile>& dex_file : opened_dex_files) {
1467             dex_file_oat_index_map_.insert(std::make_pair(dex_file.get(), i));
1468             opened_dex_files_.push_back(std::move(dex_file));
1469           }
1470         }
1471       }
1472     }
1473 
1474     compiler_options_->dex_files_for_oat_file_ = MakeNonOwningPointerVector(opened_dex_files_);
1475     const std::vector<const DexFile*>& dex_files = compiler_options_->dex_files_for_oat_file_;
1476 
1477     if (!ValidateInputVdexChecksums()) {
1478        return dex2oat::ReturnCode::kOther;
1479     }
1480 
1481     // Check if we need to downgrade the compiler-filter for size reasons.
1482     // Note: This does not affect the compiler filter already stored in the key-value
1483     //       store which is used for determining whether the oat file is up to date,
1484     //       together with the boot class path locations and checksums stored below.
1485     CompilerFilter::Filter original_compiler_filter = compiler_options_->GetCompilerFilter();
1486     if (!IsBootImage() && !IsBootImageExtension() && IsVeryLarge(dex_files)) {
1487       // Disable app image to make sure dex2oat unloading is enabled.
1488       compiler_options_->image_type_ = CompilerOptions::ImageType::kNone;
1489 
1490       // If we need to downgrade the compiler-filter for size reasons, do that early before we read
1491       // it below for creating verification callbacks.
1492       if (!CompilerFilter::IsAsGoodAs(kLargeAppFilter, compiler_options_->GetCompilerFilter())) {
1493         LOG(INFO) << "Very large app, downgrading to verify.";
1494         compiler_options_->SetCompilerFilter(kLargeAppFilter);
1495       }
1496     }
1497 
1498     if (CompilerFilter::IsAnyCompilationEnabled(compiler_options_->GetCompilerFilter()) ||
1499         IsImage()) {
1500       // Only modes with compilation or image generation require verification results.
1501       // Do this here instead of when we
1502       // create the compilation callbacks since the compilation mode may have been changed by the
1503       // very large app logic.
1504       // Avoiding setting the verification results saves RAM by not adding the dex files later in
1505       // the function.
1506       // Note: When compiling boot image, this must be done before creating the Runtime.
1507       verification_results_.reset(new VerificationResults(compiler_options_.get()));
1508       callbacks_->SetVerificationResults(verification_results_.get());
1509     }
1510 
1511     if (IsBootImage() || IsBootImageExtension()) {
1512       // For boot image or boot image extension, pass opened dex files to the Runtime::Create().
1513       // Note: Runtime acquires ownership of these dex files.
1514       runtime_options.Set(RuntimeArgumentMap::BootClassPathDexList, &opened_dex_files_);
1515     }
1516     if (!CreateRuntime(std::move(runtime_options))) {
1517       return dex2oat::ReturnCode::kCreateRuntime;
1518     }
1519     ArrayRef<const DexFile* const> bcp_dex_files(runtime_->GetClassLinker()->GetBootClassPath());
1520     if (IsBootImage() || IsBootImageExtension()) {
1521       // Check boot class path dex files and, if compiling an extension, the images it depends on.
1522       if ((IsBootImage() && bcp_dex_files.size() != dex_files.size()) ||
1523           (IsBootImageExtension() && bcp_dex_files.size() <= dex_files.size())) {
1524         LOG(ERROR) << "Unexpected number of boot class path dex files for boot image or extension, "
1525             << bcp_dex_files.size() << (IsBootImage() ? " != " : " <= ") << dex_files.size();
1526         return dex2oat::ReturnCode::kOther;
1527       }
1528       if (!std::equal(dex_files.begin(), dex_files.end(), bcp_dex_files.end() - dex_files.size())) {
1529         LOG(ERROR) << "Boot class path dex files do not end with the compiled dex files.";
1530         return dex2oat::ReturnCode::kOther;
1531       }
1532       size_t bcp_df_pos = 0u;
1533       size_t bcp_df_end = bcp_dex_files.size();
1534       for (const std::string& bcp_location : runtime_->GetBootClassPathLocations()) {
1535         if (bcp_df_pos == bcp_df_end || bcp_dex_files[bcp_df_pos]->GetLocation() != bcp_location) {
1536           LOG(ERROR) << "Missing dex file for boot class component " << bcp_location;
1537           return dex2oat::ReturnCode::kOther;
1538         }
1539         CHECK(!DexFileLoader::IsMultiDexLocation(bcp_dex_files[bcp_df_pos]->GetLocation().c_str()));
1540         ++bcp_df_pos;
1541         while (bcp_df_pos != bcp_df_end &&
1542             DexFileLoader::IsMultiDexLocation(bcp_dex_files[bcp_df_pos]->GetLocation().c_str())) {
1543           ++bcp_df_pos;
1544         }
1545       }
1546       if (bcp_df_pos != bcp_df_end) {
1547         LOG(ERROR) << "Unexpected dex file in boot class path "
1548             << bcp_dex_files[bcp_df_pos]->GetLocation();
1549         return dex2oat::ReturnCode::kOther;
1550       }
1551       auto lacks_image = [](const DexFile* df) {
1552         if (kIsDebugBuild && df->GetOatDexFile() != nullptr) {
1553           const OatFile* oat_file = df->GetOatDexFile()->GetOatFile();
1554           CHECK(oat_file != nullptr);
1555           const auto& image_spaces = Runtime::Current()->GetHeap()->GetBootImageSpaces();
1556           CHECK(std::any_of(image_spaces.begin(),
1557                             image_spaces.end(),
1558                             [=](const ImageSpace* space) {
1559                               return oat_file == space->GetOatFile();
1560                             }));
1561         }
1562         return df->GetOatDexFile() == nullptr;
1563       };
1564       if (std::any_of(bcp_dex_files.begin(), bcp_dex_files.end() - dex_files.size(), lacks_image)) {
1565         LOG(ERROR) << "Missing required boot image(s) for boot image extension.";
1566         return dex2oat::ReturnCode::kOther;
1567       }
1568     } else {
1569       // Check that we loaded at least the primary boot image for app compilation.
1570       if (runtime_->GetHeap()->GetBootImageSpaces().empty()) {
1571         LOG(ERROR) << "Missing primary boot image for app compilation.";
1572         return dex2oat::ReturnCode::kOther;
1573       }
1574     }
1575 
1576     if (!compilation_reason_.empty()) {
1577       key_value_store_->Put(OatHeader::kCompilationReasonKey, compilation_reason_);
1578     }
1579 
1580     if (IsBootImage()) {
1581       // If we're compiling the boot image, store the boot classpath into the Key-Value store.
1582       // We use this when loading the boot image.
1583       key_value_store_->Put(OatHeader::kBootClassPathKey, android::base::Join(dex_locations_, ':'));
1584     } else if (IsBootImageExtension()) {
1585       // Validate the boot class path and record the dependency on the loaded boot images.
1586       TimingLogger::ScopedTiming t3("Loading image checksum", timings_);
1587       Runtime* runtime = Runtime::Current();
1588       std::string full_bcp = android::base::Join(runtime->GetBootClassPathLocations(), ':');
1589       std::string extension_part = ":" + android::base::Join(dex_locations_, ':');
1590       if (!android::base::EndsWith(full_bcp, extension_part)) {
1591         LOG(ERROR) << "Full boot class path does not end with extension parts, full: " << full_bcp
1592             << ", extension: " << extension_part.substr(1u);
1593         return dex2oat::ReturnCode::kOther;
1594       }
1595       std::string bcp_dependency = full_bcp.substr(0u, full_bcp.size() - extension_part.size());
1596       key_value_store_->Put(OatHeader::kBootClassPathKey, bcp_dependency);
1597       ArrayRef<const DexFile* const> bcp_dex_files_dependency =
1598           bcp_dex_files.SubArray(/*pos=*/ 0u, bcp_dex_files.size() - dex_files.size());
1599       ArrayRef<ImageSpace* const> image_spaces(runtime->GetHeap()->GetBootImageSpaces());
1600       key_value_store_->Put(
1601           OatHeader::kBootClassPathChecksumsKey,
1602           gc::space::ImageSpace::GetBootClassPathChecksums(image_spaces, bcp_dex_files_dependency));
1603     } else {
1604       if (CompilerFilter::DependsOnImageChecksum(original_compiler_filter)) {
1605         TimingLogger::ScopedTiming t3("Loading image checksum", timings_);
1606         Runtime* runtime = Runtime::Current();
1607         key_value_store_->Put(OatHeader::kBootClassPathKey,
1608                               android::base::Join(runtime->GetBootClassPathLocations(), ':'));
1609         ArrayRef<ImageSpace* const> image_spaces(runtime->GetHeap()->GetBootImageSpaces());
1610         key_value_store_->Put(
1611             OatHeader::kBootClassPathChecksumsKey,
1612             gc::space::ImageSpace::GetBootClassPathChecksums(image_spaces, bcp_dex_files));
1613 
1614         std::string versions = apex_versions_argument_.empty()
1615             ? runtime->GetApexVersions()
1616             : apex_versions_argument_;
1617         key_value_store_->Put(OatHeader::kApexVersionsKey, versions);
1618       }
1619 
1620       // Open dex files for class path.
1621 
1622       if (class_loader_context_ == nullptr) {
1623         // If no context was specified use the default one (which is an empty PathClassLoader).
1624         class_loader_context_ = ClassLoaderContext::Default();
1625       }
1626 
1627       DCHECK_EQ(oat_writers_.size(), 1u);
1628 
1629       // Note: Ideally we would reject context where the source dex files are also
1630       // specified in the classpath (as it doesn't make sense). However this is currently
1631       // needed for non-prebuild tests and benchmarks which expects on the fly compilation.
1632       // Also, for secondary dex files we do not have control on the actual classpath.
1633       // Instead of aborting, remove all the source location from the context classpaths.
1634       if (class_loader_context_->RemoveLocationsFromClassPaths(
1635             oat_writers_[0]->GetSourceLocations())) {
1636         LOG(WARNING) << "The source files to be compiled are also in the classpath.";
1637       }
1638 
1639       // We need to open the dex files before encoding the context in the oat file.
1640       // (because the encoding adds the dex checksum...)
1641       // TODO(calin): consider redesigning this so we don't have to open the dex files before
1642       // creating the actual class loader.
1643       if (!class_loader_context_->OpenDexFiles(classpath_dir_,
1644                                                class_loader_context_fds_)) {
1645         // Do not abort if we couldn't open files from the classpath. They might be
1646         // apks without dex files and right now are opening flow will fail them.
1647         LOG(WARNING) << "Failed to open classpath dex files";
1648       }
1649 
1650       // Store the class loader context in the oat header.
1651       // TODO: deprecate this since store_class_loader_context should be enough to cover the users
1652       // of classpath_dir as well.
1653       std::string class_path_key =
1654           class_loader_context_->EncodeContextForOatFile(classpath_dir_,
1655                                                          stored_class_loader_context_.get());
1656       key_value_store_->Put(OatHeader::kClassPathKey, class_path_key);
1657 
1658       // Prepare exclusion list for updatable boot class path packages.
1659       if (!PrepareUpdatableBcpPackages()) {
1660         return dex2oat::ReturnCode::kOther;
1661       }
1662     }
1663 
1664     // Now that we have finalized key_value_store_, start writing the .rodata section.
1665     // Among other things, this creates type lookup tables that speed up the compilation.
1666     {
1667       TimingLogger::ScopedTiming t_dex("Starting .rodata", timings_);
1668       rodata_.reserve(oat_writers_.size());
1669       for (size_t i = 0, size = oat_writers_.size(); i != size; ++i) {
1670         rodata_.push_back(elf_writers_[i]->StartRoData());
1671         if (!oat_writers_[i]->StartRoData(dex_files_per_oat_file_[i],
1672                                           rodata_.back(),
1673                                           (i == 0u) ? key_value_store_.get() : nullptr)) {
1674           return dex2oat::ReturnCode::kOther;
1675         }
1676       }
1677     }
1678 
1679     // We had to postpone the swap decision till now, as this is the point when we actually
1680     // know about the dex files we're going to use.
1681 
1682     // Make sure that we didn't create the driver, yet.
1683     CHECK(driver_ == nullptr);
1684     // If we use a swap file, ensure we are above the threshold to make it necessary.
1685     if (swap_fd_ != -1) {
1686       if (!UseSwap(IsBootImage() || IsBootImageExtension(), dex_files)) {
1687         close(swap_fd_);
1688         swap_fd_ = -1;
1689         VLOG(compiler) << "Decided to run without swap.";
1690       } else {
1691         LOG(INFO) << "Large app, accepted running with swap.";
1692       }
1693     }
1694     // Note that dex2oat won't close the swap_fd_. The compiler driver's swap space will do that.
1695 
1696     // If we're doing the image, override the compiler filter to force full compilation. Must be
1697     // done ahead of WellKnownClasses::Init that causes verification.  Note: doesn't force
1698     // compilation of class initializers.
1699     // Whilst we're in native take the opportunity to initialize well known classes.
1700     Thread* self = Thread::Current();
1701     WellKnownClasses::Init(self->GetJniEnv());
1702 
1703     if (!IsBootImage() && !IsBootImageExtension()) {
1704       constexpr bool kSaveDexInput = false;
1705       if (kSaveDexInput) {
1706         SaveDexInput();
1707       }
1708     }
1709 
1710     // Ensure opened dex files are writable for dex-to-dex transformations.
1711     for (MemMap& map : opened_dex_files_maps_) {
1712       if (!map.Protect(PROT_READ | PROT_WRITE)) {
1713         PLOG(ERROR) << "Failed to make .dex files writeable.";
1714         return dex2oat::ReturnCode::kOther;
1715       }
1716     }
1717 
1718     // Verification results are only required for modes that have any compilation. Avoid
1719     // adding the dex files if possible to prevent allocating large arrays.
1720     if (verification_results_ != nullptr) {
1721       for (const auto& dex_file : dex_files) {
1722         // Pre-register dex files so that we can access verification results without locks during
1723         // compilation and verification.
1724         verification_results_->AddDexFile(dex_file);
1725       }
1726     }
1727 
1728     // Setup VerifierDeps for compilation and report if we fail to parse the data.
1729     if (!DoEagerUnquickeningOfVdex() && input_vdex_file_ != nullptr) {
1730       std::unique_ptr<verifier::VerifierDeps> verifier_deps(
1731           new verifier::VerifierDeps(dex_files, /*output_only=*/ false));
1732       if (!verifier_deps->ParseStoredData(dex_files, input_vdex_file_->GetVerifierDepsData())) {
1733         return dex2oat::ReturnCode::kOther;
1734       }
1735       callbacks_->SetVerifierDeps(verifier_deps.release());
1736     } else {
1737       // Create the main VerifierDeps, here instead of in the compiler since we want to aggregate
1738       // the results for all the dex files, not just the results for the current dex file.
1739       callbacks_->SetVerifierDeps(new verifier::VerifierDeps(dex_files));
1740     }
1741 
1742     return dex2oat::ReturnCode::kNoFailure;
1743   }
1744 
1745   // Validates that the input vdex checksums match the source dex checksums.
1746   // Note that this is only effective and relevant if the input_vdex_file does not
1747   // contain a dex section (e.g. when they come from .dm files).
1748   // If the input vdex does contain dex files, the dex files will be opened from there
1749   // and so this check is redundant.
ValidateInputVdexChecksums()1750   bool ValidateInputVdexChecksums() {
1751     if (input_vdex_file_ == nullptr) {
1752       // Nothing to validate
1753       return true;
1754     }
1755     if (input_vdex_file_->GetNumberOfDexFiles()
1756           != compiler_options_->dex_files_for_oat_file_.size()) {
1757       LOG(ERROR) << "Vdex file contains a different number of dex files than the source. "
1758           << " vdex_num=" << input_vdex_file_->GetNumberOfDexFiles()
1759           << " dex_source_num=" << compiler_options_->dex_files_for_oat_file_.size();
1760       return false;
1761     }
1762 
1763     for (size_t i = 0; i < compiler_options_->dex_files_for_oat_file_.size(); i++) {
1764       uint32_t dex_source_checksum =
1765           compiler_options_->dex_files_for_oat_file_[i]->GetLocationChecksum();
1766       uint32_t vdex_checksum = input_vdex_file_->GetLocationChecksum(i);
1767       if (dex_source_checksum != vdex_checksum) {
1768         LOG(ERROR) << "Vdex file checksum different than source dex checksum for position " << i
1769           << std::hex
1770           << " vdex_checksum=0x" << vdex_checksum
1771           << " dex_source_checksum=0x" << dex_source_checksum
1772           << std::dec;
1773         return false;
1774       }
1775     }
1776     return true;
1777   }
1778 
1779   // If we need to keep the oat file open for the image writer.
ShouldKeepOatFileOpen() const1780   bool ShouldKeepOatFileOpen() const {
1781     return IsImage() && oat_fd_ != File::kInvalidFd;
1782   }
1783 
1784   // Doesn't return the class loader since it's not meant to be used for image compilation.
CompileDexFilesIndividually()1785   void CompileDexFilesIndividually() {
1786     CHECK(!IsImage()) << "Not supported with image";
1787     for (const DexFile* dex_file : compiler_options_->dex_files_for_oat_file_) {
1788       std::vector<const DexFile*> dex_files(1u, dex_file);
1789       VLOG(compiler) << "Compiling " << dex_file->GetLocation();
1790       jobject class_loader = CompileDexFiles(dex_files);
1791       CHECK(class_loader != nullptr);
1792       ScopedObjectAccess soa(Thread::Current());
1793       // Unload class loader to free RAM.
1794       jweak weak_class_loader = soa.Env()->GetVm()->AddWeakGlobalRef(
1795           soa.Self(),
1796           soa.Decode<mirror::ClassLoader>(class_loader));
1797       soa.Env()->GetVm()->DeleteGlobalRef(soa.Self(), class_loader);
1798       runtime_->GetHeap()->CollectGarbage(/* clear_soft_references */ true);
1799       ObjPtr<mirror::ClassLoader> decoded_weak = soa.Decode<mirror::ClassLoader>(weak_class_loader);
1800       if (decoded_weak != nullptr) {
1801         LOG(FATAL) << "Failed to unload class loader, path from root set: "
1802                    << runtime_->GetHeap()->GetVerification()->FirstPathFromRootSet(decoded_weak);
1803       }
1804       VLOG(compiler) << "Unloaded classloader";
1805     }
1806   }
1807 
ShouldCompileDexFilesIndividually() const1808   bool ShouldCompileDexFilesIndividually() const {
1809     // Compile individually if we are allowed to, and
1810     // 1. not building an image, and
1811     // 2. not verifying a vdex file, and
1812     // 3. using multidex, and
1813     // 4. not doing any AOT compilation.
1814     // This means extract, no-vdex verify, and quicken, will use the individual compilation
1815     // mode (to reduce RAM used by the compiler).
1816     return compile_individually_ &&
1817            (!IsImage() && !update_input_vdex_ &&
1818             compiler_options_->dex_files_for_oat_file_.size() > 1 &&
1819             !CompilerFilter::IsAotCompilationEnabled(compiler_options_->GetCompilerFilter()));
1820   }
1821 
GetCombinedChecksums() const1822   uint32_t GetCombinedChecksums() const {
1823     uint32_t combined_checksums = 0u;
1824     for (const DexFile* dex_file : compiler_options_->GetDexFilesForOatFile()) {
1825       combined_checksums ^= dex_file->GetLocationChecksum();
1826     }
1827     return combined_checksums;
1828   }
1829 
1830   // Set up and create the compiler driver and then invoke it to compile all the dex files.
Compile()1831   jobject Compile() {
1832     ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
1833 
1834     TimingLogger::ScopedTiming t("dex2oat Compile", timings_);
1835 
1836     // Find the dex files we should not inline from.
1837     std::vector<std::string> no_inline_filters;
1838     Split(no_inline_from_string_, ',', &no_inline_filters);
1839 
1840     // For now, on the host always have core-oj removed.
1841     const std::string core_oj = "core-oj";
1842     if (!kIsTargetBuild && !ContainsElement(no_inline_filters, core_oj)) {
1843       if (force_allow_oj_inlines_) {
1844         LOG(ERROR) << "Inlines allowed from core-oj! FOR TESTING USE ONLY! DO NOT DISTRIBUTE"
1845                    << " BINARIES BUILT WITH THIS OPTION!";
1846       } else {
1847         no_inline_filters.push_back(core_oj);
1848       }
1849     }
1850 
1851     if (!no_inline_filters.empty()) {
1852       std::vector<const DexFile*> class_path_files;
1853       if (!IsBootImage() && !IsBootImageExtension()) {
1854         // The class loader context is used only for apps.
1855         class_path_files = class_loader_context_->FlattenOpenedDexFiles();
1856       }
1857 
1858       const std::vector<const DexFile*>& dex_files = compiler_options_->dex_files_for_oat_file_;
1859       std::vector<const DexFile*> no_inline_from_dex_files;
1860       const std::vector<const DexFile*>* dex_file_vectors[] = {
1861           &class_linker->GetBootClassPath(),
1862           &class_path_files,
1863           &dex_files
1864       };
1865       for (const std::vector<const DexFile*>* dex_file_vector : dex_file_vectors) {
1866         for (const DexFile* dex_file : *dex_file_vector) {
1867           for (const std::string& filter : no_inline_filters) {
1868             // Use dex_file->GetLocation() rather than dex_file->GetBaseLocation(). This
1869             // allows tests to specify <test-dexfile>!classes2.dex if needed but if the
1870             // base location passes the StartsWith() test, so do all extra locations.
1871             std::string dex_location = dex_file->GetLocation();
1872             if (filter.find('/') == std::string::npos) {
1873               // The filter does not contain the path. Remove the path from dex_location as well.
1874               size_t last_slash = dex_file->GetLocation().rfind('/');
1875               if (last_slash != std::string::npos) {
1876                 dex_location = dex_location.substr(last_slash + 1);
1877               }
1878             }
1879 
1880             if (android::base::StartsWith(dex_location, filter.c_str())) {
1881               VLOG(compiler) << "Disabling inlining from " << dex_file->GetLocation();
1882               no_inline_from_dex_files.push_back(dex_file);
1883               break;
1884             }
1885           }
1886         }
1887       }
1888       if (!no_inline_from_dex_files.empty()) {
1889         compiler_options_->no_inline_from_.swap(no_inline_from_dex_files);
1890       }
1891     }
1892     compiler_options_->profile_compilation_info_ = profile_compilation_info_.get();
1893 
1894     driver_.reset(new CompilerDriver(compiler_options_.get(),
1895                                      compiler_kind_,
1896                                      thread_count_,
1897                                      swap_fd_));
1898 
1899     driver_->PrepareDexFilesForOatFile(timings_);
1900 
1901     if (!IsBootImage() && !IsBootImageExtension()) {
1902       driver_->SetClasspathDexFiles(class_loader_context_->FlattenOpenedDexFiles());
1903     }
1904 
1905     const bool compile_individually = ShouldCompileDexFilesIndividually();
1906     if (compile_individually) {
1907       // Set the compiler driver in the callbacks so that we can avoid re-verification. This not
1908       // only helps performance but also prevents reverifying quickened bytecodes. Attempting
1909       // verify quickened bytecode causes verification failures.
1910       // Only set the compiler filter if we are doing separate compilation since there is a bit
1911       // of overhead when checking if a class was previously verified.
1912       callbacks_->SetDoesClassUnloading(true, driver_.get());
1913     }
1914 
1915     // Setup vdex for compilation.
1916     const std::vector<const DexFile*>& dex_files = compiler_options_->dex_files_for_oat_file_;
1917     // To allow initialization of classes that construct ThreadLocal objects in class initializer,
1918     // re-initialize the ThreadLocal.nextHashCode to a new object that's not in the boot image.
1919     ThreadLocalHashOverride thread_local_hash_override(
1920         /*apply=*/ !IsBootImage(), /*initial_value=*/ 123456789u ^ GetCombinedChecksums());
1921 
1922     // Invoke the compilation.
1923     if (compile_individually) {
1924       CompileDexFilesIndividually();
1925       // Return a null classloader since we already freed released it.
1926       return nullptr;
1927     }
1928     return CompileDexFiles(dex_files);
1929   }
1930 
1931   // Create the class loader, use it to compile, and return.
CompileDexFiles(const std::vector<const DexFile * > & dex_files)1932   jobject CompileDexFiles(const std::vector<const DexFile*>& dex_files) {
1933     ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
1934 
1935     jobject class_loader = nullptr;
1936     if (!IsBootImage() && !IsBootImageExtension()) {
1937       class_loader =
1938           class_loader_context_->CreateClassLoader(compiler_options_->GetDexFilesForOatFile());
1939     }
1940     if (!IsBootImage()) {
1941       callbacks_->SetDexFiles(&dex_files);
1942 
1943       // We need to set this after we create the class loader so that the runtime can access
1944       // the hidden fields of the well known class loaders.
1945       if (!public_sdk_.empty()) {
1946         std::string error_msg;
1947         std::unique_ptr<SdkChecker> sdk_checker(SdkChecker::Create(public_sdk_, &error_msg));
1948         if (sdk_checker != nullptr) {
1949           AotClassLinker* aot_class_linker = down_cast<AotClassLinker*>(class_linker);
1950           aot_class_linker->SetSdkChecker(std::move(sdk_checker));
1951         } else {
1952           LOG(FATAL) << "Failed to create SdkChecker with dex files "
1953               << public_sdk_ << " Error: " << error_msg;
1954           UNREACHABLE();
1955         }
1956       }
1957     }
1958 
1959     // Register dex caches and key them to the class loader so that they only unload when the
1960     // class loader unloads.
1961     for (const auto& dex_file : dex_files) {
1962       ScopedObjectAccess soa(Thread::Current());
1963       // Registering the dex cache adds a strong root in the class loader that prevents the dex
1964       // cache from being unloaded early.
1965       ObjPtr<mirror::DexCache> dex_cache = class_linker->RegisterDexFile(
1966           *dex_file,
1967           soa.Decode<mirror::ClassLoader>(class_loader));
1968       if (dex_cache == nullptr) {
1969         soa.Self()->AssertPendingException();
1970         LOG(FATAL) << "Failed to register dex file " << dex_file->GetLocation() << " "
1971                    << soa.Self()->GetException()->Dump();
1972       }
1973     }
1974     driver_->InitializeThreadPools();
1975     driver_->PreCompile(class_loader,
1976                         dex_files,
1977                         timings_,
1978                         &compiler_options_->image_classes_,
1979                         verification_results_.get());
1980     callbacks_->SetVerificationResults(nullptr);  // Should not be needed anymore.
1981     compiler_options_->verification_results_ = verification_results_.get();
1982     driver_->CompileAll(class_loader, dex_files, timings_);
1983     driver_->FreeThreadPools();
1984     return class_loader;
1985   }
1986 
1987   // Notes on the interleaving of creating the images and oat files to
1988   // ensure the references between the two are correct.
1989   //
1990   // Currently we have a memory layout that looks something like this:
1991   //
1992   // +--------------+
1993   // | images       |
1994   // +--------------+
1995   // | oat files    |
1996   // +--------------+
1997   // | alloc spaces |
1998   // +--------------+
1999   //
2000   // There are several constraints on the loading of the images and oat files.
2001   //
2002   // 1. The images are expected to be loaded at an absolute address and
2003   // contain Objects with absolute pointers within the images.
2004   //
2005   // 2. There are absolute pointers from Methods in the images to their
2006   // code in the oat files.
2007   //
2008   // 3. There are absolute pointers from the code in the oat files to Methods
2009   // in the images.
2010   //
2011   // 4. There are absolute pointers from code in the oat files to other code
2012   // in the oat files.
2013   //
2014   // To get this all correct, we go through several steps.
2015   //
2016   // 1. We prepare offsets for all data in the oat files and calculate
2017   // the oat data size and code size. During this stage, we also set
2018   // oat code offsets in methods for use by the image writer.
2019   //
2020   // 2. We prepare offsets for the objects in the images and calculate
2021   // the image sizes.
2022   //
2023   // 3. We create the oat files. Originally this was just our own proprietary
2024   // file but now it is contained within an ELF dynamic object (aka an .so
2025   // file). Since we know the image sizes and oat data sizes and code sizes we
2026   // can prepare the ELF headers and we then know the ELF memory segment
2027   // layout and we can now resolve all references. The compiler provides
2028   // LinkerPatch information in each CompiledMethod and we resolve these,
2029   // using the layout information and image object locations provided by
2030   // image writer, as we're writing the method code.
2031   //
2032   // 4. We create the image files. They need to know where the oat files
2033   // will be loaded after itself. Originally oat files were simply
2034   // memory mapped so we could predict where their contents were based
2035   // on the file size. Now that they are ELF files, we need to inspect
2036   // the ELF files to understand the in memory segment layout including
2037   // where the oat header is located within.
2038   // TODO: We could just remember this information from step 3.
2039   //
2040   // 5. We fixup the ELF program headers so that dlopen will try to
2041   // load the .so at the desired location at runtime by offsetting the
2042   // Elf32_Phdr.p_vaddr values by the desired base address.
2043   // TODO: Do this in step 3. We already know the layout there.
2044   //
2045   // Steps 1.-3. are done by the CreateOatFile() above, steps 4.-5.
2046   // are done by the CreateImageFile() below.
2047 
2048   // Write out the generated code part. Calls the OatWriter and ElfBuilder. Also prepares the
2049   // ImageWriter, if necessary.
2050   // Note: Flushing (and closing) the file is the caller's responsibility, except for the failure
2051   //       case (when the file will be explicitly erased).
WriteOutputFiles(jobject class_loader)2052   bool WriteOutputFiles(jobject class_loader) {
2053     TimingLogger::ScopedTiming t("dex2oat Oat", timings_);
2054 
2055     // Sync the data to the file, in case we did dex2dex transformations.
2056     for (MemMap& map : opened_dex_files_maps_) {
2057       if (!map.Sync()) {
2058         PLOG(ERROR) << "Failed to Sync() dex2dex output. Map: " << map.GetName();
2059         return false;
2060       }
2061     }
2062 
2063     if (IsImage()) {
2064       if (!IsBootImage()) {
2065         DCHECK_EQ(image_base_, 0u);
2066         gc::Heap* const heap = Runtime::Current()->GetHeap();
2067         image_base_ = heap->GetBootImagesStartAddress() + heap->GetBootImagesSize();
2068       }
2069       VLOG(compiler) << "Image base=" << reinterpret_cast<void*>(image_base_);
2070 
2071       image_writer_.reset(new linker::ImageWriter(*compiler_options_,
2072                                                   image_base_,
2073                                                   image_storage_mode_,
2074                                                   oat_filenames_,
2075                                                   dex_file_oat_index_map_,
2076                                                   class_loader,
2077                                                   dirty_image_objects_.get()));
2078 
2079       // We need to prepare method offsets in the image address space for resolving linker patches.
2080       TimingLogger::ScopedTiming t2("dex2oat Prepare image address space", timings_);
2081       if (!image_writer_->PrepareImageAddressSpace(timings_)) {
2082         LOG(ERROR) << "Failed to prepare image address space.";
2083         return false;
2084       }
2085     }
2086 
2087     // Initialize the writers with the compiler driver, image writer, and their
2088     // dex files. The writers were created without those being there yet.
2089     for (size_t i = 0, size = oat_files_.size(); i != size; ++i) {
2090       std::unique_ptr<linker::OatWriter>& oat_writer = oat_writers_[i];
2091       std::vector<const DexFile*>& dex_files = dex_files_per_oat_file_[i];
2092       oat_writer->Initialize(driver_.get(), image_writer_.get(), dex_files);
2093     }
2094 
2095     {
2096       TimingLogger::ScopedTiming t2("dex2oat Write VDEX", timings_);
2097       DCHECK(IsBootImage() || IsBootImageExtension() || oat_files_.size() == 1u);
2098       verifier::VerifierDeps* verifier_deps = callbacks_->GetVerifierDeps();
2099       for (size_t i = 0, size = oat_files_.size(); i != size; ++i) {
2100         File* vdex_file = vdex_files_[i].get();
2101         if (!oat_writers_[i]->FinishVdexFile(vdex_file, verifier_deps)) {
2102           LOG(ERROR) << "Failed to finish VDEX file " << vdex_file->GetPath();
2103           return false;
2104         }
2105       }
2106     }
2107 
2108     {
2109       TimingLogger::ScopedTiming t2("dex2oat Write ELF", timings_);
2110       linker::MultiOatRelativePatcher patcher(compiler_options_->GetInstructionSet(),
2111                                               compiler_options_->GetInstructionSetFeatures(),
2112                                               driver_->GetCompiledMethodStorage());
2113       for (size_t i = 0, size = oat_files_.size(); i != size; ++i) {
2114         std::unique_ptr<linker::ElfWriter>& elf_writer = elf_writers_[i];
2115         std::unique_ptr<linker::OatWriter>& oat_writer = oat_writers_[i];
2116 
2117         oat_writer->PrepareLayout(&patcher);
2118         elf_writer->PrepareDynamicSection(oat_writer->GetOatHeader().GetExecutableOffset(),
2119                                           oat_writer->GetCodeSize(),
2120                                           oat_writer->GetDataBimgRelRoSize(),
2121                                           oat_writer->GetBssSize(),
2122                                           oat_writer->GetBssMethodsOffset(),
2123                                           oat_writer->GetBssRootsOffset(),
2124                                           oat_writer->GetVdexSize());
2125         if (IsImage()) {
2126           // Update oat layout.
2127           DCHECK(image_writer_ != nullptr);
2128           DCHECK_LT(i, oat_filenames_.size());
2129           image_writer_->UpdateOatFileLayout(i,
2130                                              elf_writer->GetLoadedSize(),
2131                                              oat_writer->GetOatDataOffset(),
2132                                              oat_writer->GetOatSize());
2133         }
2134       }
2135 
2136       for (size_t i = 0, size = oat_files_.size(); i != size; ++i) {
2137         std::unique_ptr<File>& oat_file = oat_files_[i];
2138         std::unique_ptr<linker::ElfWriter>& elf_writer = elf_writers_[i];
2139         std::unique_ptr<linker::OatWriter>& oat_writer = oat_writers_[i];
2140 
2141         // We need to mirror the layout of the ELF file in the compressed debug-info.
2142         // Therefore PrepareDebugInfo() relies on the SetLoadedSectionSizes() call further above.
2143         debug::DebugInfo debug_info = oat_writer->GetDebugInfo();  // Keep the variable alive.
2144         elf_writer->PrepareDebugInfo(debug_info);  // Processes the data on background thread.
2145 
2146         OutputStream* rodata = rodata_[i];
2147         DCHECK(rodata != nullptr);
2148         if (!oat_writer->WriteRodata(rodata)) {
2149           LOG(ERROR) << "Failed to write .rodata section to the ELF file " << oat_file->GetPath();
2150           return false;
2151         }
2152         elf_writer->EndRoData(rodata);
2153         rodata = nullptr;
2154 
2155         OutputStream* text = elf_writer->StartText();
2156         if (!oat_writer->WriteCode(text)) {
2157           LOG(ERROR) << "Failed to write .text section to the ELF file " << oat_file->GetPath();
2158           return false;
2159         }
2160         elf_writer->EndText(text);
2161 
2162         if (oat_writer->GetDataBimgRelRoSize() != 0u) {
2163           OutputStream* data_bimg_rel_ro = elf_writer->StartDataBimgRelRo();
2164           if (!oat_writer->WriteDataBimgRelRo(data_bimg_rel_ro)) {
2165             LOG(ERROR) << "Failed to write .data.bimg.rel.ro section to the ELF file "
2166                 << oat_file->GetPath();
2167             return false;
2168           }
2169           elf_writer->EndDataBimgRelRo(data_bimg_rel_ro);
2170         }
2171 
2172         if (!oat_writer->WriteHeader(elf_writer->GetStream())) {
2173           LOG(ERROR) << "Failed to write oat header to the ELF file " << oat_file->GetPath();
2174           return false;
2175         }
2176 
2177         if (IsImage()) {
2178           // Update oat header information.
2179           DCHECK(image_writer_ != nullptr);
2180           DCHECK_LT(i, oat_filenames_.size());
2181           image_writer_->UpdateOatFileHeader(i, oat_writer->GetOatHeader());
2182         }
2183 
2184         elf_writer->WriteDynamicSection();
2185         elf_writer->WriteDebugInfo(oat_writer->GetDebugInfo());
2186 
2187         if (!elf_writer->End()) {
2188           LOG(ERROR) << "Failed to write ELF file " << oat_file->GetPath();
2189           return false;
2190         }
2191 
2192         if (!FlushOutputFile(&vdex_files_[i]) || !FlushOutputFile(&oat_files_[i])) {
2193           return false;
2194         }
2195 
2196         VLOG(compiler) << "Oat file written successfully: " << oat_filenames_[i];
2197 
2198         oat_writer.reset();
2199         // We may still need the ELF writer later for stripping.
2200       }
2201     }
2202 
2203     return true;
2204   }
2205 
2206   // If we are compiling an image, invoke the image creation routine. Else just skip.
HandleImage()2207   bool HandleImage() {
2208     if (IsImage()) {
2209       TimingLogger::ScopedTiming t("dex2oat ImageWriter", timings_);
2210       if (!CreateImageFile()) {
2211         return false;
2212       }
2213       VLOG(compiler) << "Images written successfully";
2214     }
2215     return true;
2216   }
2217 
2218   // Copy the full oat files to symbols directory and then strip the originals.
CopyOatFilesToSymbolsDirectoryAndStrip()2219   bool CopyOatFilesToSymbolsDirectoryAndStrip() {
2220     for (size_t i = 0; i < oat_unstripped_.size(); ++i) {
2221       // If we don't want to strip in place, copy from stripped location to unstripped location.
2222       // We need to strip after image creation because FixupElf needs to use .strtab.
2223       if (oat_unstripped_[i] != oat_filenames_[i]) {
2224         DCHECK(oat_files_[i].get() != nullptr && oat_files_[i]->IsOpened());
2225 
2226         TimingLogger::ScopedTiming t("dex2oat OatFile copy", timings_);
2227         std::unique_ptr<File>& in = oat_files_[i];
2228         int64_t in_length = in->GetLength();
2229         if (in_length < 0) {
2230           PLOG(ERROR) << "Failed to get the length of oat file: " << in->GetPath();
2231           return false;
2232         }
2233         std::unique_ptr<File> out(OS::CreateEmptyFile(oat_unstripped_[i].c_str()));
2234         if (out == nullptr) {
2235           PLOG(ERROR) << "Failed to open oat file for writing: " << oat_unstripped_[i];
2236           return false;
2237         }
2238         if (!out->Copy(in.get(), 0, in_length)) {
2239           PLOG(ERROR) << "Failed to copy oat file to file: " << out->GetPath();
2240           return false;
2241         }
2242         if (out->FlushCloseOrErase() != 0) {
2243           PLOG(ERROR) << "Failed to flush and close copied oat file: " << oat_unstripped_[i];
2244           return false;
2245         }
2246         VLOG(compiler) << "Oat file copied successfully (unstripped): " << oat_unstripped_[i];
2247 
2248         if (strip_) {
2249           TimingLogger::ScopedTiming t2("dex2oat OatFile strip", timings_);
2250           if (!elf_writers_[i]->StripDebugInfo()) {
2251             PLOG(ERROR) << "Failed strip oat file: " << in->GetPath();
2252             return false;
2253           }
2254         }
2255       }
2256     }
2257     return true;
2258   }
2259 
FlushOutputFile(std::unique_ptr<File> * file)2260   bool FlushOutputFile(std::unique_ptr<File>* file) {
2261     if (file->get() != nullptr) {
2262       if (file->get()->Flush() != 0) {
2263         PLOG(ERROR) << "Failed to flush output file: " << file->get()->GetPath();
2264         return false;
2265       }
2266     }
2267     return true;
2268   }
2269 
FlushCloseOutputFile(File * file)2270   bool FlushCloseOutputFile(File* file) {
2271     if (file != nullptr) {
2272       if (file->FlushCloseOrErase() != 0) {
2273         PLOG(ERROR) << "Failed to flush and close output file: " << file->GetPath();
2274         return false;
2275       }
2276     }
2277     return true;
2278   }
2279 
FlushOutputFiles()2280   bool FlushOutputFiles() {
2281     TimingLogger::ScopedTiming t2("dex2oat Flush Output Files", timings_);
2282     for (auto& files : { &vdex_files_, &oat_files_ }) {
2283       for (size_t i = 0; i < files->size(); ++i) {
2284         if (!FlushOutputFile(&(*files)[i])) {
2285           return false;
2286         }
2287       }
2288     }
2289     return true;
2290   }
2291 
FlushCloseOutputFiles()2292   bool FlushCloseOutputFiles() {
2293     bool result = true;
2294     for (auto& files : { &vdex_files_, &oat_files_ }) {
2295       for (size_t i = 0; i < files->size(); ++i) {
2296         result &= FlushCloseOutputFile((*files)[i].get());
2297       }
2298     }
2299     return result;
2300   }
2301 
DumpTiming()2302   void DumpTiming() {
2303     if (compiler_options_->GetDumpTimings() ||
2304         (kIsDebugBuild && timings_->GetTotalNs() > MsToNs(1000))) {
2305       LOG(INFO) << Dumpable<TimingLogger>(*timings_);
2306     }
2307   }
2308 
IsImage() const2309   bool IsImage() const {
2310     return IsAppImage() || IsBootImage() || IsBootImageExtension();
2311   }
2312 
IsAppImage() const2313   bool IsAppImage() const {
2314     return compiler_options_->IsAppImage();
2315   }
2316 
IsBootImage() const2317   bool IsBootImage() const {
2318     return compiler_options_->IsBootImage();
2319   }
2320 
IsBootImageExtension() const2321   bool IsBootImageExtension() const {
2322     return compiler_options_->IsBootImageExtension();
2323   }
2324 
IsHost() const2325   bool IsHost() const {
2326     return is_host_;
2327   }
2328 
HasProfileInput() const2329   bool HasProfileInput() const {
2330     return profile_file_fd_ != -1 || !profile_file_.empty();
2331   }
2332 
2333   // Must be called after the profile is loaded.
DoProfileGuidedOptimizations() const2334   bool DoProfileGuidedOptimizations() const {
2335     DCHECK(!HasProfileInput() || profile_load_attempted_)
2336         << "The profile has to be loaded before we can decided "
2337         << "if we do profile guided optimizations";
2338     return profile_compilation_info_ != nullptr && !profile_compilation_info_->IsEmpty();
2339   }
2340 
DoGenerateCompactDex() const2341   bool DoGenerateCompactDex() const {
2342     return compact_dex_level_ != CompactDexLevel::kCompactDexLevelNone;
2343   }
2344 
DoDexLayoutOptimizations() const2345   bool DoDexLayoutOptimizations() const {
2346     return DoProfileGuidedOptimizations() || DoGenerateCompactDex();
2347   }
2348 
DoOatLayoutOptimizations() const2349   bool DoOatLayoutOptimizations() const {
2350     return DoProfileGuidedOptimizations();
2351   }
2352 
MayInvalidateVdexMetadata() const2353   bool MayInvalidateVdexMetadata() const {
2354     // DexLayout can invalidate the vdex metadata if changing the class def order is enabled, so
2355     // we need to unquicken the vdex file eagerly, before passing it to dexlayout.
2356     return DoDexLayoutOptimizations();
2357   }
2358 
DoEagerUnquickeningOfVdex() const2359   bool DoEagerUnquickeningOfVdex() const {
2360     return MayInvalidateVdexMetadata() && dm_file_ == nullptr;
2361   }
2362 
LoadProfile()2363   bool LoadProfile() {
2364     DCHECK(HasProfileInput());
2365     profile_load_attempted_ = true;
2366     // TODO(calin): We should be using the runtime arena pool (instead of the
2367     // default profile arena). However the setup logic is messy and needs
2368     // cleaning up before that (e.g. the oat writers are created before the
2369     // runtime).
2370     bool for_boot_image = IsBootImage() || IsBootImageExtension();
2371     profile_compilation_info_.reset(new ProfileCompilationInfo(for_boot_image));
2372     // Dex2oat only uses the reference profile and that is not updated concurrently by the app or
2373     // other processes. So we don't need to lock (as we have to do in profman or when writing the
2374     // profile info).
2375     std::unique_ptr<File> profile_file;
2376     if (profile_file_fd_ != -1) {
2377       profile_file.reset(new File(DupCloexec(profile_file_fd_),
2378                                   "profile",
2379                                   /* check_usage= */ false,
2380                                   /* read_only_mode= */ true));
2381     } else if (profile_file_ != "") {
2382       profile_file.reset(OS::OpenFileForReading(profile_file_.c_str()));
2383     }
2384 
2385     if (profile_file.get() == nullptr) {
2386       PLOG(ERROR) << "Cannot lock profiles";
2387       return false;
2388     }
2389 
2390     if (!profile_compilation_info_->Load(profile_file->Fd())) {
2391       profile_compilation_info_.reset(nullptr);
2392       return false;
2393     }
2394 
2395     return true;
2396   }
2397 
2398   // If we're asked to speed-profile the app but we have no profile, or the profile
2399   // is empty, change the filter to verify, and the image_type to none.
2400   // A speed-profile compilation without profile data is equivalent to verify and
2401   // this change will increase the precision of the telemetry data.
UpdateCompilerOptionsBasedOnProfile()2402   void UpdateCompilerOptionsBasedOnProfile() {
2403     if (!DoProfileGuidedOptimizations() &&
2404         compiler_options_->GetCompilerFilter() == CompilerFilter::kSpeedProfile) {
2405       VLOG(compiler) << "Changing compiler filter to verify from speed-profile "
2406           << "because of empty or non existing profile";
2407 
2408       compiler_options_->SetCompilerFilter(CompilerFilter::kVerify);
2409 
2410       // Note that we could reset the image_type to CompilerOptions::ImageType::kNone
2411       // to prevent an app image generation.
2412       // However, if we were pass an image file we would essentially leave the image
2413       // file empty (possibly triggering some harmless errors when we try to load it).
2414       //
2415       // Letting the image_type_ be determined by whether or not we passed an image
2416       // file will at least write the appropriate header making it an empty but valid
2417       // image.
2418     }
2419   }
2420 
2421   class ScopedDex2oatReporting {
2422    public:
ScopedDex2oatReporting(const Dex2Oat & dex2oat)2423     explicit ScopedDex2oatReporting(const Dex2Oat& dex2oat) {
2424       bool should_report = false;
2425       PaletteShouldReportDex2oatCompilation(&should_report);
2426       if (should_report) {
2427         if (dex2oat.zip_fd_ != -1) {
2428           zip_dup_fd_.reset(DupCloexecOrError(dex2oat.zip_fd_));
2429           if (zip_dup_fd_ < 0) {
2430             return;
2431           }
2432         }
2433         int image_fd = dex2oat.IsAppImage() ? dex2oat.app_image_fd_ : dex2oat.image_fd_;
2434         if (image_fd != -1) {
2435           image_dup_fd_.reset(DupCloexecOrError(image_fd));
2436           if (image_dup_fd_ < 0) {
2437             return;
2438           }
2439         }
2440         oat_dup_fd_.reset(DupCloexecOrError(dex2oat.oat_fd_));
2441         if (oat_dup_fd_ < 0) {
2442           return;
2443         }
2444         vdex_dup_fd_.reset(DupCloexecOrError(dex2oat.output_vdex_fd_));
2445         if (vdex_dup_fd_ < 0) {
2446           return;
2447         }
2448         PaletteNotifyStartDex2oatCompilation(zip_dup_fd_,
2449                                              image_dup_fd_,
2450                                              oat_dup_fd_,
2451                                              vdex_dup_fd_);
2452       }
2453       error_reporting_ = false;
2454     }
2455 
~ScopedDex2oatReporting()2456     ~ScopedDex2oatReporting() {
2457       if (!error_reporting_) {
2458         bool should_report = false;
2459         PaletteShouldReportDex2oatCompilation(&should_report);
2460         if (should_report) {
2461           PaletteNotifyEndDex2oatCompilation(zip_dup_fd_,
2462                                              image_dup_fd_,
2463                                              oat_dup_fd_,
2464                                              vdex_dup_fd_);
2465         }
2466       }
2467     }
2468 
ErrorReporting() const2469     bool ErrorReporting() const { return error_reporting_; }
2470 
2471    private:
DupCloexecOrError(int fd)2472     int DupCloexecOrError(int fd) {
2473       int dup_fd = DupCloexec(fd);
2474       if (dup_fd < 0) {
2475         LOG(ERROR) << "Error dup'ing a file descriptor " << strerror(errno);
2476         error_reporting_ = true;
2477       }
2478       return dup_fd;
2479     }
2480     android::base::unique_fd oat_dup_fd_;
2481     android::base::unique_fd vdex_dup_fd_;
2482     android::base::unique_fd zip_dup_fd_;
2483     android::base::unique_fd image_dup_fd_;
2484     bool error_reporting_ = false;
2485   };
2486 
2487  private:
UseSwap(bool is_image,const std::vector<const DexFile * > & dex_files)2488   bool UseSwap(bool is_image, const std::vector<const DexFile*>& dex_files) {
2489     if (is_image) {
2490       // Don't use swap, we know generation should succeed, and we don't want to slow it down.
2491       return false;
2492     }
2493     if (dex_files.size() < min_dex_files_for_swap_) {
2494       // If there are less dex files than the threshold, assume it's gonna be fine.
2495       return false;
2496     }
2497     size_t dex_files_size = 0;
2498     for (const auto* dex_file : dex_files) {
2499       dex_files_size += dex_file->GetHeader().file_size_;
2500     }
2501     return dex_files_size >= min_dex_file_cumulative_size_for_swap_;
2502   }
2503 
IsVeryLarge(const std::vector<const DexFile * > & dex_files)2504   bool IsVeryLarge(const std::vector<const DexFile*>& dex_files) {
2505     size_t dex_files_size = 0;
2506     for (const auto* dex_file : dex_files) {
2507       dex_files_size += dex_file->GetHeader().file_size_;
2508     }
2509     return dex_files_size >= very_large_threshold_;
2510   }
2511 
PrepareDirtyObjects()2512   bool PrepareDirtyObjects() {
2513     if (dirty_image_objects_filename_ != nullptr) {
2514       dirty_image_objects_ = ReadCommentedInputFromFile<HashSet<std::string>>(
2515           dirty_image_objects_filename_,
2516           nullptr);
2517       if (dirty_image_objects_ == nullptr) {
2518         LOG(ERROR) << "Failed to create list of dirty objects from '"
2519             << dirty_image_objects_filename_ << "'";
2520         return false;
2521       }
2522     } else {
2523       dirty_image_objects_.reset(nullptr);
2524     }
2525     return true;
2526   }
2527 
PrepareUpdatableBcpPackages()2528   bool PrepareUpdatableBcpPackages() {
2529     DCHECK(!IsBootImage() && !IsBootImageExtension());
2530     AotClassLinker* aot_class_linker = down_cast<AotClassLinker*>(runtime_->GetClassLinker());
2531     if (updatable_bcp_packages_filename_ != nullptr) {
2532       std::unique_ptr<std::vector<std::string>> updatable_bcp_packages =
2533           ReadCommentedInputFromFile<std::vector<std::string>>(updatable_bcp_packages_filename_,
2534                                                                nullptr);  // No post-processing.
2535       if (updatable_bcp_packages == nullptr) {
2536         LOG(ERROR) << "Failed to load updatable boot class path packages from '"
2537             << updatable_bcp_packages_filename_ << "'";
2538         return false;
2539       }
2540       return aot_class_linker->SetUpdatableBootClassPackages(*updatable_bcp_packages);
2541     } else {
2542       // Use the default list based on updatable packages for Android 11.
2543       return aot_class_linker->SetUpdatableBootClassPackages({
2544           // Reserved conscrypt packages (includes sub-packages under these paths).
2545           // "android.net.ssl",  // Covered by android.net below.
2546           "com.android.org.conscrypt",
2547           // Reserved updatable-media package (includes sub-packages under this path).
2548           "android.media",
2549           // Reserved framework-mediaprovider package (includes sub-packages under this path).
2550           "android.provider",
2551           // Reserved framework-statsd packages (includes sub-packages under these paths).
2552           "android.app",
2553           "android.os",
2554           "android.util",
2555           "com.android.internal.statsd",
2556           // Reserved framework-permission packages (includes sub-packages under this path).
2557           "android.permission",
2558           // "android.app.role",  // Covered by android.app above.
2559           // Reserved framework-sdkextensions package (includes sub-packages under this path).
2560           // "android.os.ext",  // Covered by android.os above.
2561           // Reserved framework-wifi packages (includes sub-packages under these paths).
2562           "android.hardware.wifi",
2563           // "android.net.wifi",  // Covered by android.net below.
2564           "com.android.wifi.x",
2565           // Reserved framework-tethering package (includes sub-packages under this path).
2566           "android.net",
2567       });
2568     }
2569   }
2570 
PruneNonExistentDexFiles()2571   void PruneNonExistentDexFiles() {
2572     DCHECK_EQ(dex_filenames_.size(), dex_locations_.size());
2573     size_t kept = 0u;
2574     for (size_t i = 0, size = dex_filenames_.size(); i != size; ++i) {
2575       if (!OS::FileExists(dex_filenames_[i].c_str())) {
2576         LOG(WARNING) << "Skipping non-existent dex file '" << dex_filenames_[i] << "'";
2577       } else {
2578         if (kept != i) {
2579           dex_filenames_[kept] = dex_filenames_[i];
2580           dex_locations_[kept] = dex_locations_[i];
2581         }
2582         ++kept;
2583       }
2584     }
2585     dex_filenames_.resize(kept);
2586     dex_locations_.resize(kept);
2587   }
2588 
AddDexFileSources()2589   bool AddDexFileSources() {
2590     TimingLogger::ScopedTiming t2("AddDexFileSources", timings_);
2591     if (input_vdex_file_ != nullptr && input_vdex_file_->HasDexSection()) {
2592       DCHECK_EQ(oat_writers_.size(), 1u);
2593       const std::string& name = zip_location_.empty() ? dex_locations_[0] : zip_location_;
2594       DCHECK(!name.empty());
2595       if (!oat_writers_[0]->AddVdexDexFilesSource(*input_vdex_file_.get(), name.c_str())) {
2596         return false;
2597       }
2598     } else if (zip_fd_ != -1) {
2599       DCHECK_EQ(oat_writers_.size(), 1u);
2600       if (!oat_writers_[0]->AddDexFileSource(File(zip_fd_, /* check_usage */ false),
2601                                              zip_location_.c_str())) {
2602         return false;
2603       }
2604     } else if (oat_writers_.size() > 1u) {
2605       // Multi-image.
2606       DCHECK_EQ(oat_writers_.size(), dex_filenames_.size());
2607       DCHECK_EQ(oat_writers_.size(), dex_locations_.size());
2608       for (size_t i = 0, size = oat_writers_.size(); i != size; ++i) {
2609         if (!oat_writers_[i]->AddDexFileSource(dex_filenames_[i].c_str(),
2610                                                dex_locations_[i].c_str())) {
2611           return false;
2612         }
2613       }
2614     } else {
2615       DCHECK_EQ(oat_writers_.size(), 1u);
2616       DCHECK_EQ(dex_filenames_.size(), dex_locations_.size());
2617       for (size_t i = 0; i != dex_filenames_.size(); ++i) {
2618         if (!oat_writers_[0]->AddDexFileSource(dex_filenames_[i].c_str(),
2619                                                dex_locations_[i].c_str())) {
2620           return false;
2621         }
2622       }
2623     }
2624     return true;
2625   }
2626 
CreateOatWriters()2627   void CreateOatWriters() {
2628     TimingLogger::ScopedTiming t2("CreateOatWriters", timings_);
2629     elf_writers_.reserve(oat_files_.size());
2630     oat_writers_.reserve(oat_files_.size());
2631     for (const std::unique_ptr<File>& oat_file : oat_files_) {
2632       elf_writers_.emplace_back(linker::CreateElfWriterQuick(*compiler_options_, oat_file.get()));
2633       elf_writers_.back()->Start();
2634       bool do_oat_writer_layout = DoDexLayoutOptimizations() || DoOatLayoutOptimizations();
2635       oat_writers_.emplace_back(new linker::OatWriter(
2636           *compiler_options_,
2637           timings_,
2638           do_oat_writer_layout ? profile_compilation_info_.get() : nullptr,
2639           compact_dex_level_));
2640     }
2641   }
2642 
SaveDexInput()2643   void SaveDexInput() {
2644     const std::vector<const DexFile*>& dex_files = compiler_options_->dex_files_for_oat_file_;
2645     for (size_t i = 0, size = dex_files.size(); i != size; ++i) {
2646       const DexFile* dex_file = dex_files[i];
2647       std::string tmp_file_name(StringPrintf("/data/local/tmp/dex2oat.%d.%zd.dex",
2648                                              getpid(), i));
2649       std::unique_ptr<File> tmp_file(OS::CreateEmptyFile(tmp_file_name.c_str()));
2650       if (tmp_file.get() == nullptr) {
2651         PLOG(ERROR) << "Failed to open file " << tmp_file_name
2652             << ". Try: adb shell chmod 777 /data/local/tmp";
2653         continue;
2654       }
2655       // This is just dumping files for debugging. Ignore errors, and leave remnants.
2656       UNUSED(tmp_file->WriteFully(dex_file->Begin(), dex_file->Size()));
2657       UNUSED(tmp_file->Flush());
2658       UNUSED(tmp_file->Close());
2659       LOG(INFO) << "Wrote input to " << tmp_file_name;
2660     }
2661   }
2662 
PrepareRuntimeOptions(RuntimeArgumentMap * runtime_options,QuickCompilerCallbacks * callbacks)2663   bool PrepareRuntimeOptions(RuntimeArgumentMap* runtime_options,
2664                              QuickCompilerCallbacks* callbacks) {
2665     RuntimeOptions raw_options;
2666     if (IsBootImage()) {
2667       std::string boot_class_path = "-Xbootclasspath:";
2668       boot_class_path += android::base::Join(dex_filenames_, ':');
2669       raw_options.push_back(std::make_pair(boot_class_path, nullptr));
2670       std::string boot_class_path_locations = "-Xbootclasspath-locations:";
2671       boot_class_path_locations += android::base::Join(dex_locations_, ':');
2672       raw_options.push_back(std::make_pair(boot_class_path_locations, nullptr));
2673     } else {
2674       std::string boot_image_option = "-Ximage:";
2675       boot_image_option += boot_image_filename_;
2676       raw_options.push_back(std::make_pair(boot_image_option, nullptr));
2677     }
2678     for (size_t i = 0; i < runtime_args_.size(); i++) {
2679       raw_options.push_back(std::make_pair(runtime_args_[i], nullptr));
2680     }
2681 
2682     raw_options.push_back(std::make_pair("compilercallbacks", callbacks));
2683     raw_options.push_back(
2684         std::make_pair("imageinstructionset",
2685                        GetInstructionSetString(compiler_options_->GetInstructionSet())));
2686 
2687     // Never allow implicit image compilation.
2688     raw_options.push_back(std::make_pair("-Xnoimage-dex2oat", nullptr));
2689     // Disable libsigchain. We don't don't need it during compilation and it prevents us
2690     // from getting a statically linked version of dex2oat (because of dlsym and RTLD_NEXT).
2691     raw_options.push_back(std::make_pair("-Xno-sig-chain", nullptr));
2692     // Disable Hspace compaction to save heap size virtual space.
2693     // Only need disable Hspace for OOM becasue background collector is equal to
2694     // foreground collector by default for dex2oat.
2695     raw_options.push_back(std::make_pair("-XX:DisableHSpaceCompactForOOM", nullptr));
2696 
2697     if (!Runtime::ParseOptions(raw_options, false, runtime_options)) {
2698       LOG(ERROR) << "Failed to parse runtime options";
2699       return false;
2700     }
2701     return true;
2702   }
2703 
2704   // Create a runtime necessary for compilation.
CreateRuntime(RuntimeArgumentMap && runtime_options)2705   bool CreateRuntime(RuntimeArgumentMap&& runtime_options) {
2706     // To make identity hashcode deterministic, set a seed based on the dex file checksums.
2707     // That makes the seed also most likely different for different inputs, for example
2708     // for primary boot image and different extensions that could be loaded together.
2709     mirror::Object::SetHashCodeSeed(987654321u ^ GetCombinedChecksums());
2710 
2711     TimingLogger::ScopedTiming t_runtime("Create runtime", timings_);
2712     if (!Runtime::Create(std::move(runtime_options))) {
2713       LOG(ERROR) << "Failed to create runtime";
2714       return false;
2715     }
2716 
2717     // Runtime::Init will rename this thread to be "main". Prefer "dex2oat" so that "top" and
2718     // "ps -a" don't change to non-descript "main."
2719     SetThreadName(kIsDebugBuild ? "dex2oatd" : "dex2oat");
2720 
2721     runtime_.reset(Runtime::Current());
2722     runtime_->SetInstructionSet(compiler_options_->GetInstructionSet());
2723     for (uint32_t i = 0; i < static_cast<uint32_t>(CalleeSaveType::kLastCalleeSaveType); ++i) {
2724       CalleeSaveType type = CalleeSaveType(i);
2725       if (!runtime_->HasCalleeSaveMethod(type)) {
2726         runtime_->SetCalleeSaveMethod(runtime_->CreateCalleeSaveMethod(), type);
2727       }
2728     }
2729 
2730     // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
2731     // set up.
2732     interpreter::UnstartedRuntime::Initialize();
2733 
2734     Thread* self = Thread::Current();
2735     runtime_->RunRootClinits(self);
2736 
2737     // Runtime::Create acquired the mutator_lock_ that is normally given away when we
2738     // Runtime::Start, give it away now so that we don't starve GC.
2739     self->TransitionFromRunnableToSuspended(kNative);
2740 
2741     WatchDog::SetRuntime(runtime_.get());
2742 
2743     return true;
2744   }
2745 
2746   // Let the ImageWriter write the image files. If we do not compile PIC, also fix up the oat files.
CreateImageFile()2747   bool CreateImageFile()
2748       REQUIRES(!Locks::mutator_lock_) {
2749     CHECK(image_writer_ != nullptr);
2750     if (IsAppImage()) {
2751       DCHECK(image_filenames_.empty());
2752       if (app_image_fd_ != -1) {
2753         image_filenames_.push_back(StringPrintf("FileDescriptor[%d]", app_image_fd_));
2754       } else {
2755         image_filenames_.push_back(app_image_file_name_);
2756       }
2757     }
2758     if (image_fd_ != -1) {
2759       DCHECK(image_filenames_.empty());
2760       image_filenames_.push_back(StringPrintf("FileDescriptor[%d]", image_fd_));
2761     }
2762     if (!image_writer_->Write(IsAppImage() ? app_image_fd_ : image_fd_,
2763                               image_filenames_,
2764                               IsAppImage() ? 1u : dex_locations_.size())) {
2765       LOG(ERROR) << "Failure during image file creation";
2766       return false;
2767     }
2768 
2769     // We need the OatDataBegin entries.
2770     dchecked_vector<uintptr_t> oat_data_begins;
2771     for (size_t i = 0, size = oat_filenames_.size(); i != size; ++i) {
2772       oat_data_begins.push_back(image_writer_->GetOatDataBegin(i));
2773     }
2774     // Destroy ImageWriter.
2775     image_writer_.reset();
2776 
2777     return true;
2778   }
2779 
2780   // Read lines from the given file, dropping comments and empty lines. Post-process each line with
2781   // the given function.
2782   template <typename T>
ReadCommentedInputFromFile(const char * input_filename,std::function<std::string (const char *)> * process)2783   static std::unique_ptr<T> ReadCommentedInputFromFile(
2784       const char* input_filename, std::function<std::string(const char*)>* process) {
2785     std::ifstream input_file(input_filename, std::ifstream::in);
2786     if (!input_file.good()) {
2787       LOG(ERROR) << "Failed to open input file " << input_filename;
2788       return nullptr;
2789     }
2790     std::unique_ptr<T> result = ReadCommentedInputStream<T>(input_file, process);
2791     input_file.close();
2792     return result;
2793   }
2794 
2795   // Read lines from the given file from the given zip file, dropping comments and empty lines.
2796   // Post-process each line with the given function.
2797   template <typename T>
ReadCommentedInputFromZip(const char * zip_filename,const char * input_filename,std::function<std::string (const char *)> * process,std::string * error_msg)2798   static std::unique_ptr<T> ReadCommentedInputFromZip(
2799       const char* zip_filename,
2800       const char* input_filename,
2801       std::function<std::string(const char*)>* process,
2802       std::string* error_msg) {
2803     std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(zip_filename, error_msg));
2804     if (zip_archive.get() == nullptr) {
2805       return nullptr;
2806     }
2807     std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(input_filename, error_msg));
2808     if (zip_entry.get() == nullptr) {
2809       *error_msg = StringPrintf("Failed to find '%s' within '%s': %s", input_filename,
2810                                 zip_filename, error_msg->c_str());
2811       return nullptr;
2812     }
2813     MemMap input_file = zip_entry->ExtractToMemMap(zip_filename, input_filename, error_msg);
2814     if (!input_file.IsValid()) {
2815       *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", input_filename,
2816                                 zip_filename, error_msg->c_str());
2817       return nullptr;
2818     }
2819     const std::string input_string(reinterpret_cast<char*>(input_file.Begin()), input_file.Size());
2820     std::istringstream input_stream(input_string);
2821     return ReadCommentedInputStream<T>(input_stream, process);
2822   }
2823 
2824   // Read lines from the given stream, dropping comments and empty lines. Post-process each line
2825   // with the given function.
2826   template <typename T>
ReadCommentedInputStream(std::istream & in_stream,std::function<std::string (const char *)> * process)2827   static std::unique_ptr<T> ReadCommentedInputStream(
2828       std::istream& in_stream,
2829       std::function<std::string(const char*)>* process) {
2830     std::unique_ptr<T> output(new T());
2831     while (in_stream.good()) {
2832       std::string dot;
2833       std::getline(in_stream, dot);
2834       if (android::base::StartsWith(dot, "#") || dot.empty()) {
2835         continue;
2836       }
2837       if (process != nullptr) {
2838         std::string descriptor((*process)(dot.c_str()));
2839         output->insert(output->end(), descriptor);
2840       } else {
2841         output->insert(output->end(), dot);
2842       }
2843     }
2844     return output;
2845   }
2846 
LogCompletionTime()2847   void LogCompletionTime() {
2848     // Note: when creation of a runtime fails, e.g., when trying to compile an app but when there
2849     //       is no image, there won't be a Runtime::Current().
2850     // Note: driver creation can fail when loading an invalid dex file.
2851     LOG(INFO) << "dex2oat took "
2852               << PrettyDuration(NanoTime() - start_ns_)
2853               << " (" << PrettyDuration(ProcessCpuNanoTime() - start_cputime_ns_) << " cpu)"
2854               << " (threads: " << thread_count_ << ") "
2855               << ((Runtime::Current() != nullptr && driver_ != nullptr) ?
2856                   driver_->GetMemoryUsageString(kIsDebugBuild || VLOG_IS_ON(compiler)) :
2857                   "");
2858   }
2859 
StripIsaFrom(const char * image_filename,InstructionSet isa)2860   std::string StripIsaFrom(const char* image_filename, InstructionSet isa) {
2861     std::string res(image_filename);
2862     size_t last_slash = res.rfind('/');
2863     if (last_slash == std::string::npos || last_slash == 0) {
2864       return res;
2865     }
2866     size_t penultimate_slash = res.rfind('/', last_slash - 1);
2867     if (penultimate_slash == std::string::npos) {
2868       return res;
2869     }
2870     // Check that the string in-between is the expected one.
2871     if (res.substr(penultimate_slash + 1, last_slash - penultimate_slash - 1) !=
2872             GetInstructionSetString(isa)) {
2873       LOG(WARNING) << "Unexpected string when trying to strip isa: " << res;
2874       return res;
2875     }
2876     return res.substr(0, penultimate_slash) + res.substr(last_slash);
2877   }
2878 
2879   std::unique_ptr<CompilerOptions> compiler_options_;
2880   Compiler::Kind compiler_kind_;
2881 
2882   std::unique_ptr<OatKeyValueStore> key_value_store_;
2883 
2884   std::unique_ptr<VerificationResults> verification_results_;
2885 
2886   std::unique_ptr<QuickCompilerCallbacks> callbacks_;
2887 
2888   std::unique_ptr<Runtime> runtime_;
2889 
2890   // The spec describing how the class loader should be setup for compilation.
2891   std::unique_ptr<ClassLoaderContext> class_loader_context_;
2892 
2893   // Optional list of file descriptors corresponding to dex file locations in
2894   // flattened `class_loader_context_`.
2895   std::vector<int> class_loader_context_fds_;
2896 
2897   // The class loader context stored in the oat file. May be equal to class_loader_context_.
2898   std::unique_ptr<ClassLoaderContext> stored_class_loader_context_;
2899 
2900   size_t thread_count_;
2901   std::vector<int32_t> cpu_set_;
2902   uint64_t start_ns_;
2903   uint64_t start_cputime_ns_;
2904   std::unique_ptr<WatchDog> watchdog_;
2905   std::vector<std::unique_ptr<File>> oat_files_;
2906   std::vector<std::unique_ptr<File>> vdex_files_;
2907   std::string oat_location_;
2908   std::vector<std::string> oat_filenames_;
2909   std::vector<std::string> oat_unstripped_;
2910   bool strip_;
2911   int oat_fd_;
2912   int input_vdex_fd_;
2913   int output_vdex_fd_;
2914   std::string input_vdex_;
2915   std::string output_vdex_;
2916   std::unique_ptr<VdexFile> input_vdex_file_;
2917   int dm_fd_;
2918   std::string dm_file_location_;
2919   std::unique_ptr<ZipArchive> dm_file_;
2920   std::vector<std::string> dex_filenames_;
2921   std::vector<std::string> dex_locations_;
2922   int zip_fd_;
2923   std::string zip_location_;
2924   std::string boot_image_filename_;
2925   std::vector<const char*> runtime_args_;
2926   std::vector<std::string> image_filenames_;
2927   int image_fd_;
2928   bool have_multi_image_arg_;
2929   bool multi_image_;
2930   uintptr_t image_base_;
2931   ImageHeader::StorageMode image_storage_mode_;
2932   const char* passes_to_run_filename_;
2933   const char* dirty_image_objects_filename_;
2934   const char* updatable_bcp_packages_filename_;
2935   std::unique_ptr<HashSet<std::string>> dirty_image_objects_;
2936   std::unique_ptr<std::vector<std::string>> passes_to_run_;
2937   bool is_host_;
2938   std::string android_root_;
2939   std::string no_inline_from_string_;
2940   bool force_allow_oj_inlines_ = false;
2941   CompactDexLevel compact_dex_level_ = kDefaultCompactDexLevel;
2942 
2943   std::vector<std::unique_ptr<linker::ElfWriter>> elf_writers_;
2944   std::vector<std::unique_ptr<linker::OatWriter>> oat_writers_;
2945   std::vector<OutputStream*> rodata_;
2946   std::vector<std::unique_ptr<OutputStream>> vdex_out_;
2947   std::unique_ptr<linker::ImageWriter> image_writer_;
2948   std::unique_ptr<CompilerDriver> driver_;
2949 
2950   std::vector<MemMap> opened_dex_files_maps_;
2951   std::vector<std::unique_ptr<const DexFile>> opened_dex_files_;
2952 
2953   bool avoid_storing_invocation_;
2954   android::base::unique_fd invocation_file_;
2955   std::string swap_file_name_;
2956   int swap_fd_;
2957   size_t min_dex_files_for_swap_ = kDefaultMinDexFilesForSwap;
2958   size_t min_dex_file_cumulative_size_for_swap_ = kDefaultMinDexFileCumulativeSizeForSwap;
2959   size_t very_large_threshold_ = std::numeric_limits<size_t>::max();
2960   std::string app_image_file_name_;
2961   int app_image_fd_;
2962   std::string profile_file_;
2963   int profile_file_fd_;
2964   std::unique_ptr<ProfileCompilationInfo> profile_compilation_info_;
2965   TimingLogger* timings_;
2966   std::vector<std::vector<const DexFile*>> dex_files_per_oat_file_;
2967   HashMap<const DexFile*, size_t> dex_file_oat_index_map_;
2968 
2969   // Backing storage.
2970   std::forward_list<std::string> char_backing_storage_;
2971 
2972   // See CompilerOptions.force_determinism_.
2973   bool force_determinism_;
2974   // See CompilerOptions.crash_on_linkage_violation_.
2975   bool check_linkage_conditions_;
2976   // See CompilerOptions.crash_on_linkage_violation_.
2977   bool crash_on_linkage_violation_;
2978 
2979   // Directory of relative classpaths.
2980   std::string classpath_dir_;
2981 
2982   // Whether the given input vdex is also the output.
2983   bool update_input_vdex_ = false;
2984 
2985   // By default, copy the dex to the vdex file only if dex files are
2986   // compressed in APK.
2987   linker::CopyOption copy_dex_files_ = linker::CopyOption::kOnlyIfCompressed;
2988 
2989   // The reason for invoking the compiler.
2990   std::string compilation_reason_;
2991 
2992   // Whether to force individual compilation.
2993   bool compile_individually_;
2994 
2995   // The classpath that determines if a given symbol should be resolved at compile time or not.
2996   std::string public_sdk_;
2997 
2998   // The apex versions of jars in the boot classpath. Set through command line
2999   // argument.
3000   std::string apex_versions_argument_;
3001 
3002   // Whether or we attempted to load the profile (if given).
3003   bool profile_load_attempted_;
3004 
3005   DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat);
3006 };
3007 
b13564922()3008 static void b13564922() {
3009 #if defined(__linux__) && defined(__arm__)
3010   int major, minor;
3011   struct utsname uts;
3012   if (uname(&uts) != -1 &&
3013       sscanf(uts.release, "%d.%d", &major, &minor) == 2 &&
3014       ((major < 3) || ((major == 3) && (minor < 4)))) {
3015     // Kernels before 3.4 don't handle the ASLR well and we can run out of address
3016     // space (http://b/13564922). Work around the issue by inhibiting further mmap() randomization.
3017     int old_personality = personality(0xffffffff);
3018     if ((old_personality & ADDR_NO_RANDOMIZE) == 0) {
3019       int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
3020       if (new_personality == -1) {
3021         LOG(WARNING) << "personality(. | ADDR_NO_RANDOMIZE) failed.";
3022       }
3023     }
3024   }
3025 #endif
3026 }
3027 
3028 class ScopedGlobalRef {
3029  public:
ScopedGlobalRef(jobject obj)3030   explicit ScopedGlobalRef(jobject obj) : obj_(obj) {}
~ScopedGlobalRef()3031   ~ScopedGlobalRef() {
3032     if (obj_ != nullptr) {
3033       ScopedObjectAccess soa(Thread::Current());
3034       soa.Env()->GetVm()->DeleteGlobalRef(soa.Self(), obj_);
3035     }
3036   }
3037 
3038  private:
3039   jobject obj_;
3040 };
3041 
DoCompilation(Dex2Oat & dex2oat)3042 static dex2oat::ReturnCode DoCompilation(Dex2Oat& dex2oat) {
3043   dex2oat.LoadClassProfileDescriptors();
3044   jobject class_loader = dex2oat.Compile();
3045   // Keep the class loader that was used for compilation live for the rest of the compilation
3046   // process.
3047   ScopedGlobalRef global_ref(class_loader);
3048 
3049   if (!dex2oat.WriteOutputFiles(class_loader)) {
3050     dex2oat.EraseOutputFiles();
3051     return dex2oat::ReturnCode::kOther;
3052   }
3053 
3054   // Flush output files.  Keep them open as we might still modify them later (strip them).
3055   if (!dex2oat.FlushOutputFiles()) {
3056     dex2oat.EraseOutputFiles();
3057     return dex2oat::ReturnCode::kOther;
3058   }
3059 
3060   // Creates the boot.art and patches the oat files.
3061   if (!dex2oat.HandleImage()) {
3062     return dex2oat::ReturnCode::kOther;
3063   }
3064 
3065   // When given --host, finish early without stripping.
3066   if (dex2oat.IsHost()) {
3067     if (!dex2oat.FlushCloseOutputFiles()) {
3068       return dex2oat::ReturnCode::kOther;
3069     }
3070     dex2oat.DumpTiming();
3071     return dex2oat::ReturnCode::kNoFailure;
3072   }
3073 
3074   // Copy stripped to unstripped location, if necessary. This will implicitly flush & close the
3075   // stripped versions. If this is given, we expect to be able to open writable files by name.
3076   if (!dex2oat.CopyOatFilesToSymbolsDirectoryAndStrip()) {
3077     return dex2oat::ReturnCode::kOther;
3078   }
3079 
3080   // FlushClose again, as stripping might have re-opened the oat files.
3081   if (!dex2oat.FlushCloseOutputFiles()) {
3082     return dex2oat::ReturnCode::kOther;
3083   }
3084 
3085   dex2oat.DumpTiming();
3086   return dex2oat::ReturnCode::kNoFailure;
3087 }
3088 
Dex2oat(int argc,char ** argv)3089 static dex2oat::ReturnCode Dex2oat(int argc, char** argv) {
3090   b13564922();
3091 
3092   TimingLogger timings("compiler", false, false);
3093 
3094   // Allocate `dex2oat` on the heap instead of on the stack, as Clang
3095   // might produce a stack frame too large for this function or for
3096   // functions inlining it (such as main), that would not fit the
3097   // requirements of the `-Wframe-larger-than` option.
3098   std::unique_ptr<Dex2Oat> dex2oat = std::make_unique<Dex2Oat>(&timings);
3099 
3100   // Parse arguments. Argument mistakes will lead to exit(EXIT_FAILURE) in UsageError.
3101   dex2oat->ParseArgs(argc, argv);
3102 
3103   art::MemMap::Init();  // For ZipEntry::ExtractToMemMap, vdex and profiles.
3104 
3105   // If needed, process profile information for profile guided compilation.
3106   // This operation involves I/O.
3107   if (dex2oat->HasProfileInput()) {
3108     if (!dex2oat->LoadProfile()) {
3109       LOG(ERROR) << "Failed to process profile file";
3110       return dex2oat::ReturnCode::kOther;
3111     }
3112   }
3113 
3114   // Check if we need to update any of the compiler options (such as the filter)
3115   // and do it before anything else (so that the other operations have a true
3116   // view of the state).
3117   dex2oat->UpdateCompilerOptionsBasedOnProfile();
3118 
3119   // Insert the compiler options in the key value store.
3120   // We have to do this after we altered any incoming arguments
3121   // (such as the compiler filter).
3122   dex2oat->InsertCompileOptions(argc, argv);
3123 
3124   // Check early that the result of compilation can be written
3125   if (!dex2oat->OpenFile()) {
3126     // Flush close so that the File Guard checks don't fail the assertions.
3127     dex2oat->FlushCloseOutputFiles();
3128     return dex2oat::ReturnCode::kOther;
3129   }
3130 
3131   // Print the complete line when any of the following is true:
3132   //   1) Debug build
3133   //   2) Compiling an image
3134   //   3) Compiling with --host
3135   //   4) Compiling on the host (not a target build)
3136   // Otherwise, print a stripped command line.
3137   if (kIsDebugBuild ||
3138       dex2oat->IsBootImage() || dex2oat->IsBootImageExtension() ||
3139       dex2oat->IsHost() ||
3140       !kIsTargetBuild) {
3141     LOG(INFO) << CommandLine();
3142   } else {
3143     LOG(INFO) << StrippedCommandLine();
3144   }
3145 
3146   Dex2Oat::ScopedDex2oatReporting sdr(*dex2oat.get());
3147 
3148   if (sdr.ErrorReporting()) {
3149     dex2oat->EraseOutputFiles();
3150     return dex2oat::ReturnCode::kOther;
3151   }
3152 
3153   dex2oat::ReturnCode setup_code = dex2oat->Setup();
3154   if (setup_code != dex2oat::ReturnCode::kNoFailure) {
3155     dex2oat->EraseOutputFiles();
3156     return setup_code;
3157   }
3158 
3159   // TODO: Due to the cyclic dependencies, profile loading and verifying are
3160   // being done separately. Refactor and place the two next to each other.
3161   // If verification fails, we don't abort the compilation and instead log an
3162   // error.
3163   // TODO(b/62602192, b/65260586): We should consider aborting compilation when
3164   // the profile verification fails.
3165   // Note: If dex2oat fails, installd will remove the oat files causing the app
3166   // to fallback to apk with possible in-memory extraction. We want to avoid
3167   // that, and thus we're lenient towards profile corruptions.
3168   if (dex2oat->DoProfileGuidedOptimizations()) {
3169     dex2oat->VerifyProfileData();
3170   }
3171 
3172   // Helps debugging on device. Can be used to determine which dalvikvm instance invoked a dex2oat
3173   // instance. Used by tools/bisection_search/bisection_search.py.
3174   VLOG(compiler) << "Running dex2oat (parent PID = " << getppid() << ")";
3175 
3176   dex2oat::ReturnCode result = DoCompilation(*dex2oat);
3177 
3178   return result;
3179 }
3180 }  // namespace art
3181 
main(int argc,char ** argv)3182 int main(int argc, char** argv) {
3183   int result = static_cast<int>(art::Dex2oat(argc, argv));
3184   // Everything was done, do an explicit exit here to avoid running Runtime destructors that take
3185   // time (bug 10645725) unless we're a debug or instrumented build or running on a memory tool.
3186   // Note: The Dex2Oat class should not destruct the runtime in this case.
3187   if (!art::kIsDebugBuild && !art::kIsPGOInstrumentation && !art::kRunningOnMemoryTool) {
3188     art::FastExit(result);
3189   }
3190   return result;
3191 }
3192