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>
23#include "third_party/dart/runtime/include/dart_api.h"
27static bool OpenVmo(fuchsia::mem::Buffer* resource_vmo,
29 const std::string& path,
31 TRACE_DURATION(
"dart",
"LoadFromNamespace",
"path", path);
33 if (namespc ==
nullptr) {
44 auto root_dir = fdio_ns_opendir(namespc);
46 FML_LOG(ERROR) <<
"Failed to open namespace directory";
62 const std::string& path,
65 fuchsia::mem::Buffer resource_vmo;
66 return OpenVmo(&resource_vmo, namespc, path, executable) &&
67 LoadFromVmo(path, std::move(resource_vmo), resource, executable);
71 fuchsia::mem::Buffer resource_vmo,
74 if (resource_vmo.size == 0) {
78 uint32_t flags = ZX_VM_PERM_READ;
80 flags |= ZX_VM_PERM_EXECUTE;
83 zx_status_t status = zx::vmar::root_self()->map(flags, 0, resource_vmo.vmo, 0,
84 resource_vmo.size, &addr);
85 if (status != ZX_OK) {
86 FML_LOG(ERROR) <<
"Failed to map: " << zx_status_get_string(status);
90 resource.address_ =
reinterpret_cast<void*
>(addr);
91 resource.size_ = resource_vmo.size;
96 if (address_ !=
nullptr) {
97 zx::vmar::root_self()->unmap(
reinterpret_cast<uintptr_t
>(address_), size_);
106 const char* path_ptr = path.c_str();
107 if (path_ptr && path_ptr[0] ==
'/') {
110 zx_status_t result = fdio_open3_fd_at(
112 uint64_t{fuchsia::io::PERM_READABLE | fuchsia::io::PERM_EXECUTABLE}, &fd);
113 if (result != ZX_OK) {
114 FML_LOG(ERROR) <<
"fdio_open3_fd_at(" << path <<
") "
115 <<
"failed: " << zx_status_get_string(result);
123 if (namespc ==
nullptr) {
126 root_dir = fdio_ns_opendir(namespc);
128 FML_LOG(ERROR) <<
"Failed to open namespace directory";
132 return Load(root_dir, path);
138 FML_LOG(ERROR) <<
"Failed to open VMO for " << path <<
" from dir.";
145 zx_handle_t vmo = ZX_HANDLE_INVALID;
146 zx_status_t status = fdio_get_vmo_exec(fd.
get(), &vmo);
147 if (status != ZX_OK) {
148 FML_LOG(ERROR) <<
"Failed load ELF: " << zx_status_get_string(status);
151 handle_ = dlopen_vmo(vmo, RTLD_LAZY);
152 if (handle_ ==
nullptr) {
153 const char*
error = dlerror();
159 reinterpret_cast<const uint8_t*
>(dlsym(handle_, kVmSnapshotDataCSymbol));
160 vm_instrs_ =
reinterpret_cast<const uint8_t*
>(
161 dlsym(handle_, kVmSnapshotInstructionsCSymbol));
162 isolate_data_ =
reinterpret_cast<const uint8_t*
>(
163 dlsym(handle_, kIsolateSnapshotDataCSymbol));
164 isolate_instrs_ =
reinterpret_cast<const uint8_t*
>(
165 dlsym(handle_, kIsolateSnapshotInstructionsCSymbol));
166 if (vm_data_ ==
nullptr || vm_instrs_ ==
nullptr ||
167 isolate_data_ ==
nullptr || isolate_instrs_ ==
nullptr) {
168 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)