Mercurial > hg > CbC > CbC_llvm
view tools/dsymutil/BinaryHolder.h @ 147:c2174574ed3a
LLVM 10
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 16:55:33 +0900 |
parents | 1172e4bd9c6f |
children |
line wrap: on
line source
//===-- BinaryHolder.h - Utility class for accessing binaries -------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This program is a utility that aims to be a dropin replacement for // Darwin's dsymutil. // //===----------------------------------------------------------------------===// #ifndef LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H #define LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Triple.h" #include "llvm/Object/Archive.h" #include "llvm/Object/Error.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/Errc.h" #include "llvm/Support/ErrorOr.h" #include <mutex> namespace llvm { namespace dsymutil { /// The BinaryHolder class is responsible for creating and owning /// ObjectFiles and their underlying MemoryBuffers. It differs from a simple /// OwningBinary in that it handles accessing and caching of archives and its /// members. class BinaryHolder { public: using TimestampTy = sys::TimePoint<std::chrono::seconds>; BinaryHolder(bool Verbose = false) : Verbose(Verbose) {} // Forward declarations for friend declaration. class ObjectEntry; class ArchiveEntry; /// Base class shared by cached entries, representing objects and archives. class EntryBase { protected: std::unique_ptr<MemoryBuffer> MemBuffer; std::unique_ptr<object::MachOUniversalBinary> FatBinary; std::string FatBinaryName; }; /// Cached entry holding one or more (in case of a fat binary) object files. class ObjectEntry : public EntryBase { public: /// Load the given object binary in memory. Error load(StringRef Filename, bool Verbose = false); /// Access all owned ObjectFiles. std::vector<const object::ObjectFile *> getObjects() const; /// Access to a derived version of all the currently owned ObjectFiles. The /// conversion might be invalid, in which case an Error is returned. template <typename ObjectFileType> Expected<std::vector<const ObjectFileType *>> getObjectsAs() const { std::vector<const ObjectFileType *> Result; Result.reserve(Objects.size()); for (auto &Object : Objects) { const auto *Derived = dyn_cast<ObjectFileType>(Object.get()); if (!Derived) return errorCodeToError(object::object_error::invalid_file_type); Result.push_back(Derived); } return Result; } /// Access the owned ObjectFile with architecture \p T. Expected<const object::ObjectFile &> getObject(const Triple &T) const; /// Access to a derived version of the currently owned ObjectFile with /// architecture \p T. The conversion must be known to be valid. template <typename ObjectFileType> Expected<const ObjectFileType &> getObjectAs(const Triple &T) const { auto Object = getObject(T); if (!Object) return Object.takeError(); return cast<ObjectFileType>(*Object); } private: std::vector<std::unique_ptr<object::ObjectFile>> Objects; friend ArchiveEntry; }; /// Cached entry holding one or more (in the of a fat binary) archive files. class ArchiveEntry : public EntryBase { public: struct KeyTy { std::string Filename; TimestampTy Timestamp; KeyTy() : Filename(), Timestamp() {} KeyTy(StringRef Filename, TimestampTy Timestamp) : Filename(Filename.str()), Timestamp(Timestamp) {} }; /// Load the given object binary in memory. Error load(StringRef Filename, TimestampTy Timestamp, bool Verbose = false); Expected<const ObjectEntry &> getObjectEntry(StringRef Filename, TimestampTy Timestamp, bool Verbose = false); private: std::vector<std::unique_ptr<object::Archive>> Archives; DenseMap<KeyTy, ObjectEntry> MemberCache; std::mutex MemberCacheMutex; }; Expected<const ObjectEntry &> getObjectEntry(StringRef Filename, TimestampTy Timestamp = TimestampTy()); void clear(); private: /// Cache of static archives. Objects that are part of a static archive are /// stored under this object, rather than in the map below. StringMap<ArchiveEntry> ArchiveCache; std::mutex ArchiveCacheMutex; /// Object entries for objects that are not in a static archive. StringMap<ObjectEntry> ObjectCache; std::mutex ObjectCacheMutex; bool Verbose; }; } // namespace dsymutil template <> struct DenseMapInfo<dsymutil::BinaryHolder::ArchiveEntry::KeyTy> { static inline dsymutil::BinaryHolder::ArchiveEntry::KeyTy getEmptyKey() { return dsymutil::BinaryHolder::ArchiveEntry::KeyTy(); } static inline dsymutil::BinaryHolder::ArchiveEntry::KeyTy getTombstoneKey() { return dsymutil::BinaryHolder::ArchiveEntry::KeyTy("/", {}); } static unsigned getHashValue(const dsymutil::BinaryHolder::ArchiveEntry::KeyTy &K) { return hash_combine(DenseMapInfo<StringRef>::getHashValue(K.Filename), DenseMapInfo<unsigned>::getHashValue( K.Timestamp.time_since_epoch().count())); } static bool isEqual(const dsymutil::BinaryHolder::ArchiveEntry::KeyTy &LHS, const dsymutil::BinaryHolder::ArchiveEntry::KeyTy &RHS) { return LHS.Filename == RHS.Filename && LHS.Timestamp == RHS.Timestamp; } }; } // namespace llvm #endif