SharedLibraries.h (6537B)
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 #include "mozilla/BaseProfiler.h" 11 12 #include <algorithm> 13 #include <stdint.h> 14 #include <string> 15 #include <vector> 16 #include <tuple> 17 18 namespace IPC { 19 template <typename T> 20 struct ParamTraits; 21 } // namespace IPC 22 23 class SharedLibrary { 24 public: 25 SharedLibrary(uintptr_t aStart, uintptr_t aEnd, uintptr_t aOffset, 26 const std::string& aBreakpadId, const std::string& aCodeId, 27 const std::string& aModuleName, const std::string& aModulePath, 28 const std::string& aDebugName, const std::string& aDebugPath, 29 const std::string& aVersion, const char* aArch) 30 : mStart(aStart), 31 mEnd(aEnd), 32 mOffset(aOffset), 33 mBreakpadId(aBreakpadId), 34 mCodeId(aCodeId), 35 mModuleName(aModuleName), 36 mModulePath(aModulePath), 37 mDebugName(aDebugName), 38 mDebugPath(aDebugPath), 39 mVersion(aVersion), 40 mArch(aArch) {} 41 42 bool operator==(const SharedLibrary& other) const { 43 return (mStart == other.mStart) && (mEnd == other.mEnd) && 44 (mOffset == other.mOffset) && (mModuleName == other.mModuleName) && 45 (mModulePath == other.mModulePath) && 46 (mDebugName == other.mDebugName) && 47 (mDebugPath == other.mDebugPath) && 48 (mBreakpadId == other.mBreakpadId) && (mCodeId == other.mCodeId) && 49 (mVersion == other.mVersion) && (mArch == other.mArch); 50 } 51 52 uintptr_t GetStart() const { return mStart; } 53 uintptr_t GetEnd() const { return mEnd; } 54 uintptr_t GetOffset() const { return mOffset; } 55 const std::string& GetBreakpadId() const { return mBreakpadId; } 56 const std::string& GetCodeId() const { return mCodeId; } 57 const std::string& GetModuleName() const { return mModuleName; } 58 const std::string& GetModulePath() const { return mModulePath; } 59 const std::string& GetDebugName() const { return mDebugName; } 60 const std::string& GetDebugPath() const { return mDebugPath; } 61 const std::string& GetVersion() const { return mVersion; } 62 const std::string& GetArch() const { return mArch; } 63 size_t SizeOf() const { 64 return sizeof *this + mBreakpadId.length() + mCodeId.length() + 65 mModuleName.length() + mModulePath.length() + mDebugName.length() + 66 mDebugPath.length() + mVersion.length() + mArch.size(); 67 } 68 69 SharedLibrary() : mStart{0}, mEnd{0}, mOffset{0} {} 70 71 private: 72 uintptr_t mStart; 73 uintptr_t mEnd; 74 uintptr_t mOffset; 75 std::string mBreakpadId; 76 // A string carrying an identifier for a binary. 77 // 78 // All platforms have different formats: 79 // - Windows: The code ID for a Windows PE file. 80 // It's the PE timestamp and PE image size. 81 // - macOS: The code ID for a macOS / iOS binary (mach-O). 82 // It's the mach-O UUID without dashes and without the trailing 0 for the 83 // breakpad ID. 84 // - Linux/Android: The code ID for a Linux ELF file. 85 // It's the complete build ID, as hex string. 86 std::string mCodeId; 87 std::string mModuleName; 88 std::string mModulePath; 89 std::string mDebugName; 90 std::string mDebugPath; 91 std::string mVersion; 92 std::string mArch; 93 94 friend struct IPC::ParamTraits<SharedLibrary>; 95 }; 96 97 static bool CompareAddresses(const SharedLibrary& first, 98 const SharedLibrary& second) { 99 return first.GetStart() < second.GetStart(); 100 } 101 102 class SharedLibraryInfo { 103 public: 104 #ifdef MOZ_GECKO_PROFILER 105 MFBT_API static SharedLibraryInfo GetInfoForSelf(); 106 # ifdef XP_WIN 107 MFBT_API static SharedLibraryInfo GetInfoFromPath(const wchar_t* aPath); 108 # endif 109 110 MFBT_API static void Initialize(); 111 #else 112 static SharedLibraryInfo GetInfoForSelf() { return SharedLibraryInfo(); } 113 # ifdef XP_WIN 114 static SharedLibraryInfo GetInfoFromPath(const wchar_t* aPath) { 115 return SharedLibraryInfo(); 116 } 117 # endif 118 119 static void Initialize() {} 120 #endif 121 122 void AddSharedLibrary(SharedLibrary entry) { mEntries.push_back(entry); } 123 124 void AddAllSharedLibraries(const SharedLibraryInfo& sharedLibraryInfo) { 125 mEntries.insert(mEntries.end(), sharedLibraryInfo.mEntries.begin(), 126 sharedLibraryInfo.mEntries.end()); 127 } 128 129 const SharedLibrary& GetEntry(size_t i) const { return mEntries[i]; } 130 131 SharedLibrary& GetMutableEntry(size_t i) { return mEntries[i]; } 132 133 // Removes items in the range [first, last) 134 // i.e. element at the "last" index is not removed 135 void RemoveEntries(size_t first, size_t last) { 136 mEntries.erase(mEntries.begin() + first, mEntries.begin() + last); 137 } 138 139 bool Contains(const SharedLibrary& searchItem) const { 140 return (mEntries.end() != 141 std::find(mEntries.begin(), mEntries.end(), searchItem)); 142 } 143 144 size_t GetSize() const { return mEntries.size(); } 145 146 void SortByAddress() { 147 std::sort(mEntries.begin(), mEntries.end(), CompareAddresses); 148 } 149 150 // Remove duplicate entries from the vector. 151 // 152 // We purposefully don't use the operator== implementation of SharedLibrary 153 // because it compares all the fields including mStart, mEnd and mOffset which 154 // are not the same across different processes. 155 void DeduplicateEntries() { 156 static auto cmpSort = [](const SharedLibrary& a, const SharedLibrary& b) { 157 return std::tie(a.GetModuleName(), a.GetBreakpadId()) < 158 std::tie(b.GetModuleName(), b.GetBreakpadId()); 159 }; 160 static auto cmpEqual = [](const SharedLibrary& a, const SharedLibrary& b) { 161 return std::tie(a.GetModuleName(), a.GetBreakpadId()) == 162 std::tie(b.GetModuleName(), b.GetBreakpadId()); 163 }; 164 // std::unique requires the vector to be sorted first. It can only remove 165 // consecutive duplicate elements. 166 std::sort(mEntries.begin(), mEntries.end(), cmpSort); 167 // Remove the duplicates since it's sorted now. 168 mEntries.erase(std::unique(mEntries.begin(), mEntries.end(), cmpEqual), 169 mEntries.end()); 170 } 171 172 void Clear() { mEntries.clear(); } 173 174 size_t SizeOf() const { 175 size_t size = 0; 176 177 for (const auto& item : mEntries) { 178 size += item.SizeOf(); 179 } 180 181 return size; 182 } 183 184 private: 185 std::vector<SharedLibrary> mEntries; 186 187 friend struct IPC::ParamTraits<SharedLibraryInfo>; 188 }; 189 190 #endif // SHARED_LIBRARIES_H_