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