1 //===-- sanitizer_procmaps.h ------------------------------------*- C++ -*-===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is shared between AddressSanitizer and ThreadSanitizer.
10 // Information about the process mappings.
11 //===----------------------------------------------------------------------===//
12 #ifndef SANITIZER_PROCMAPS_H
13 #define SANITIZER_PROCMAPS_H
15 #include "sanitizer_internal_defs.h"
16 #include "sanitizer_mutex.h"
18 namespace __sanitizer
{
21 class MemoryMappingLayout
{
23 explicit MemoryMappingLayout(bool cache_enabled
) {
26 bool GetObjectNameAndOffset(uptr addr
, uptr
*offset
,
27 char filename
[], uptr filename_size
,
33 #else // SANITIZER_WINDOWS
35 struct ProcSelfMapsBuff
{
40 #endif // SANITIZER_LINUX
42 class MemoryMappingLayout
{
44 explicit MemoryMappingLayout(bool cache_enabled
);
45 bool Next(uptr
*start
, uptr
*end
, uptr
*offset
,
46 char filename
[], uptr filename_size
, uptr
*protection
);
48 // Gets the object file name and the offset in that object for a given
49 // address 'addr'. Returns true on success.
50 bool GetObjectNameAndOffset(uptr addr
, uptr
*offset
,
51 char filename
[], uptr filename_size
,
53 // In some cases, e.g. when running under a sandbox on Linux, ASan is unable
54 // to obtain the memory mappings. It should fall back to pre-cached data
55 // instead of aborting.
56 static void CacheMemoryMappings();
57 ~MemoryMappingLayout();
59 // Memory protection masks.
60 static const uptr kProtectionRead
= 1;
61 static const uptr kProtectionWrite
= 2;
62 static const uptr kProtectionExecute
= 4;
63 static const uptr kProtectionShared
= 8;
67 // Default implementation of GetObjectNameAndOffset.
68 // Quite slow, because it iterates through the whole process map for each
70 bool IterateForObjectNameAndOffset(uptr addr
, uptr
*offset
,
71 char filename
[], uptr filename_size
,
74 uptr start
, end
, file_offset
;
75 for (int i
= 0; Next(&start
, &end
, &file_offset
, filename
, filename_size
,
78 if (addr
>= start
&& addr
< end
) {
79 // Don't subtract 'start' for the first entry:
80 // * If a binary is compiled w/o -pie, then the first entry in
81 // process maps is likely the binary itself (all dynamic libs
82 // are mapped higher in address space). For such a binary,
83 // instruction offset in binary coincides with the actual
84 // instruction address in virtual memory (as code section
85 // is mapped to a fixed memory range).
86 // * If a binary is compiled with -pie, all the modules are
87 // mapped high at address space (in particular, higher than
88 // shadow memory of the tool), so the module can't be the
90 *offset
= (addr
- (i
? start
: 0)) + file_offset
;
100 ProcSelfMapsBuff proc_self_maps_
;
103 // Static mappings cache.
104 static ProcSelfMapsBuff cached_proc_self_maps_
;
105 static StaticSpinMutex cache_lock_
; // protects cached_proc_self_maps_.
107 template<u32 kLCSegment
, typename SegmentCommand
>
108 bool NextSegmentLoad(uptr
*start
, uptr
*end
, uptr
*offset
,
109 char filename
[], uptr filename_size
,
113 u32 current_filetype_
;
114 int current_load_cmd_count_
;
115 char *current_load_cmd_addr_
;
119 typedef void (*fill_profile_f
)(uptr start
, uptr rss
, bool file
,
120 /*out*/uptr
*stats
, uptr stats_size
);
122 // Parse the contents of /proc/self/smaps and generate a memory profile.
123 // |cb| is a tool-specific callback that fills the |stats| array containing
124 // |stats_size| elements.
125 void GetMemoryProfile(fill_profile_f cb
, uptr
*stats
, uptr stats_size
);
127 // Returns code range for the specified module.
128 bool GetCodeRangeForFile(const char *module
, uptr
*start
, uptr
*end
);
130 #endif // SANITIZER_WINDOWS
132 } // namespace __sanitizer
134 #endif // SANITIZER_PROCMAPS_H