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