tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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_