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