xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_fuchsia.cpp (revision e25152834cdf3b353892835a4f3b157e066a8ed4)
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