1238901Sandrew//===-- sanitizer_procmaps.h ------------------------------------*- C++ -*-===//
2238901Sandrew//
3238901Sandrew//                     The LLVM Compiler Infrastructure
4238901Sandrew//
5238901Sandrew// This file is distributed under the University of Illinois Open Source
6238901Sandrew// License. See LICENSE.TXT for details.
7238901Sandrew//
8238901Sandrew//===----------------------------------------------------------------------===//
9238901Sandrew//
10238901Sandrew// This file is shared between AddressSanitizer and ThreadSanitizer.
11238901Sandrew//
12238901Sandrew// Information about the process mappings.
13238901Sandrew//===----------------------------------------------------------------------===//
14238901Sandrew#ifndef SANITIZER_PROCMAPS_H
15238901Sandrew#define SANITIZER_PROCMAPS_H
16238901Sandrew
17276789Sdim#include "sanitizer_common.h"
18238901Sandrew#include "sanitizer_internal_defs.h"
19245614Sandrew#include "sanitizer_mutex.h"
20238901Sandrew
21238901Sandrewnamespace __sanitizer {
22238901Sandrew
23276789Sdim#if SANITIZER_FREEBSD || SANITIZER_LINUX
24245614Sandrewstruct ProcSelfMapsBuff {
25245614Sandrew  char *data;
26245614Sandrew  uptr mmaped_size;
27245614Sandrew  uptr len;
28245614Sandrew};
29245614Sandrew
30276789Sdim// Reads process memory map in an OS-specific way.
31276789Sdimvoid ReadProcMaps(ProcSelfMapsBuff *proc_maps);
32276789Sdim#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX
33276789Sdim
34245614Sandrewclass MemoryMappingLayout {
35245614Sandrew public:
36251034Sed  explicit MemoryMappingLayout(bool cache_enabled);
37276789Sdim  ~MemoryMappingLayout();
38238901Sandrew  bool Next(uptr *start, uptr *end, uptr *offset,
39251034Sed            char filename[], uptr filename_size, uptr *protection);
40238901Sandrew  void Reset();
41245614Sandrew  // In some cases, e.g. when running under a sandbox on Linux, ASan is unable
42245614Sandrew  // to obtain the memory mappings. It should fall back to pre-cached data
43245614Sandrew  // instead of aborting.
44245614Sandrew  static void CacheMemoryMappings();
45238901Sandrew
46276789Sdim  // Stores the list of mapped objects into an array.
47276789Sdim  uptr DumpListOfModules(LoadedModule *modules, uptr max_modules,
48276789Sdim                         string_predicate_t filter);
49276789Sdim
50251034Sed  // Memory protection masks.
51251034Sed  static const uptr kProtectionRead = 1;
52251034Sed  static const uptr kProtectionWrite = 2;
53251034Sed  static const uptr kProtectionExecute = 4;
54251034Sed  static const uptr kProtectionShared = 8;
55251034Sed
56238901Sandrew private:
57245614Sandrew  void LoadFromCache();
58238901Sandrew
59276789Sdim  // FIXME: Hide implementation details for different platforms in
60276789Sdim  // platform-specific files.
61276789Sdim# if SANITIZER_FREEBSD || SANITIZER_LINUX
62245614Sandrew  ProcSelfMapsBuff proc_self_maps_;
63276789Sdim  const char *current_;
64245614Sandrew
65245614Sandrew  // Static mappings cache.
66245614Sandrew  static ProcSelfMapsBuff cached_proc_self_maps_;
67245614Sandrew  static StaticSpinMutex cache_lock_;  // protects cached_proc_self_maps_.
68251034Sed# elif SANITIZER_MAC
69238901Sandrew  template<u32 kLCSegment, typename SegmentCommand>
70238901Sandrew  bool NextSegmentLoad(uptr *start, uptr *end, uptr *offset,
71251034Sed                       char filename[], uptr filename_size,
72251034Sed                       uptr *protection);
73238901Sandrew  int current_image_;
74238901Sandrew  u32 current_magic_;
75245614Sandrew  u32 current_filetype_;
76238901Sandrew  int current_load_cmd_count_;
77238901Sandrew  char *current_load_cmd_addr_;
78245614Sandrew# endif
79238901Sandrew};
80238901Sandrew
81274201Sdimtypedef void (*fill_profile_f)(uptr start, uptr rss, bool file,
82274201Sdim                               /*out*/uptr *stats, uptr stats_size);
83245614Sandrew
84274201Sdim// Parse the contents of /proc/self/smaps and generate a memory profile.
85274201Sdim// |cb| is a tool-specific callback that fills the |stats| array containing
86274201Sdim// |stats_size| elements.
87274201Sdimvoid GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size);
88274201Sdim
89274201Sdim// Returns code range for the specified module.
90274201Sdimbool GetCodeRangeForFile(const char *module, uptr *start, uptr *end);
91274201Sdim
92276789Sdimbool IsDecimal(char c);
93276789Sdimuptr ParseDecimal(const char **p);
94276789Sdimbool IsHex(char c);
95276789Sdimuptr ParseHex(const char **p);
96274201Sdim
97238901Sandrew}  // namespace __sanitizer
98238901Sandrew
99238901Sandrew#endif  // SANITIZER_PROCMAPS_H
100