BinaryHolder.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //===-- BinaryHolder.h - Utility class for accessing binaries -------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This program is a utility that aims to be a dropin replacement for
  11. // Darwin's dsymutil.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H
  15. #define LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H
  16. #include "llvm/Object/Archive.h"
  17. #include "llvm/Object/Error.h"
  18. #include "llvm/Object/ObjectFile.h"
  19. #include "llvm/Support/Errc.h"
  20. #include "llvm/Support/ErrorOr.h"
  21. namespace llvm {
  22. namespace dsymutil {
  23. /// \brief The BinaryHolder class is responsible for creating and
  24. /// owning ObjectFile objects and their underlying MemoryBuffer. This
  25. /// is different from a simple OwningBinary in that it handles
  26. /// accessing to archive members.
  27. ///
  28. /// As an optimization, this class will reuse an already mapped and
  29. /// parsed Archive object if 2 successive requests target the same
  30. /// archive file (Which is always the case in debug maps).
  31. /// Currently it only owns one memory buffer at any given time,
  32. /// meaning that a mapping request will invalidate the previous memory
  33. /// mapping.
  34. class BinaryHolder {
  35. std::unique_ptr<object::Archive> CurrentArchive;
  36. std::unique_ptr<MemoryBuffer> CurrentMemoryBuffer;
  37. std::unique_ptr<object::ObjectFile> CurrentObjectFile;
  38. bool Verbose;
  39. /// \brief Get the MemoryBufferRef for the file specification in \p
  40. /// Filename from the current archive.
  41. ///
  42. /// This function performs no system calls, it just looks up a
  43. /// potential match for the given \p Filename in the currently
  44. /// mapped archive if there is one.
  45. ErrorOr<MemoryBufferRef> GetArchiveMemberBuffer(StringRef Filename);
  46. /// \brief Interpret Filename as an archive member specification,
  47. /// map the corresponding archive to memory and return the
  48. /// MemoryBufferRef corresponding to the described member.
  49. ErrorOr<MemoryBufferRef> MapArchiveAndGetMemberBuffer(StringRef Filename);
  50. /// \brief Return the MemoryBufferRef that holds the memory
  51. /// mapping for the given \p Filename. This function will try to
  52. /// parse archive member specifications of the form
  53. /// /path/to/archive.a(member.o).
  54. ///
  55. /// The returned MemoryBufferRef points to a buffer owned by this
  56. /// object. The buffer is valid until the next call to
  57. /// GetMemoryBufferForFile() on this object.
  58. ErrorOr<MemoryBufferRef> GetMemoryBufferForFile(StringRef Filename);
  59. public:
  60. BinaryHolder(bool Verbose) : Verbose(Verbose) {}
  61. /// \brief Get the ObjectFile designated by the \p Filename. This
  62. /// might be an archive member specification of the form
  63. /// /path/to/archive.a(member.o).
  64. ///
  65. /// Calling this function invalidates the previous mapping owned by
  66. /// the BinaryHolder.
  67. ErrorOr<const object::ObjectFile &> GetObjectFile(StringRef Filename);
  68. /// \brief Wraps GetObjectFile() to return a derived ObjectFile type.
  69. template <typename ObjectFileType>
  70. ErrorOr<const ObjectFileType &> GetFileAs(StringRef Filename) {
  71. auto ErrOrObjFile = GetObjectFile(Filename);
  72. if (auto Err = ErrOrObjFile.getError())
  73. return Err;
  74. if (const auto *Derived = dyn_cast<ObjectFileType>(CurrentObjectFile.get()))
  75. return *Derived;
  76. return make_error_code(object::object_error::invalid_file_type);
  77. }
  78. /// \brief Access the currently owned ObjectFile. As successfull
  79. /// call to GetObjectFile() or GetFileAs() must have been performed
  80. /// before calling this.
  81. const object::ObjectFile &Get() {
  82. assert(CurrentObjectFile);
  83. return *CurrentObjectFile;
  84. }
  85. /// \brief Access to a derived version of the currently owned
  86. /// ObjectFile. The conversion must be known to be valid.
  87. template <typename ObjectFileType> const ObjectFileType &GetAs() {
  88. return cast<ObjectFileType>(*CurrentObjectFile);
  89. }
  90. };
  91. }
  92. }
  93. #endif