16d1862363c88c183b0ed7740fca876342cf0474bStephen Hines//===-- sanitizer_procmaps_freebsd.cc -------------------------------------===// 26d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// 36d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// The LLVM Compiler Infrastructure 46d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// 56d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// This file is distributed under the University of Illinois Open Source 66d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// License. See LICENSE.TXT for details. 76d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// 86d1862363c88c183b0ed7740fca876342cf0474bStephen Hines//===----------------------------------------------------------------------===// 96d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// 106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// Information about the process mappings (FreeBSD-specific parts). 116d1862363c88c183b0ed7740fca876342cf0474bStephen Hines//===----------------------------------------------------------------------===// 126d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 136d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include "sanitizer_platform.h" 146d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if SANITIZER_FREEBSD 156d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include "sanitizer_common.h" 166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include "sanitizer_freebsd.h" 176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include "sanitizer_procmaps.h" 186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <unistd.h> 206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <sys/sysctl.h> 216d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <sys/user.h> 226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// Fix 'kinfo_vmentry' definition on FreeBSD prior v9.2 in 32-bit mode. 246d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) 256d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# include <osreldate.h> 266d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# if __FreeBSD_version <= 902001 // v9.2 276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# define kinfo_vmentry xkinfo_vmentry 286d1862363c88c183b0ed7740fca876342cf0474bStephen Hines# endif 296d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif 306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 316d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesnamespace __sanitizer { 326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 336d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid ReadProcMaps(ProcSelfMapsBuff *proc_maps) { 346d1862363c88c183b0ed7740fca876342cf0474bStephen Hines const int Mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid() }; 356d1862363c88c183b0ed7740fca876342cf0474bStephen Hines size_t Size = 0; 366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines int Err = sysctl(Mib, 4, NULL, &Size, NULL, 0); 376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines CHECK_EQ(Err, 0); 386d1862363c88c183b0ed7740fca876342cf0474bStephen Hines CHECK_GT(Size, 0); 396d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 406d1862363c88c183b0ed7740fca876342cf0474bStephen Hines size_t MmapedSize = Size * 4 / 3; 416d1862363c88c183b0ed7740fca876342cf0474bStephen Hines void *VmMap = MmapOrDie(MmapedSize, "ReadProcMaps()"); 426d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Size = MmapedSize; 436d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Err = sysctl(Mib, 4, VmMap, &Size, NULL, 0); 446d1862363c88c183b0ed7740fca876342cf0474bStephen Hines CHECK_EQ(Err, 0); 456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 466d1862363c88c183b0ed7740fca876342cf0474bStephen Hines proc_maps->data = (char*)VmMap; 476d1862363c88c183b0ed7740fca876342cf0474bStephen Hines proc_maps->mmaped_size = MmapedSize; 486d1862363c88c183b0ed7740fca876342cf0474bStephen Hines proc_maps->len = Size; 496d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 506d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 516d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesbool MemoryMappingLayout::Next(uptr *start, uptr *end, uptr *offset, 526d1862363c88c183b0ed7740fca876342cf0474bStephen Hines char filename[], uptr filename_size, 536d1862363c88c183b0ed7740fca876342cf0474bStephen Hines uptr *protection) { 546d1862363c88c183b0ed7740fca876342cf0474bStephen Hines char *last = proc_self_maps_.data + proc_self_maps_.len; 556d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (current_ >= last) return false; 566d1862363c88c183b0ed7740fca876342cf0474bStephen Hines uptr dummy; 576d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (!start) start = &dummy; 586d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (!end) end = &dummy; 596d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (!offset) offset = &dummy; 606d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (!protection) protection = &dummy; 616d1862363c88c183b0ed7740fca876342cf0474bStephen Hines struct kinfo_vmentry *VmEntry = (struct kinfo_vmentry*)current_; 626d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines *start = (uptr)VmEntry->kve_start; 646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines *end = (uptr)VmEntry->kve_end; 656d1862363c88c183b0ed7740fca876342cf0474bStephen Hines *offset = (uptr)VmEntry->kve_offset; 666d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 676d1862363c88c183b0ed7740fca876342cf0474bStephen Hines *protection = 0; 686d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if ((VmEntry->kve_protection & KVME_PROT_READ) != 0) 696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines *protection |= kProtectionRead; 706d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if ((VmEntry->kve_protection & KVME_PROT_WRITE) != 0) 716d1862363c88c183b0ed7740fca876342cf0474bStephen Hines *protection |= kProtectionWrite; 726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if ((VmEntry->kve_protection & KVME_PROT_EXEC) != 0) 736d1862363c88c183b0ed7740fca876342cf0474bStephen Hines *protection |= kProtectionExecute; 746d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 756d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (filename != NULL && filename_size > 0) { 766d1862363c88c183b0ed7740fca876342cf0474bStephen Hines internal_snprintf(filename, 776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Min(filename_size, (uptr)PATH_MAX), 786d1862363c88c183b0ed7740fca876342cf0474bStephen Hines "%s", VmEntry->kve_path); 796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines } 806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 816d1862363c88c183b0ed7740fca876342cf0474bStephen Hines current_ += VmEntry->kve_structsize; 826d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines return true; 846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} // namespace __sanitizer 876d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 886d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif // SANITIZER_FREEBSD 89