blob: d3386c05002f7e1d5f5e7b3563f54c6517606492 [file] [log] [blame] [edit]
// 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 <align.h>
#include <inttypes.h>
#include <lib/userabi/rodso.h>
#include <ktl/array.h>
#include <object/handle.h>
#include <object/vm_address_region_dispatcher.h>
#include <object/vm_object_dispatcher.h>
#include <vm/vm_address_region.h>
#include <vm/vm_aspace.h>
#include <vm/vm_object.h>
#include <ktl/enforce.h>
// Map one segment from our VM object.
zx_status_t RoDso::MapSegment(fbl::RefPtr<VmAddressRegionDispatcher> vmar, bool code,
size_t vmar_offset, size_t start_offset, size_t end_offset) const {
uint32_t flags = ZX_VM_SPECIFIC | ZX_VM_PERM_READ;
if (code)
flags |= ZX_VM_PERM_EXECUTE;
size_t len = end_offset - start_offset;
zx::result<VmAddressRegion::MapResult> mapping_result =
vmar->Map(vmar_offset, vmo_, start_offset, len, flags);
ktl::array<char, ZX_MAX_NAME_LEN> name;
vmo_->get_name(name.data(), name.size());
const char* segment_name = code ? "code" : "rodata";
if (mapping_result.is_error()) {
dprintf(CRITICAL, "userboot: %s %s mapping %#zx @ %#" PRIxPTR " size %#zx failed %d\n",
name.data(), segment_name, start_offset, vmar->vmar()->base() + vmar_offset, len,
mapping_result.status_value());
} else {
DEBUG_ASSERT(mapping_result->base == vmar->vmar()->base() + vmar_offset);
dprintf(SPEW, "userboot: %-8s %-6s %#7zx @ [%#" PRIxPTR ",%#" PRIxPTR ")\n", name.data(),
segment_name, start_offset, mapping_result->base, mapping_result->base + len);
}
return mapping_result.status_value();
}
zx_status_t RoDso::Map(fbl::RefPtr<VmAddressRegionDispatcher> vmar, size_t offset) const {
zx_status_t status = MapSegment(vmar, false, offset, 0, code_start_);
if (status == ZX_OK)
status = MapSegment(ktl::move(vmar), true, offset + code_start_, code_start_, size_);
return status;
}