diff options
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_procmaps_fuchsia.cpp')
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_procmaps_fuchsia.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_fuchsia.cpp new file mode 100644 index 000000000000..cc3e9be06458 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_fuchsia.cpp @@ -0,0 +1,80 @@ +//===-- 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 |