xref: /openbsd-src/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_bsd.cpp (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrick //===-- sanitizer_procmaps_bsd.cpp ----------------------------------------===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // Information about the process mappings
10d89ec533Spatrick // (FreeBSD and NetBSD-specific parts).
113cab2bb3Spatrick //===----------------------------------------------------------------------===//
123cab2bb3Spatrick 
133cab2bb3Spatrick #include "sanitizer_platform.h"
14d89ec533Spatrick #if SANITIZER_FREEBSD || SANITIZER_NETBSD
153cab2bb3Spatrick #include "sanitizer_common.h"
163cab2bb3Spatrick #if SANITIZER_FREEBSD
173cab2bb3Spatrick #include "sanitizer_freebsd.h"
183cab2bb3Spatrick #endif
193cab2bb3Spatrick #include "sanitizer_procmaps.h"
203cab2bb3Spatrick 
213cab2bb3Spatrick // clang-format off
223cab2bb3Spatrick #include <sys/types.h>
233cab2bb3Spatrick #include <sys/sysctl.h>
243cab2bb3Spatrick // clang-format on
253cab2bb3Spatrick #include <unistd.h>
263cab2bb3Spatrick #if SANITIZER_FREEBSD
273cab2bb3Spatrick #include <sys/user.h>
283cab2bb3Spatrick #endif
293cab2bb3Spatrick 
303cab2bb3Spatrick #include <limits.h>
313cab2bb3Spatrick 
323cab2bb3Spatrick // Fix 'kinfo_vmentry' definition on FreeBSD prior v9.2 in 32-bit mode.
333cab2bb3Spatrick #if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
343cab2bb3Spatrick #include <osreldate.h>
353cab2bb3Spatrick #if __FreeBSD_version <= 902001 // v9.2
363cab2bb3Spatrick #define kinfo_vmentry xkinfo_vmentry
373cab2bb3Spatrick #endif
383cab2bb3Spatrick #endif
393cab2bb3Spatrick 
403cab2bb3Spatrick namespace __sanitizer {
413cab2bb3Spatrick 
42*810390e3Srobert #if SANITIZER_FREEBSD
GetMemoryProfile(fill_profile_f cb,uptr * stats)43*810390e3Srobert void GetMemoryProfile(fill_profile_f cb, uptr *stats) {
44*810390e3Srobert   const int Mib[] = {
45*810390e3Srobert     CTL_KERN,
46*810390e3Srobert     KERN_PROC,
47*810390e3Srobert     KERN_PROC_PID,
48*810390e3Srobert     getpid()
49*810390e3Srobert   };
50*810390e3Srobert 
51*810390e3Srobert   struct kinfo_proc InfoProc;
52*810390e3Srobert   uptr Len = sizeof(InfoProc);
53*810390e3Srobert   CHECK_EQ(internal_sysctl(Mib, ARRAY_SIZE(Mib), nullptr, (uptr *)&InfoProc, &Len, 0), 0);
54*810390e3Srobert   cb(0, InfoProc.ki_rssize * GetPageSizeCached(), false, stats);
55*810390e3Srobert }
56*810390e3Srobert #endif
57*810390e3Srobert 
ReadProcMaps(ProcSelfMapsBuff * proc_maps)583cab2bb3Spatrick void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
593cab2bb3Spatrick   const int Mib[] = {
603cab2bb3Spatrick #if SANITIZER_FREEBSD
613cab2bb3Spatrick     CTL_KERN,
623cab2bb3Spatrick     KERN_PROC,
633cab2bb3Spatrick     KERN_PROC_VMMAP,
643cab2bb3Spatrick     getpid()
653cab2bb3Spatrick #elif SANITIZER_NETBSD
663cab2bb3Spatrick     CTL_VM,
673cab2bb3Spatrick     VM_PROC,
683cab2bb3Spatrick     VM_PROC_MAP,
693cab2bb3Spatrick     getpid(),
703cab2bb3Spatrick     sizeof(struct kinfo_vmentry)
713cab2bb3Spatrick #else
723cab2bb3Spatrick #error "not supported"
733cab2bb3Spatrick #endif
743cab2bb3Spatrick   };
753cab2bb3Spatrick 
763cab2bb3Spatrick   uptr Size = 0;
773cab2bb3Spatrick   int Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), NULL, &Size, NULL, 0);
783cab2bb3Spatrick   CHECK_EQ(Err, 0);
793cab2bb3Spatrick   CHECK_GT(Size, 0);
803cab2bb3Spatrick 
813cab2bb3Spatrick   size_t MmapedSize = Size * 4 / 3;
823cab2bb3Spatrick   void *VmMap = MmapOrDie(MmapedSize, "ReadProcMaps()");
833cab2bb3Spatrick   Size = MmapedSize;
843cab2bb3Spatrick   Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), VmMap, &Size, NULL, 0);
853cab2bb3Spatrick   CHECK_EQ(Err, 0);
863cab2bb3Spatrick   proc_maps->data = (char *)VmMap;
873cab2bb3Spatrick   proc_maps->mmaped_size = MmapedSize;
883cab2bb3Spatrick   proc_maps->len = Size;
893cab2bb3Spatrick }
903cab2bb3Spatrick 
Next(MemoryMappedSegment * segment)913cab2bb3Spatrick bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
923cab2bb3Spatrick   CHECK(!Error()); // can not fail
933cab2bb3Spatrick   char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
943cab2bb3Spatrick   if (data_.current >= last)
953cab2bb3Spatrick     return false;
963cab2bb3Spatrick   const struct kinfo_vmentry *VmEntry =
973cab2bb3Spatrick       (const struct kinfo_vmentry *)data_.current;
983cab2bb3Spatrick 
993cab2bb3Spatrick   segment->start = (uptr)VmEntry->kve_start;
1003cab2bb3Spatrick   segment->end = (uptr)VmEntry->kve_end;
1013cab2bb3Spatrick   segment->offset = (uptr)VmEntry->kve_offset;
1023cab2bb3Spatrick 
1033cab2bb3Spatrick   segment->protection = 0;
1043cab2bb3Spatrick   if ((VmEntry->kve_protection & KVME_PROT_READ) != 0)
1053cab2bb3Spatrick     segment->protection |= kProtectionRead;
1063cab2bb3Spatrick   if ((VmEntry->kve_protection & KVME_PROT_WRITE) != 0)
1073cab2bb3Spatrick     segment->protection |= kProtectionWrite;
1083cab2bb3Spatrick   if ((VmEntry->kve_protection & KVME_PROT_EXEC) != 0)
1093cab2bb3Spatrick     segment->protection |= kProtectionExecute;
1103cab2bb3Spatrick 
1113cab2bb3Spatrick   if (segment->filename != NULL && segment->filename_size > 0) {
1123cab2bb3Spatrick     internal_snprintf(segment->filename,
1133cab2bb3Spatrick                       Min(segment->filename_size, (uptr)PATH_MAX), "%s",
1143cab2bb3Spatrick                       VmEntry->kve_path);
1153cab2bb3Spatrick   }
1163cab2bb3Spatrick 
1173cab2bb3Spatrick #if SANITIZER_FREEBSD
1183cab2bb3Spatrick   data_.current += VmEntry->kve_structsize;
1193cab2bb3Spatrick #else
1203cab2bb3Spatrick   data_.current += sizeof(*VmEntry);
1213cab2bb3Spatrick #endif
1223cab2bb3Spatrick 
1233cab2bb3Spatrick   return true;
1243cab2bb3Spatrick }
1253cab2bb3Spatrick 
1263cab2bb3Spatrick } // namespace __sanitizer
1273cab2bb3Spatrick 
1283cab2bb3Spatrick #endif
129