1 //===-- sanitizer_procmaps_bsd.cpp ----------------------------------------===//
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-exception
7 //===----------------------------------------------------------------------===//
9 // Information about the process mappings
10 // (FreeBSD and NetBSD-specific parts).
11 //===----------------------------------------------------------------------===//
13 #include "sanitizer_platform.h"
14 #if SANITIZER_FREEBSD || SANITIZER_NETBSD
15 #include "sanitizer_common.h"
17 #include "sanitizer_freebsd.h"
19 #include "sanitizer_procmaps.h"
22 #include <sys/types.h>
23 #include <sys/sysctl.h>
32 // Fix 'kinfo_vmentry' definition on FreeBSD prior v9.2 in 32-bit mode.
33 #if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
34 #include <osreldate.h>
35 #if __FreeBSD_version <= 902001 // v9.2
36 #define kinfo_vmentry xkinfo_vmentry
40 namespace __sanitizer
{
43 void GetMemoryProfile(fill_profile_f cb
, uptr
*stats
) {
51 struct kinfo_proc InfoProc
;
52 uptr Len
= sizeof(InfoProc
);
53 CHECK_EQ(internal_sysctl(Mib
, ARRAY_SIZE(Mib
), nullptr, (uptr
*)&InfoProc
, &Len
, 0), 0);
54 cb(0, InfoProc
.ki_rssize
* GetPageSizeCached(), false, stats
);
58 void ReadProcMaps(ProcSelfMapsBuff
*proc_maps
) {
65 #elif SANITIZER_NETBSD
70 sizeof(struct kinfo_vmentry
)
72 #error "not supported"
77 int Err
= internal_sysctl(Mib
, ARRAY_SIZE(Mib
), NULL
, &Size
, NULL
, 0);
81 size_t MmapedSize
= Size
* 4 / 3;
82 void *VmMap
= MmapOrDie(MmapedSize
, "ReadProcMaps()");
84 Err
= internal_sysctl(Mib
, ARRAY_SIZE(Mib
), VmMap
, &Size
, NULL
, 0);
86 proc_maps
->data
= (char *)VmMap
;
87 proc_maps
->mmaped_size
= MmapedSize
;
88 proc_maps
->len
= Size
;
91 bool MemoryMappingLayout::Next(MemoryMappedSegment
*segment
) {
92 CHECK(!Error()); // can not fail
93 char *last
= data_
.proc_self_maps
.data
+ data_
.proc_self_maps
.len
;
94 if (data_
.current
>= last
)
96 const struct kinfo_vmentry
*VmEntry
=
97 (const struct kinfo_vmentry
*)data_
.current
;
99 segment
->start
= (uptr
)VmEntry
->kve_start
;
100 segment
->end
= (uptr
)VmEntry
->kve_end
;
101 segment
->offset
= (uptr
)VmEntry
->kve_offset
;
103 segment
->protection
= 0;
104 if ((VmEntry
->kve_protection
& KVME_PROT_READ
) != 0)
105 segment
->protection
|= kProtectionRead
;
106 if ((VmEntry
->kve_protection
& KVME_PROT_WRITE
) != 0)
107 segment
->protection
|= kProtectionWrite
;
108 if ((VmEntry
->kve_protection
& KVME_PROT_EXEC
) != 0)
109 segment
->protection
|= kProtectionExecute
;
111 if (segment
->filename
!= NULL
&& segment
->filename_size
> 0) {
112 internal_snprintf(segment
->filename
,
113 Min(segment
->filename_size
, (uptr
)PATH_MAX
), "%s",
117 #if SANITIZER_FREEBSD
118 data_
.current
+= VmEntry
->kve_structsize
;
120 data_
.current
+= sizeof(*VmEntry
);
126 } // namespace __sanitizer