blob: 2d2f2ea8c335fb48f7ed7addb66c77e7681d1f10 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include "bootfs.h"
#include <lib/zbitl/error-stdio.h>
#include <stdarg.h>
#include <zircon/syscalls/log.h>
#include <zircon/types.h>
#include "util.h"
zx::vmo Bootfs::Open(std::string_view root, std::string_view filename, std::string_view purpose) {
printl(log_, "searching BOOTFS for '%.*s%s%.*s' (%.*s)", //
static_cast<int>(root.size()), root.data(), //
root.empty() ? "" : "/", //
static_cast<int>(filename.size()), filename.data(), //
static_cast<int>(purpose.size()), purpose.data());
auto it = root.empty() ? bootfs_.find(filename) : bootfs_.find({root, filename});
if (auto result = bootfs_.take_error(); result.is_error()) {
Fail(result.error_value());
}
if (it == bootfs_.end()) {
fail(log_, "failed to find '%.*s%s%.*s'", //
static_cast<int>(root.size()), root.data(), //
root.empty() ? "" : "/", //
static_cast<int>(filename.size()), filename.data());
}
// Clone a private, read-only snapshot of the file's subset of the bootfs VMO.
zx::vmo file_vmo;
zx_status_t status = bootfs_.storage().vmo().create_child(
ZX_VMO_CHILD_SNAPSHOT | ZX_VMO_CHILD_NO_WRITE, it->offset, it->size, &file_vmo);
check(log_, status, "zx_vmo_create_child failed");
status = file_vmo.set_property(ZX_PROP_NAME, filename.data(), filename.size());
check(log_, status, "failed to set ZX_PROP_NAME");
uint64_t size = it->size;
status = file_vmo.set_property(ZX_PROP_VMO_CONTENT_SIZE, &size, sizeof(size));
check(log_, status, "failed to set ZX_PROP_VMO_CONTENT_SIZE");
status = file_vmo.replace_as_executable(vmex_resource_, &file_vmo);
check(log_, status, "zx_vmo_replace_as_executable failed");
return file_vmo;
}
void Bootfs::Fail(const BootfsView::Error& error) {
zbitl::PrintBootfsError(error, [this](const char* fmt, ...) {
va_list args;
va_start(args, fmt);
printl(log_, fmt, args);
va_end(args);
});
zx_process_exit(-1);
}