brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · ee3fd5b Raw
132 lines · cpp
1//===-- sanitizer_procmaps_bsd.cpp ----------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Information about the process mappings10// (FreeBSD and NetBSD-specific parts).11//===----------------------------------------------------------------------===//12 13#include "sanitizer_platform.h"14#if SANITIZER_FREEBSD || SANITIZER_NETBSD15#include "sanitizer_common.h"16#include "sanitizer_procmaps.h"17 18// clang-format off19#include <sys/types.h>20#include <sys/sysctl.h>21// clang-format on22#include <unistd.h>23#if SANITIZER_FREEBSD24#include <sys/user.h>25#endif26 27#include <limits.h>28 29namespace __sanitizer {30 31#if SANITIZER_FREEBSD32void GetMemoryProfile(fill_profile_f cb, uptr *stats) {33  const int Mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};34 35  struct kinfo_proc *InfoProc;36  uptr Len = sizeof(*InfoProc);37  uptr Size = Len;38  InfoProc = (struct kinfo_proc *)MmapOrDie(Size, "GetMemoryProfile()");39  CHECK_EQ(40      internal_sysctl(Mib, ARRAY_SIZE(Mib), nullptr, (uptr *)InfoProc, &Len, 0),41      0);42  cb(0, InfoProc->ki_rssize * GetPageSizeCached(), false, stats);43  UnmapOrDie(InfoProc, Size, true);44}45#elif SANITIZER_NETBSD46void GetMemoryProfile(fill_profile_f cb, uptr *stats) {47  struct kinfo_proc2 *InfoProc;48  uptr Len = sizeof(*InfoProc);49  uptr Size = Len;50  const int Mib[] = {CTL_KERN, KERN_PROC2, KERN_PROC_PID,51                     getpid(), (int)Size,  1};52  InfoProc = (struct kinfo_proc2 *)MmapOrDie(Size, "GetMemoryProfile()");53  CHECK_EQ(54      internal_sysctl(Mib, ARRAY_SIZE(Mib), nullptr, (uptr *)InfoProc, &Len, 0),55      0);56  cb(0, InfoProc->p_vm_rssize * GetPageSizeCached(), false, stats);57  UnmapOrDie(InfoProc, Size, true);58}59#endif60 61void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {62  const int Mib[] = {63#if SANITIZER_FREEBSD64    CTL_KERN,65    KERN_PROC,66    KERN_PROC_VMMAP,67    getpid()68#elif SANITIZER_NETBSD69    CTL_VM,70    VM_PROC,71    VM_PROC_MAP,72    getpid(),73    sizeof(struct kinfo_vmentry)74#else75#error "not supported"76#endif77  };78 79  uptr Size = 0;80  int Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), NULL, &Size, NULL, 0);81  CHECK_EQ(Err, 0);82  CHECK_GT(Size, 0);83 84  size_t MmapedSize = Size * 4 / 3;85  void *VmMap = MmapOrDie(MmapedSize, "ReadProcMaps()");86  Size = MmapedSize;87  Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), VmMap, &Size, NULL, 0);88  CHECK_EQ(Err, 0);89  proc_maps->data = (char *)VmMap;90  proc_maps->mmaped_size = MmapedSize;91  proc_maps->len = Size;92}93 94bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {95  CHECK(!Error()); // can not fail96  char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;97  if (data_.current >= last)98    return false;99  const struct kinfo_vmentry *VmEntry =100      (const struct kinfo_vmentry *)data_.current;101 102  segment->start = (uptr)VmEntry->kve_start;103  segment->end = (uptr)VmEntry->kve_end;104  segment->offset = (uptr)VmEntry->kve_offset;105 106  segment->protection = 0;107  if ((VmEntry->kve_protection & KVME_PROT_READ) != 0)108    segment->protection |= kProtectionRead;109  if ((VmEntry->kve_protection & KVME_PROT_WRITE) != 0)110    segment->protection |= kProtectionWrite;111  if ((VmEntry->kve_protection & KVME_PROT_EXEC) != 0)112    segment->protection |= kProtectionExecute;113 114  if (segment->filename != NULL && segment->filename_size > 0) {115    internal_snprintf(segment->filename,116                      Min(segment->filename_size, (uptr)PATH_MAX), "%s",117                      VmEntry->kve_path);118  }119 120#if SANITIZER_FREEBSD121  data_.current += VmEntry->kve_structsize;122#else123  data_.current += sizeof(*VmEntry);124#endif125 126  return true;127}128 129} // namespace __sanitizer130 131#endif132