1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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 BASE_PROFILER_SHARED_LIBRARIES_H_
8 #define BASE_PROFILER_SHARED_LIBRARIES_H_
9 
10 #include "BaseProfiler.h"
11 
12 #ifndef MOZ_GECKO_PROFILER
13 #  error Do not #include this header when MOZ_GECKO_PROFILER is not #defined.
14 #endif
15 
16 #include <algorithm>
17 #include <stdint.h>
18 #include <stdlib.h>
19 #include <string>
20 #include <vector>
21 
22 class SharedLibrary {
23  public:
SharedLibrary(uintptr_t aStart,uintptr_t aEnd,uintptr_t aOffset,const std::string & aBreakpadId,const std::string & aModuleName,const std::string & aModulePath,const std::string & aDebugName,const std::string & aDebugPath,const std::string & aVersion,const char * aArch)24   SharedLibrary(uintptr_t aStart, uintptr_t aEnd, uintptr_t aOffset,
25                 const std::string& aBreakpadId, const std::string& aModuleName,
26                 const std::string& aModulePath, const std::string& aDebugName,
27                 const std::string& aDebugPath, const std::string& aVersion,
28                 const char* aArch)
29       : mStart(aStart),
30         mEnd(aEnd),
31         mOffset(aOffset),
32         mBreakpadId(aBreakpadId),
33         mModuleName(aModuleName),
34         mModulePath(aModulePath),
35         mDebugName(aDebugName),
36         mDebugPath(aDebugPath),
37         mVersion(aVersion),
38         mArch(aArch) {}
39 
SharedLibrary(const SharedLibrary & aEntry)40   SharedLibrary(const SharedLibrary& aEntry)
41       : mStart(aEntry.mStart),
42         mEnd(aEntry.mEnd),
43         mOffset(aEntry.mOffset),
44         mBreakpadId(aEntry.mBreakpadId),
45         mModuleName(aEntry.mModuleName),
46         mModulePath(aEntry.mModulePath),
47         mDebugName(aEntry.mDebugName),
48         mDebugPath(aEntry.mDebugPath),
49         mVersion(aEntry.mVersion),
50         mArch(aEntry.mArch) {}
51 
52   SharedLibrary& operator=(const SharedLibrary& aEntry) {
53     // Gracefully handle self assignment
54     if (this == &aEntry) return *this;
55 
56     mStart = aEntry.mStart;
57     mEnd = aEntry.mEnd;
58     mOffset = aEntry.mOffset;
59     mBreakpadId = aEntry.mBreakpadId;
60     mModuleName = aEntry.mModuleName;
61     mModulePath = aEntry.mModulePath;
62     mDebugName = aEntry.mDebugName;
63     mDebugPath = aEntry.mDebugPath;
64     mVersion = aEntry.mVersion;
65     mArch = aEntry.mArch;
66     return *this;
67   }
68 
69   bool operator==(const SharedLibrary& other) const {
70     return (mStart == other.mStart) && (mEnd == other.mEnd) &&
71            (mOffset == other.mOffset) && (mModuleName == other.mModuleName) &&
72            (mModulePath == other.mModulePath) &&
73            (mDebugName == other.mDebugName) &&
74            (mDebugPath == other.mDebugPath) &&
75            (mBreakpadId == other.mBreakpadId) && (mVersion == other.mVersion) &&
76            (mArch == other.mArch);
77   }
78 
GetStart()79   uintptr_t GetStart() const { return mStart; }
GetEnd()80   uintptr_t GetEnd() const { return mEnd; }
GetOffset()81   uintptr_t GetOffset() const { return mOffset; }
GetBreakpadId()82   const std::string& GetBreakpadId() const { return mBreakpadId; }
GetModuleName()83   const std::string& GetModuleName() const { return mModuleName; }
GetModulePath()84   const std::string& GetModulePath() const { return mModulePath; }
GetDebugName()85   const std::string& GetDebugName() const { return mDebugName; }
GetDebugPath()86   const std::string& GetDebugPath() const { return mDebugPath; }
GetVersion()87   const std::string& GetVersion() const { return mVersion; }
GetArch()88   const std::string& GetArch() const { return mArch; }
89 
90  private:
SharedLibrary()91   SharedLibrary() : mStart{0}, mEnd{0}, mOffset{0} {}
92 
93   uintptr_t mStart;
94   uintptr_t mEnd;
95   uintptr_t mOffset;
96   std::string mBreakpadId;
97   std::string mModuleName;
98   std::string mModulePath;
99   std::string mDebugName;
100   std::string mDebugPath;
101   std::string mVersion;
102   std::string mArch;
103 };
104 
CompareAddresses(const SharedLibrary & first,const SharedLibrary & second)105 static bool CompareAddresses(const SharedLibrary& first,
106                              const SharedLibrary& second) {
107   return first.GetStart() < second.GetStart();
108 }
109 
110 class SharedLibraryInfo {
111  public:
112   static SharedLibraryInfo GetInfoForSelf();
113   static void Initialize();
114 
SharedLibraryInfo()115   SharedLibraryInfo() {}
116 
AddSharedLibrary(SharedLibrary entry)117   void AddSharedLibrary(SharedLibrary entry) { mEntries.push_back(entry); }
118 
GetEntry(size_t i)119   const SharedLibrary& GetEntry(size_t i) const { return mEntries[i]; }
120 
GetMutableEntry(size_t i)121   SharedLibrary& GetMutableEntry(size_t i) { return mEntries[i]; }
122 
123   // Removes items in the range [first, last)
124   // i.e. element at the "last" index is not removed
RemoveEntries(size_t first,size_t last)125   void RemoveEntries(size_t first, size_t last) {
126     mEntries.erase(mEntries.begin() + first, mEntries.begin() + last);
127   }
128 
Contains(const SharedLibrary & searchItem)129   bool Contains(const SharedLibrary& searchItem) const {
130     return (mEntries.end() !=
131             std::find(mEntries.begin(), mEntries.end(), searchItem));
132   }
133 
GetSize()134   size_t GetSize() const { return mEntries.size(); }
135 
SortByAddress()136   void SortByAddress() {
137     std::sort(mEntries.begin(), mEntries.end(), CompareAddresses);
138   }
139 
Clear()140   void Clear() { mEntries.clear(); }
141 
142  private:
143   std::vector<SharedLibrary> mEntries;
144 };
145 
146 #endif  // BASE_PROFILER_SHARED_LIBRARIES_H_
147