123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- //===-- sanitizer_procmaps_bsd.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
- // (FreeBSD and NetBSD-specific parts).
- //===----------------------------------------------------------------------===//
- #include "sanitizer_platform.h"
- #if SANITIZER_FREEBSD || SANITIZER_NETBSD
- #include "sanitizer_common.h"
- #if SANITIZER_FREEBSD
- #include "sanitizer_freebsd.h"
- #endif
- #include "sanitizer_procmaps.h"
- // clang-format off
- #include <sys/types.h>
- #include <sys/sysctl.h>
- // clang-format on
- #include <unistd.h>
- #if SANITIZER_FREEBSD
- #include <sys/user.h>
- #endif
- #include <limits.h>
- // Fix 'kinfo_vmentry' definition on FreeBSD prior v9.2 in 32-bit mode.
- #if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
- #include <osreldate.h>
- #if __FreeBSD_version <= 902001 // v9.2
- #define kinfo_vmentry xkinfo_vmentry
- #endif
- #endif
- namespace __sanitizer {
- #if SANITIZER_FREEBSD
- void GetMemoryProfile(fill_profile_f cb, uptr *stats) {
- const int Mib[] = {
- CTL_KERN,
- KERN_PROC,
- KERN_PROC_PID,
- getpid()
- };
- struct kinfo_proc InfoProc;
- uptr Len = sizeof(InfoProc);
- CHECK_EQ(internal_sysctl(Mib, ARRAY_SIZE(Mib), nullptr, (uptr *)&InfoProc, &Len, 0), 0);
- cb(0, InfoProc.ki_rssize * GetPageSizeCached(), false, stats);
- }
- #endif
- void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
- const int Mib[] = {
- #if SANITIZER_FREEBSD
- CTL_KERN,
- KERN_PROC,
- KERN_PROC_VMMAP,
- getpid()
- #elif SANITIZER_NETBSD
- CTL_VM,
- VM_PROC,
- VM_PROC_MAP,
- getpid(),
- sizeof(struct kinfo_vmentry)
- #else
- #error "not supported"
- #endif
- };
- uptr Size = 0;
- int Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), NULL, &Size, NULL, 0);
- CHECK_EQ(Err, 0);
- CHECK_GT(Size, 0);
- size_t MmapedSize = Size * 4 / 3;
- void *VmMap = MmapOrDie(MmapedSize, "ReadProcMaps()");
- Size = MmapedSize;
- Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), VmMap, &Size, NULL, 0);
- CHECK_EQ(Err, 0);
- proc_maps->data = (char *)VmMap;
- proc_maps->mmaped_size = MmapedSize;
- proc_maps->len = Size;
- }
- bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
- CHECK(!Error()); // can not fail
- char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
- if (data_.current >= last)
- return false;
- const struct kinfo_vmentry *VmEntry =
- (const struct kinfo_vmentry *)data_.current;
- segment->start = (uptr)VmEntry->kve_start;
- segment->end = (uptr)VmEntry->kve_end;
- segment->offset = (uptr)VmEntry->kve_offset;
- segment->protection = 0;
- if ((VmEntry->kve_protection & KVME_PROT_READ) != 0)
- segment->protection |= kProtectionRead;
- if ((VmEntry->kve_protection & KVME_PROT_WRITE) != 0)
- segment->protection |= kProtectionWrite;
- if ((VmEntry->kve_protection & KVME_PROT_EXEC) != 0)
- segment->protection |= kProtectionExecute;
- if (segment->filename != NULL && segment->filename_size > 0) {
- internal_snprintf(segment->filename,
- Min(segment->filename_size, (uptr)PATH_MAX), "%s",
- VmEntry->kve_path);
- }
- #if SANITIZER_FREEBSD
- data_.current += VmEntry->kve_structsize;
- #else
- data_.current += sizeof(*VmEntry);
- #endif
- return true;
- }
- } // namespace __sanitizer
- #endif
|