| // 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 |