1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/testing/elf_loader.h"
6
7#include "flutter/fml/file.h"
8#include "flutter/fml/paths.h"
9#include "flutter/runtime/dart_vm.h"
10#include "flutter/testing/testing.h"
11
12namespace flutter {
13namespace testing {
14
15ELFAOTSymbols LoadELFSymbolFromFixturesIfNeccessary() {
16 if (!DartVM::IsRunningPrecompiledCode()) {
17 return {};
18 }
19
20 const auto elf_path =
21 fml::paths::JoinPaths({GetFixturesPath(), kAOTAppELFFileName});
22
23 if (!fml::IsFile(elf_path)) {
24 FML_LOG(ERROR) << "App AOT file does not exist for this fixture. Attempts "
25 "to launch the Dart VM with these AOT symbols will fail.";
26 return {};
27 }
28
29 ELFAOTSymbols symbols;
30
31 // Must not be freed.
32 const char* error = nullptr;
33
34#if OS_FUCHSIA
35 // TODO(gw280): https://github.com/flutter/flutter/issues/50285
36 // Dart doesn't implement Dart_LoadELF on Fuchsia
37 auto loaded_elf = nullptr;
38#else
39 auto loaded_elf =
40 Dart_LoadELF(elf_path.c_str(), // file path
41 0, // file offset
42 &error, // error (out)
43 &symbols.vm_snapshot_data, // vm snapshot data (out)
44 &symbols.vm_snapshot_instrs, // vm snapshot instrs (out)
45 &symbols.vm_isolate_data, // vm isolate data (out)
46 &symbols.vm_isolate_instrs // vm isolate instr (out)
47 );
48#endif
49
50 if (loaded_elf == nullptr) {
51 FML_LOG(ERROR)
52 << "Could not fetch AOT symbols from loaded ELF. Attempts "
53 "to launch the Dart VM with these AOT symbols will fail. Error: "
54 << error;
55 return {};
56 }
57
58 symbols.loaded_elf.reset(loaded_elf);
59
60 return symbols;
61}
62
63bool PrepareSettingsForAOTWithSymbols(Settings& settings,
64 const ELFAOTSymbols& symbols) {
65 if (!DartVM::IsRunningPrecompiledCode()) {
66 return false;
67 }
68 settings.vm_snapshot_data = [&]() {
69 return std::make_unique<fml::NonOwnedMapping>(symbols.vm_snapshot_data, 0u);
70 };
71 settings.isolate_snapshot_data = [&]() {
72 return std::make_unique<fml::NonOwnedMapping>(symbols.vm_isolate_data, 0u);
73 };
74 settings.vm_snapshot_instr = [&]() {
75 return std::make_unique<fml::NonOwnedMapping>(symbols.vm_snapshot_instrs,
76 0u);
77 };
78 settings.isolate_snapshot_instr = [&]() {
79 return std::make_unique<fml::NonOwnedMapping>(symbols.vm_isolate_instrs,
80 0u);
81 };
82 return true;
83}
84
85} // namespace testing
86} // namespace flutter
87