| // Copyright 2013 The Flutter Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "flutter/testing/elf_loader.h" | 
 |  | 
 | #include <utility> | 
 |  | 
 | #include "flutter/fml/file.h" | 
 | #include "flutter/fml/paths.h" | 
 | #include "flutter/runtime/dart_vm.h" | 
 | #include "flutter/testing/testing.h" | 
 |  | 
 | namespace flutter { | 
 | namespace testing { | 
 |  | 
 | ELFAOTSymbols LoadELFSymbolFromFixturesIfNeccessary(std::string elf_filename) { | 
 |   if (!DartVM::IsRunningPrecompiledCode()) { | 
 |     return {}; | 
 |   } | 
 |  | 
 |   const auto elf_path = | 
 |       fml::paths::JoinPaths({GetFixturesPath(), std::move(elf_filename)}); | 
 |  | 
 |   if (!fml::IsFile(elf_path)) { | 
 |     FML_LOG(ERROR) << "App AOT file does not exist for this fixture. Attempts " | 
 |                       "to launch the Dart VM with these AOT symbols will fail."; | 
 |     return {}; | 
 |   } | 
 |  | 
 |   ELFAOTSymbols symbols; | 
 |  | 
 | #if OS_FUCHSIA | 
 |   // TODO(gw280): https://github.com/flutter/flutter/issues/50285 | 
 |   // Dart doesn't implement Dart_LoadELF on Fuchsia | 
 |   FML_LOG(ERROR) << "Dart doesn't implement Dart_LoadELF on Fuchsia"; | 
 |   return {}; | 
 | #else | 
 |   // Must not be freed. | 
 |   const char* error = nullptr; | 
 |  | 
 |   auto loaded_elf = | 
 |       Dart_LoadELF(elf_path.c_str(),             // file path | 
 |                    0,                            // file offset | 
 |                    &error,                       // error (out) | 
 |                    &symbols.vm_snapshot_data,    // vm snapshot data (out) | 
 |                    &symbols.vm_snapshot_instrs,  // vm snapshot instrs (out) | 
 |                    &symbols.vm_isolate_data,     // vm isolate data (out) | 
 |                    &symbols.vm_isolate_instrs    // vm isolate instr (out) | 
 |       ); | 
 |  | 
 |   if (loaded_elf == nullptr) { | 
 |     FML_LOG(ERROR) | 
 |         << "Could not fetch AOT symbols from loaded ELF. Attempts " | 
 |            "to launch the Dart VM with these AOT symbols  will fail. Error: " | 
 |         << error; | 
 |     return {}; | 
 |   } | 
 |  | 
 |   symbols.loaded_elf.reset(loaded_elf); | 
 |  | 
 |   return symbols; | 
 | #endif  // OS_FUCHSIA | 
 | } | 
 |  | 
 | ELFAOTSymbols LoadELFSplitSymbolFromFixturesIfNeccessary( | 
 |     std::string elf_split_filename) { | 
 |   if (!DartVM::IsRunningPrecompiledCode()) { | 
 |     return {}; | 
 |   } | 
 |  | 
 |   const auto elf_path = | 
 |       fml::paths::JoinPaths({GetFixturesPath(), std::move(elf_split_filename)}); | 
 |  | 
 |   if (!fml::IsFile(elf_path)) { | 
 |     // We do not log here, as there is no expectation for a split library to | 
 |     // exist. | 
 |     return {}; | 
 |   } | 
 |  | 
 |   ELFAOTSymbols symbols; | 
 |  | 
 | #if OS_FUCHSIA | 
 |   // TODO(gw280): https://github.com/flutter/flutter/issues/50285 | 
 |   // Dart doesn't implement Dart_LoadELF on Fuchsia | 
 |   FML_LOG(ERROR) << "Dart doesn't implement Dart_LoadELF on Fuchsia"; | 
 |   return {}; | 
 | #else | 
 |   // Must not be freed. | 
 |   const char* error = nullptr; | 
 |  | 
 |   auto loaded_elf = | 
 |       Dart_LoadELF(elf_path.c_str(),             // file path | 
 |                    0,                            // file offset | 
 |                    &error,                       // error (out) | 
 |                    &symbols.vm_snapshot_data,    // vm snapshot data (out) | 
 |                    &symbols.vm_snapshot_instrs,  // vm snapshot instrs (out) | 
 |                    &symbols.vm_isolate_data,     // vm isolate data (out) | 
 |                    &symbols.vm_isolate_instrs    // vm isolate instr (out) | 
 |       ); | 
 |  | 
 |   if (loaded_elf == nullptr) { | 
 |     FML_LOG(ERROR) | 
 |         << "Could not fetch AOT symbols from loaded ELF. Attempts " | 
 |            "to launch the Dart VM with these AOT symbols  will fail. Error: " | 
 |         << error; | 
 |     return {}; | 
 |   } | 
 |  | 
 |   symbols.loaded_elf.reset(loaded_elf); | 
 |  | 
 |   return symbols; | 
 | #endif | 
 | } | 
 |  | 
 | bool PrepareSettingsForAOTWithSymbols(Settings& settings, | 
 |                                       const ELFAOTSymbols& symbols) { | 
 |   if (!DartVM::IsRunningPrecompiledCode()) { | 
 |     return false; | 
 |   } | 
 |   settings.vm_snapshot_data = [&]() { | 
 |     return std::make_unique<fml::NonOwnedMapping>(symbols.vm_snapshot_data, 0u); | 
 |   }; | 
 |   settings.isolate_snapshot_data = [&]() { | 
 |     return std::make_unique<fml::NonOwnedMapping>(symbols.vm_isolate_data, 0u); | 
 |   }; | 
 |   settings.vm_snapshot_instr = [&]() { | 
 |     return std::make_unique<fml::NonOwnedMapping>(symbols.vm_snapshot_instrs, | 
 |                                                   0u); | 
 |   }; | 
 |   settings.isolate_snapshot_instr = [&]() { | 
 |     return std::make_unique<fml::NonOwnedMapping>(symbols.vm_isolate_instrs, | 
 |                                                   0u); | 
 |   }; | 
 |   return true; | 
 | } | 
 |  | 
 | }  // namespace testing | 
 | }  // namespace flutter |