blob: ed281997f1ad3a452866cf6a493451f5b8cd56ce [file] [log] [blame]
Alexey Samsonov28a98952012-06-07 06:15:12 +00001//===-- sanitizer_procmaps.h ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is shared between AddressSanitizer and ThreadSanitizer.
11//
12// Information about the process mappings.
13//===----------------------------------------------------------------------===//
14#ifndef SANITIZER_PROCMAPS_H
15#define SANITIZER_PROCMAPS_H
16
17#include "sanitizer_internal_defs.h"
Alexander Potapenko78114252012-12-01 02:39:45 +000018#include "sanitizer_mutex.h"
Alexey Samsonov28a98952012-06-07 06:15:12 +000019
20namespace __sanitizer {
21
Evgeniy Stepanov95eaa212013-03-19 14:54:17 +000022#if SANITIZER_WINDOWS
Alexey Samsonovcc622112012-08-27 13:48:48 +000023class MemoryMappingLayout {
Alexey Samsonov28d8be22012-08-27 14:08:53 +000024 public:
Dmitry Vyukov9f08fe52013-03-27 17:57:58 +000025 explicit MemoryMappingLayout(bool cache_enabled) {
Alexander Potapenko29310ba2013-03-26 13:02:11 +000026 (void)cache_enabled;
27 }
Alexey Samsonovcae486c2012-08-28 07:22:24 +000028 bool GetObjectNameAndOffset(uptr addr, uptr *offset,
Alexey Samsonov91f833a2013-03-13 07:39:25 +000029 char filename[], uptr filename_size,
30 uptr *protection) {
Alexey Samsonovcae486c2012-08-28 07:22:24 +000031 UNIMPLEMENTED();
Alexey Samsonovcae486c2012-08-28 07:22:24 +000032 }
Alexey Samsonovcc622112012-08-27 13:48:48 +000033};
34
Alexander Potapenko7e1c5192013-09-03 11:09:16 +000035#else // SANITIZER_WINDOWS
Evgeniy Stepanov0af67232013-03-19 14:33:38 +000036#if SANITIZER_LINUX
Alexander Potapenkoe2b6d082012-12-03 21:21:22 +000037struct ProcSelfMapsBuff {
38 char *data;
39 uptr mmaped_size;
40 uptr len;
41};
Evgeniy Stepanov0af67232013-03-19 14:33:38 +000042#endif // SANITIZER_LINUX
Alexander Potapenkoe2b6d082012-12-03 21:21:22 +000043
Alexey Samsonovcc622112012-08-27 13:48:48 +000044class MemoryMappingLayout {
Alexey Samsonov28a98952012-06-07 06:15:12 +000045 public:
Alexander Potapenkof8109dd2013-03-26 10:34:37 +000046 explicit MemoryMappingLayout(bool cache_enabled);
Alexey Samsonov28a98952012-06-07 06:15:12 +000047 bool Next(uptr *start, uptr *end, uptr *offset,
Alexey Samsonov06d3aa42013-03-13 06:51:02 +000048 char filename[], uptr filename_size, uptr *protection);
Alexey Samsonov28a98952012-06-07 06:15:12 +000049 void Reset();
50 // Gets the object file name and the offset in that object for a given
51 // address 'addr'. Returns true on success.
52 bool GetObjectNameAndOffset(uptr addr, uptr *offset,
Alexey Samsonov06d3aa42013-03-13 06:51:02 +000053 char filename[], uptr filename_size,
54 uptr *protection);
Alexander Potapenko78114252012-12-01 02:39:45 +000055 // In some cases, e.g. when running under a sandbox on Linux, ASan is unable
56 // to obtain the memory mappings. It should fall back to pre-cached data
57 // instead of aborting.
58 static void CacheMemoryMappings();
Alexey Samsonovcc622112012-08-27 13:48:48 +000059 ~MemoryMappingLayout();
Kostya Serebryany98390d02012-06-20 15:19:17 +000060
Alexey Samsonov06d3aa42013-03-13 06:51:02 +000061 // Memory protection masks.
62 static const uptr kProtectionRead = 1;
63 static const uptr kProtectionWrite = 2;
64 static const uptr kProtectionExecute = 4;
65 static const uptr kProtectionShared = 8;
66
Alexey Samsonov28a98952012-06-07 06:15:12 +000067 private:
Alexander Potapenko78114252012-12-01 02:39:45 +000068 void LoadFromCache();
Alexey Samsonov28a98952012-06-07 06:15:12 +000069 // Default implementation of GetObjectNameAndOffset.
70 // Quite slow, because it iterates through the whole process map for each
71 // lookup.
72 bool IterateForObjectNameAndOffset(uptr addr, uptr *offset,
Alexey Samsonov06d3aa42013-03-13 06:51:02 +000073 char filename[], uptr filename_size,
74 uptr *protection) {
Alexey Samsonov28a98952012-06-07 06:15:12 +000075 Reset();
76 uptr start, end, file_offset;
Alexey Samsonov06d3aa42013-03-13 06:51:02 +000077 for (int i = 0; Next(&start, &end, &file_offset, filename, filename_size,
78 protection);
Alexey Samsonov28a98952012-06-07 06:15:12 +000079 i++) {
80 if (addr >= start && addr < end) {
Alexey Samsonov961276a2012-07-03 08:24:14 +000081 // Don't subtract 'start' for the first entry:
82 // * If a binary is compiled w/o -pie, then the first entry in
83 // process maps is likely the binary itself (all dynamic libs
84 // are mapped higher in address space). For such a binary,
85 // instruction offset in binary coincides with the actual
86 // instruction address in virtual memory (as code section
87 // is mapped to a fixed memory range).
88 // * If a binary is compiled with -pie, all the modules are
89 // mapped high at address space (in particular, higher than
90 // shadow memory of the tool), so the module can't be the
91 // first entry.
Alexey Samsonov28a98952012-06-07 06:15:12 +000092 *offset = (addr - (i ? start : 0)) + file_offset;
93 return true;
94 }
95 }
96 if (filename_size)
97 filename[0] = '\0';
98 return false;
99 }
100
Alexey Samsonova0e28a72013-04-03 07:24:35 +0000101# if SANITIZER_LINUX
Alexander Potapenkoe2b6d082012-12-03 21:21:22 +0000102 ProcSelfMapsBuff proc_self_maps_;
Alexey Samsonov28a98952012-06-07 06:15:12 +0000103 char *current_;
Alexander Potapenko78114252012-12-01 02:39:45 +0000104
105 // Static mappings cache.
Alexander Potapenkoe2b6d082012-12-03 21:21:22 +0000106 static ProcSelfMapsBuff cached_proc_self_maps_;
107 static StaticSpinMutex cache_lock_; // protects cached_proc_self_maps_.
Alexey Samsonova0e28a72013-04-03 07:24:35 +0000108# elif SANITIZER_MAC
Alexey Samsonov28a98952012-06-07 06:15:12 +0000109 template<u32 kLCSegment, typename SegmentCommand>
110 bool NextSegmentLoad(uptr *start, uptr *end, uptr *offset,
Alexey Samsonov91f833a2013-03-13 07:39:25 +0000111 char filename[], uptr filename_size,
112 uptr *protection);
Alexey Samsonov28a98952012-06-07 06:15:12 +0000113 int current_image_;
114 u32 current_magic_;
Alexander Potapenko77c0ac22012-10-02 15:42:24 +0000115 u32 current_filetype_;
Alexey Samsonov28a98952012-06-07 06:15:12 +0000116 int current_load_cmd_count_;
117 char *current_load_cmd_addr_;
Alexey Samsonovcae486c2012-08-28 07:22:24 +0000118# endif
Alexey Samsonov28a98952012-06-07 06:15:12 +0000119};
120
Alexander Potapenko7e1c5192013-09-03 11:09:16 +0000121typedef void (*fill_profile_f)(uptr start, uptr rss, bool file,
122 /*out*/uptr *stats, uptr stats_size);
123
124// Parse the contents of /proc/self/smaps and generate a memory profile.
125// |cb| is a tool-specific callback that fills the |stats| array containing
126// |stats_size| elements.
127void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size);
128
129#endif // SANITIZER_WINDOWS
Alexey Samsonovcc622112012-08-27 13:48:48 +0000130
Alexey Samsonov28a98952012-06-07 06:15:12 +0000131} // namespace __sanitizer
132
133#endif // SANITIZER_PROCMAPS_H