Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/MemoryMapping.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef mozilla_MemoryMapping_h
8
#define mozilla_MemoryMapping_h
9
10
#include "mozilla/EnumSet.h"
11
#include "nsString.h"
12
#include "nsTArray.h"
13
14
/**
15
 * MemoryMapping is a helper class which describes an entry in the Linux
16
 * /proc/<pid>/smaps file. See procfs(5) for details on the entry format.
17
 *
18
 * The GetMemoryMappings() function returns an array of such entries, sorted by
19
 * start address, one for each entry in the current process's address space.
20
 */
21
22
namespace mozilla {
23
24
enum class VMFlag : uint8_t
25
{
26
  Readable,      // rd  - readable
27
  Writable,      // wr  - writable
28
  Executable,    // ex  - executable
29
  Shared,        // sh  - shared
30
  MayRead,       // mr  - may read
31
  MayWrite,      // mw  - may write
32
  MayExecute,    // me  - may execute
33
  MayShare,      // ms  - may share
34
  GrowsDown,     // gd  - stack segment grows down
35
  PurePFN,       // pf  - pure PFN range
36
  DisabledWrite, // dw  - disabled write to the mapped file
37
  Locked,        // lo  - pages are locked in memory
38
  IO,            // io  - memory mapped I/O area
39
  Sequential,    // sr  - sequential read advise provided
40
  Random,        // rr  - random read advise provided
41
  NoFork,        // dc  - do not copy area on fork
42
  NoExpand,      // de  - do not expand area on remapping
43
  Accountable,   // ac  - area is accountable
44
  NotReserved,   // nr  - swap space is not reserved for the area
45
  HugeTLB,       // ht  - area uses huge tlb pages
46
  NonLinear,     // nl  - non-linear mapping
47
  ArchSpecific,  // ar  - architecture specific flag
48
  NoCore,        // dd  - do not include area into core dump
49
  SoftDirty,     // sd  - soft-dirty flag
50
  MixedMap,      // mm  - mixed map area
51
  HugePage,      // hg  - huge page advise flag
52
  NoHugePage,    // nh  - no-huge page advise flag
53
  Mergeable,     // mg  - mergeable advise flag
54
};
55
56
using VMFlagSet = EnumSet<VMFlag, uint32_t>;
57
58
class MemoryMapping final
59
{
60
public:
61
  enum class Perm : uint8_t
62
  {
63
    Read,
64
    Write,
65
    Execute,
66
    Shared,
67
    Private,
68
  };
69
70
  using PermSet = EnumSet<Perm>;
71
72
  MemoryMapping(uintptr_t aStart, uintptr_t aEnd,
73
                PermSet aPerms, size_t aOffset,
74
                const char* aName)
75
    : mStart(aStart)
76
    , mEnd(aEnd)
77
    , mOffset(aOffset)
78
    , mName(aName)
79
    , mPerms(aPerms)
80
0
  {}
81
82
0
  const nsCString& Name() const { return mName; }
83
84
0
  uintptr_t Start() const { return mStart; }
85
0
  uintptr_t End() const { return mEnd; }
86
87
  bool Includes(const void* aPtr) const
88
0
  {
89
0
    auto ptr = uintptr_t(aPtr);
90
0
    return ptr >= mStart && ptr < mEnd;
91
0
  }
92
93
0
  PermSet Perms() const { return mPerms; }
94
0
  VMFlagSet VMFlags() const { return mFlags; }
95
96
  // For file mappings, the offset in the mapped file which corresponds to the
97
  // start of the mapped region.
98
0
  size_t Offset() const { return mOffset; }
99
100
0
  size_t AnonHugePages() const { return mAnonHugePages; }
101
0
  size_t Anonymous() const { return mAnonymous; }
102
0
  size_t KernelPageSize() const { return mKernelPageSize; }
103
0
  size_t LazyFree() const { return mLazyFree; }
104
0
  size_t Locked() const { return mLocked; }
105
0
  size_t MMUPageSize() const { return mMMUPageSize; }
106
0
  size_t Private_Clean() const { return mPrivate_Clean; }
107
0
  size_t Private_Dirty() const { return mPrivate_Dirty; }
108
0
  size_t Private_Hugetlb() const { return mPrivate_Hugetlb; }
109
0
  size_t Pss() const { return mPss; }
110
0
  size_t Referenced() const { return mReferenced; }
111
0
  size_t Rss() const { return mRss; }
112
0
  size_t Shared_Clean() const { return mShared_Clean; }
113
0
  size_t Shared_Dirty() const { return mShared_Dirty; }
114
0
  size_t Shared_Hugetlb() const { return mShared_Hugetlb; }
115
0
  size_t ShmemPmdMapped() const { return mShmemPmdMapped; }
116
0
  size_t Size() const { return mSize; }
117
0
  size_t Swap() const { return mSwap; }
118
0
  size_t SwapPss() const { return mSwapPss; }
119
120
  // Dumps a string representation of the entry, similar to its format in the
121
  // smaps file, to the given string. Mainly useful for debugging.
122
  void Dump(nsACString& aOut) const;
123
124
  // These comparison operators are used for binary searching sorted arrays of
125
  // MemoryMapping entries to find the one which contains a given pointer.
126
0
  bool operator==(const void* aPtr) const { return Includes(aPtr); }
127
0
  bool operator<(const void* aPtr) const { return mStart < uintptr_t(aPtr); }
128
129
private:
130
  friend nsresult GetMemoryMappings(nsTArray<MemoryMapping>& aMappings);
131
132
  uintptr_t mStart = 0;
133
  uintptr_t mEnd = 0;
134
135
  size_t mOffset = 0;
136
137
  nsCString mName;
138
139
  // Members for size fields in the smaps file. Please keep these in sync with
140
  // the sFields array.
141
  size_t mAnonHugePages = 0;
142
  size_t mAnonymous = 0;
143
  size_t mKernelPageSize = 0;
144
  size_t mLazyFree = 0;
145
  size_t mLocked = 0;
146
  size_t mMMUPageSize = 0;
147
  size_t mPrivate_Clean = 0;
148
  size_t mPrivate_Dirty = 0;
149
  size_t mPrivate_Hugetlb = 0;
150
  size_t mPss = 0;
151
  size_t mReferenced = 0;
152
  size_t mRss = 0;
153
  size_t mShared_Clean = 0;
154
  size_t mShared_Dirty = 0;
155
  size_t mShared_Hugetlb = 0;
156
  size_t mShmemPmdMapped = 0;
157
  size_t mSize = 0;
158
  size_t mSwap = 0;
159
  size_t mSwapPss = 0;
160
161
  PermSet mPerms{};
162
  VMFlagSet mFlags{};
163
164
  // Contains the name and offset of one of the above size_t fields, for use in
165
  // parsing in dumping. The below helpers contain a list of the fields, and map
166
  // Field entries to the appropriate member in a class instance.
167
  struct Field
168
  {
169
    const char* mName;
170
    size_t mOffset;
171
  };
172
173
  static const Field sFields[20];
174
175
  size_t& ValueForField(const Field& aField)
176
0
  {
177
0
    char* fieldPtr = reinterpret_cast<char*>(this) + aField.mOffset;
178
0
    return reinterpret_cast<size_t*>(fieldPtr)[0];
179
0
  }
180
  size_t ValueForField(const Field& aField) const
181
0
  {
182
0
    return const_cast<MemoryMapping*>(this)->ValueForField(aField);
183
0
  }
184
};
185
186
nsresult GetMemoryMappings(nsTArray<MemoryMapping>& aMappings);
187
188
} // namespace mozilla
189
190
#endif // mozilla_MemoryMapping_h