| //===-- sanitizer_procmaps_fuchsia.cpp |
| //----------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Information about the process mappings (Fuchsia-specific parts). |
| //===----------------------------------------------------------------------===// |
| |
| #include "sanitizer_platform.h" |
| #if SANITIZER_FUCHSIA |
| #include <zircon/process.h> |
| #include <zircon/syscalls.h> |
| |
| #include "sanitizer_common.h" |
| #include "sanitizer_procmaps.h" |
| |
| namespace __sanitizer { |
| |
| // The cache flag is ignored on Fuchsia because a process can always get this |
| // information via its process-self handle. |
| MemoryMappingLayout::MemoryMappingLayout(bool) { Reset(); } |
| |
| void MemoryMappingLayout::Reset() { |
| data_.data.clear(); |
| data_.current = 0; |
| |
| size_t count; |
| zx_status_t status = _zx_object_get_info( |
| _zx_process_self(), ZX_INFO_PROCESS_MAPS, nullptr, 0, nullptr, &count); |
| if (status != ZX_OK) { |
| return; |
| } |
| |
| size_t filled; |
| do { |
| data_.data.resize(count); |
| status = _zx_object_get_info( |
| _zx_process_self(), ZX_INFO_PROCESS_MAPS, data_.data.data(), |
| count * sizeof(zx_info_maps_t), &filled, &count); |
| if (status != ZX_OK) { |
| data_.data.clear(); |
| return; |
| } |
| } while (filled < count); |
| } |
| |
| MemoryMappingLayout::~MemoryMappingLayout() {} |
| |
| bool MemoryMappingLayout::Error() const { return data_.data.empty(); } |
| |
| bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { |
| while (data_.current < data_.data.size()) { |
| const auto &entry = data_.data[data_.current++]; |
| if (entry.type == ZX_INFO_MAPS_TYPE_MAPPING) { |
| segment->start = entry.base; |
| segment->end = entry.base + entry.size; |
| segment->offset = entry.u.mapping.vmo_offset; |
| const auto flags = entry.u.mapping.mmu_flags; |
| segment->protection = |
| ((flags & ZX_VM_PERM_READ) ? kProtectionRead : 0) | |
| ((flags & ZX_VM_PERM_WRITE) ? kProtectionWrite : 0) | |
| ((flags & ZX_VM_PERM_EXECUTE) ? kProtectionExecute : 0); |
| if (segment->filename && segment->filename_size > 0) { |
| uptr len = Min(sizeof(entry.name), segment->filename_size) - 1; |
| internal_strncpy(segment->filename, entry.name, len); |
| segment->filename[len] = 0; |
| } |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| } // namespace __sanitizer |
| |
| #endif // SANITIZER_FUCHSIA |