1*5ffd83dbSDimitry Andric //===-- sanitizer_procmaps_fuchsia.cpp
2*5ffd83dbSDimitry Andric //----------------------------------------===//
3*5ffd83dbSDimitry Andric //
4*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*5ffd83dbSDimitry Andric //
8*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
9*5ffd83dbSDimitry Andric //
10*5ffd83dbSDimitry Andric // Information about the process mappings (Fuchsia-specific parts).
11*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
12*5ffd83dbSDimitry Andric
13*5ffd83dbSDimitry Andric #include "sanitizer_platform.h"
14*5ffd83dbSDimitry Andric #if SANITIZER_FUCHSIA
15*5ffd83dbSDimitry Andric #include <zircon/process.h>
16*5ffd83dbSDimitry Andric #include <zircon/syscalls.h>
17*5ffd83dbSDimitry Andric
18*5ffd83dbSDimitry Andric #include "sanitizer_common.h"
19*5ffd83dbSDimitry Andric #include "sanitizer_procmaps.h"
20*5ffd83dbSDimitry Andric
21*5ffd83dbSDimitry Andric namespace __sanitizer {
22*5ffd83dbSDimitry Andric
23*5ffd83dbSDimitry Andric // The cache flag is ignored on Fuchsia because a process can always get this
24*5ffd83dbSDimitry Andric // information via its process-self handle.
MemoryMappingLayout(bool)25*5ffd83dbSDimitry Andric MemoryMappingLayout::MemoryMappingLayout(bool) { Reset(); }
26*5ffd83dbSDimitry Andric
Reset()27*5ffd83dbSDimitry Andric void MemoryMappingLayout::Reset() {
28*5ffd83dbSDimitry Andric data_.data.clear();
29*5ffd83dbSDimitry Andric data_.current = 0;
30*5ffd83dbSDimitry Andric
31*5ffd83dbSDimitry Andric size_t count;
32*5ffd83dbSDimitry Andric zx_status_t status = _zx_object_get_info(
33*5ffd83dbSDimitry Andric _zx_process_self(), ZX_INFO_PROCESS_MAPS, nullptr, 0, nullptr, &count);
34*5ffd83dbSDimitry Andric if (status != ZX_OK) {
35*5ffd83dbSDimitry Andric return;
36*5ffd83dbSDimitry Andric }
37*5ffd83dbSDimitry Andric
38*5ffd83dbSDimitry Andric size_t filled;
39*5ffd83dbSDimitry Andric do {
40*5ffd83dbSDimitry Andric data_.data.resize(count);
41*5ffd83dbSDimitry Andric status = _zx_object_get_info(
42*5ffd83dbSDimitry Andric _zx_process_self(), ZX_INFO_PROCESS_MAPS, data_.data.data(),
43*5ffd83dbSDimitry Andric count * sizeof(zx_info_maps_t), &filled, &count);
44*5ffd83dbSDimitry Andric if (status != ZX_OK) {
45*5ffd83dbSDimitry Andric data_.data.clear();
46*5ffd83dbSDimitry Andric return;
47*5ffd83dbSDimitry Andric }
48*5ffd83dbSDimitry Andric } while (filled < count);
49*5ffd83dbSDimitry Andric }
50*5ffd83dbSDimitry Andric
~MemoryMappingLayout()51*5ffd83dbSDimitry Andric MemoryMappingLayout::~MemoryMappingLayout() {}
52*5ffd83dbSDimitry Andric
Error() const53*5ffd83dbSDimitry Andric bool MemoryMappingLayout::Error() const { return data_.data.empty(); }
54*5ffd83dbSDimitry Andric
Next(MemoryMappedSegment * segment)55*5ffd83dbSDimitry Andric bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
56*5ffd83dbSDimitry Andric while (data_.current < data_.data.size()) {
57*5ffd83dbSDimitry Andric const auto &entry = data_.data[data_.current++];
58*5ffd83dbSDimitry Andric if (entry.type == ZX_INFO_MAPS_TYPE_MAPPING) {
59*5ffd83dbSDimitry Andric segment->start = entry.base;
60*5ffd83dbSDimitry Andric segment->end = entry.base + entry.size;
61*5ffd83dbSDimitry Andric segment->offset = entry.u.mapping.vmo_offset;
62*5ffd83dbSDimitry Andric const auto flags = entry.u.mapping.mmu_flags;
63*5ffd83dbSDimitry Andric segment->protection =
64*5ffd83dbSDimitry Andric ((flags & ZX_VM_PERM_READ) ? kProtectionRead : 0) |
65*5ffd83dbSDimitry Andric ((flags & ZX_VM_PERM_WRITE) ? kProtectionWrite : 0) |
66*5ffd83dbSDimitry Andric ((flags & ZX_VM_PERM_EXECUTE) ? kProtectionExecute : 0);
67*5ffd83dbSDimitry Andric if (segment->filename && segment->filename_size > 0) {
68*5ffd83dbSDimitry Andric uptr len = Min(sizeof(entry.name), segment->filename_size) - 1;
69*5ffd83dbSDimitry Andric internal_strncpy(segment->filename, entry.name, len);
70*5ffd83dbSDimitry Andric segment->filename[len] = 0;
71*5ffd83dbSDimitry Andric }
72*5ffd83dbSDimitry Andric return true;
73*5ffd83dbSDimitry Andric }
74*5ffd83dbSDimitry Andric }
75*5ffd83dbSDimitry Andric return false;
76*5ffd83dbSDimitry Andric }
77*5ffd83dbSDimitry Andric
78*5ffd83dbSDimitry Andric } // namespace __sanitizer
79*5ffd83dbSDimitry Andric
80*5ffd83dbSDimitry Andric #endif // SANITIZER_FUCHSIA
81