9#include <fuchsia/io/cpp/fidl.h>
10#include <fuchsia/mem/cpp/fidl.h>
11#include <lib/fdio/directory.h>
12#include <lib/fdio/io.h>
13#include <lib/trace/event.h>
17#include <zircon/dlfcn.h>
18#include <zircon/status.h>
21#include "third_party/dart/runtime/include/dart_api.h"
28static bool OpenVmo(fuchsia::mem::Buffer* resource_vmo,
30 const std::string& path,
32 TRACE_DURATION(
"dart",
"LoadFromNamespace",
"path", path);
34 if (namespc ==
nullptr) {
45 auto root_dir = fdio_ns_opendir(namespc);
47 FML_LOG(ERROR) <<
"Failed to open namespace directory";
63 const std::string& path,
66 fuchsia::mem::Buffer resource_vmo;
67 return OpenVmo(&resource_vmo, namespc, path, executable) &&
68 LoadFromVmo(path, std::move(resource_vmo), resource, executable);
72 fuchsia::mem::Buffer resource_vmo,
75 if (resource_vmo.size == 0) {
79 uint32_t flags = ZX_VM_PERM_READ;
81 flags |= ZX_VM_PERM_EXECUTE;
84 zx_status_t status = zx::vmar::root_self()->map(flags, 0, resource_vmo.vmo, 0,
85 resource_vmo.size, &addr);
86 if (status != ZX_OK) {
87 FML_LOG(ERROR) <<
"Failed to map: " << zx_status_get_string(status);
91 resource.address_ =
reinterpret_cast<void*
>(addr);
92 resource.size_ = resource_vmo.size;
97 if (address_ !=
nullptr) {
98 zx::vmar::root_self()->unmap(
reinterpret_cast<uintptr_t
>(address_), size_);
107 const char* path_ptr = path.c_str();
108 if (path_ptr && path_ptr[0] ==
'/') {
111 zx_status_t result = fdio_open3_fd_at(
113 uint64_t{fuchsia::io::PERM_READABLE | fuchsia::io::PERM_EXECUTABLE}, &fd);
114 if (result != ZX_OK) {
115 FML_LOG(ERROR) <<
"fdio_open3_fd_at(" << path <<
") "
116 <<
"failed: " << zx_status_get_string(result);
124 if (namespc ==
nullptr) {
127 root_dir = fdio_ns_opendir(namespc);
129 FML_LOG(ERROR) <<
"Failed to open namespace directory";
133 return Load(root_dir, path);
139 FML_LOG(ERROR) <<
"Failed to open VMO for " << path <<
" from dir.";
146 zx_handle_t vmo = ZX_HANDLE_INVALID;
147 zx_status_t status = fdio_get_vmo_exec(fd.
get(), &vmo);
148 if (status != ZX_OK) {
149 FML_LOG(ERROR) <<
"Failed load ELF: " << zx_status_get_string(status);
152 handle_ = dlopen_vmo(vmo, RTLD_LAZY);
153 if (handle_ ==
nullptr) {
154 const char*
error = dlerror();
160 reinterpret_cast<const uint8_t*
>(dlsym(handle_, kVmSnapshotDataCSymbol));
161 vm_instrs_ =
reinterpret_cast<const uint8_t*
>(
162 dlsym(handle_, kVmSnapshotInstructionsCSymbol));
163 isolate_data_ =
reinterpret_cast<const uint8_t*
>(
164 dlsym(handle_, kIsolateSnapshotDataCSymbol));
165 isolate_instrs_ =
reinterpret_cast<const uint8_t*
>(
166 dlsym(handle_, kIsolateSnapshotInstructionsCSymbol));
167 if (vm_data_ ==
nullptr || vm_instrs_ ==
nullptr ||
168 isolate_data_ ==
nullptr || isolate_instrs_ ==
nullptr) {
169 FML_LOG(ERROR) <<
"Failed to load ELF symbols";
bool Load(fdio_ns_t *namespc, const std::string &path)
static bool LoadFromNamespace(fdio_ns_t *namespc, const std::string &path, MappedResource &resource, bool executable=false)
static bool LoadFromVmo(const std::string &path, fuchsia::mem::Buffer resource_vmo, MappedResource &resource, bool executable=false)
const uint8_t uint32_t uint32_t GError ** error
#define FML_LOG(severity)
#define FML_CHECK(condition)
bool VmoFromFilenameAt(int dirfd, const std::string &filename, bool executable, fuchsia::mem::Buffer *buffer)
static int OpenFdExec(const std::string &path, int dirfd)
bool VmoFromFilename(const std::string &filename, bool executable, fuchsia::mem::Buffer *buffer)
static bool OpenVmo(fuchsia::mem::Buffer *resource_vmo, fdio_ns_t *namespc, const std::string &path, bool executable)