Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

619 lines
21 KiB

  1. //===- ObjectFile.h - File format independent object file -------*- C++ -*-===//
  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 file declares a file format independent ObjectFile class.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_OBJECT_OBJECTFILE_H
  14. #define LLVM_OBJECT_OBJECTFILE_H
  15. #include "llvm/ADT/StringRef.h"
  16. #include "llvm/Object/Binary.h"
  17. #include "llvm/Support/DataTypes.h"
  18. #include "llvm/Support/ErrorHandling.h"
  19. #include "llvm/Support/MemoryBuffer.h"
  20. #include <cstring>
  21. #include <vector>
  22. namespace llvm {
  23. namespace object {
  24. class ObjectFile;
  25. union DataRefImpl {
  26. struct {
  27. // ELF needs this for relocations. This entire union should probably be a
  28. // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
  29. uint16_t a, b;
  30. uint32_t c;
  31. } w;
  32. struct {
  33. uint32_t a, b;
  34. } d;
  35. uintptr_t p;
  36. DataRefImpl() {
  37. std::memset(this, 0, sizeof(DataRefImpl));
  38. }
  39. };
  40. template<class content_type>
  41. class content_iterator {
  42. content_type Current;
  43. public:
  44. content_iterator(content_type symb)
  45. : Current(symb) {}
  46. const content_type* operator->() const {
  47. return &Current;
  48. }
  49. const content_type &operator*() const {
  50. return Current;
  51. }
  52. bool operator==(const content_iterator &other) const {
  53. return Current == other.Current;
  54. }
  55. bool operator!=(const content_iterator &other) const {
  56. return !(*this == other);
  57. }
  58. content_iterator& increment(error_code &err) {
  59. content_type next;
  60. if (error_code ec = Current.getNext(next))
  61. err = ec;
  62. else
  63. Current = next;
  64. return *this;
  65. }
  66. };
  67. inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
  68. // Check bitwise identical. This is the only legal way to compare a union w/o
  69. // knowing which member is in use.
  70. return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
  71. }
  72. inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
  73. // Check bitwise identical. This is the only legal way to compare a union w/o
  74. // knowing which member is in use.
  75. return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
  76. }
  77. class SymbolRef;
  78. /// RelocationRef - This is a value type class that represents a single
  79. /// relocation in the list of relocations in the object file.
  80. class RelocationRef {
  81. DataRefImpl RelocationPimpl;
  82. const ObjectFile *OwningObject;
  83. public:
  84. RelocationRef() : OwningObject(NULL) { }
  85. RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
  86. bool operator==(const RelocationRef &Other) const;
  87. error_code getNext(RelocationRef &Result) const;
  88. error_code getAddress(uint64_t &Result) const;
  89. error_code getOffset(uint64_t &Result) const;
  90. error_code getSymbol(SymbolRef &Result) const;
  91. error_code getType(uint64_t &Result) const;
  92. /// @brief Indicates whether this relocation should hidden when listing
  93. /// relocations, usually because it is the trailing part of a multipart
  94. /// relocation that will be printed as part of the leading relocation.
  95. error_code getHidden(bool &Result) const;
  96. /// @brief Get a string that represents the type of this relocation.
  97. ///
  98. /// This is for display purposes only.
  99. error_code getTypeName(SmallVectorImpl<char> &Result) const;
  100. error_code getAdditionalInfo(int64_t &Result) const;
  101. /// @brief Get a string that represents the calculation of the value of this
  102. /// relocation.
  103. ///
  104. /// This is for display purposes only.
  105. error_code getValueString(SmallVectorImpl<char> &Result) const;
  106. DataRefImpl getRawDataRefImpl() const;
  107. };
  108. typedef content_iterator<RelocationRef> relocation_iterator;
  109. /// SectionRef - This is a value type class that represents a single section in
  110. /// the list of sections in the object file.
  111. class SectionRef {
  112. friend class SymbolRef;
  113. DataRefImpl SectionPimpl;
  114. const ObjectFile *OwningObject;
  115. public:
  116. SectionRef() : OwningObject(NULL) { }
  117. SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
  118. bool operator==(const SectionRef &Other) const;
  119. bool operator<(const SectionRef &Other) const;
  120. error_code getNext(SectionRef &Result) const;
  121. error_code getName(StringRef &Result) const;
  122. error_code getAddress(uint64_t &Result) const;
  123. error_code getSize(uint64_t &Result) const;
  124. error_code getContents(StringRef &Result) const;
  125. /// @brief Get the alignment of this section as the actual value (not log 2).
  126. error_code getAlignment(uint64_t &Result) const;
  127. // FIXME: Move to the normalization layer when it's created.
  128. error_code isText(bool &Result) const;
  129. error_code isData(bool &Result) const;
  130. error_code isBSS(bool &Result) const;
  131. error_code isRequiredForExecution(bool &Result) const;
  132. error_code isVirtual(bool &Result) const;
  133. error_code isZeroInit(bool &Result) const;
  134. error_code isReadOnlyData(bool &Result) const;
  135. error_code containsSymbol(SymbolRef S, bool &Result) const;
  136. relocation_iterator begin_relocations() const;
  137. relocation_iterator end_relocations() const;
  138. DataRefImpl getRawDataRefImpl() const;
  139. };
  140. typedef content_iterator<SectionRef> section_iterator;
  141. /// SymbolRef - This is a value type class that represents a single symbol in
  142. /// the list of symbols in the object file.
  143. class SymbolRef {
  144. friend class SectionRef;
  145. DataRefImpl SymbolPimpl;
  146. const ObjectFile *OwningObject;
  147. public:
  148. SymbolRef() : OwningObject(NULL) { }
  149. enum Type {
  150. ST_Unknown, // Type not specified
  151. ST_Data,
  152. ST_Debug,
  153. ST_File,
  154. ST_Function,
  155. ST_Other
  156. };
  157. enum Flags {
  158. SF_None = 0,
  159. SF_Undefined = 1U << 0, // Symbol is defined in another object file
  160. SF_Global = 1U << 1, // Global symbol
  161. SF_Weak = 1U << 2, // Weak symbol
  162. SF_Absolute = 1U << 3, // Absolute symbol
  163. SF_ThreadLocal = 1U << 4, // Thread local symbol
  164. SF_Common = 1U << 5, // Symbol has common linkage
  165. SF_FormatSpecific = 1U << 31 // Specific to the object file format
  166. // (e.g. section symbols)
  167. };
  168. SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
  169. bool operator==(const SymbolRef &Other) const;
  170. bool operator<(const SymbolRef &Other) const;
  171. error_code getNext(SymbolRef &Result) const;
  172. error_code getName(StringRef &Result) const;
  173. /// Returns the symbol virtual address (i.e. address at which it will be
  174. /// mapped).
  175. error_code getAddress(uint64_t &Result) const;
  176. error_code getFileOffset(uint64_t &Result) const;
  177. error_code getSize(uint64_t &Result) const;
  178. error_code getType(SymbolRef::Type &Result) const;
  179. /// Returns the ascii char that should be displayed in a symbol table dump via
  180. /// nm for this symbol.
  181. error_code getNMTypeChar(char &Result) const;
  182. /// Get symbol flags (bitwise OR of SymbolRef::Flags)
  183. error_code getFlags(uint32_t &Result) const;
  184. /// @brief Return true for common symbols such as uninitialized globals
  185. error_code isCommon(bool &Result) const;
  186. /// @brief Get section this symbol is defined in reference to. Result is
  187. /// end_sections() if it is undefined or is an absolute symbol.
  188. error_code getSection(section_iterator &Result) const;
  189. /// @brief Get value of the symbol in the symbol table.
  190. error_code getValue(uint64_t &Val) const;
  191. DataRefImpl getRawDataRefImpl() const;
  192. };
  193. typedef content_iterator<SymbolRef> symbol_iterator;
  194. /// LibraryRef - This is a value type class that represents a single library in
  195. /// the list of libraries needed by a shared or dynamic object.
  196. class LibraryRef {
  197. friend class SectionRef;
  198. DataRefImpl LibraryPimpl;
  199. const ObjectFile *OwningObject;
  200. public:
  201. LibraryRef() : OwningObject(NULL) { }
  202. LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner);
  203. bool operator==(const LibraryRef &Other) const;
  204. bool operator<(const LibraryRef &Other) const;
  205. error_code getNext(LibraryRef &Result) const;
  206. // Get the path to this library, as stored in the object file.
  207. error_code getPath(StringRef &Result) const;
  208. DataRefImpl getRawDataRefImpl() const;
  209. };
  210. typedef content_iterator<LibraryRef> library_iterator;
  211. const uint64_t UnknownAddressOrSize = ~0ULL;
  212. /// ObjectFile - This class is the base class for all object file types.
  213. /// Concrete instances of this object are created by createObjectFile, which
  214. /// figures out which type to create.
  215. class ObjectFile : public Binary {
  216. virtual void anchor();
  217. ObjectFile() LLVM_DELETED_FUNCTION;
  218. ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
  219. protected:
  220. ObjectFile(unsigned int Type, MemoryBuffer *source);
  221. const uint8_t *base() const {
  222. return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
  223. }
  224. // These functions are for SymbolRef to call internally. The main goal of
  225. // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
  226. // entry in the memory mapped object file. SymbolPimpl cannot contain any
  227. // virtual functions because then it could not point into the memory mapped
  228. // file.
  229. //
  230. // Implementations assume that the DataRefImpl is valid and has not been
  231. // modified externally. It's UB otherwise.
  232. friend class SymbolRef;
  233. virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0;
  234. virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
  235. virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0;
  236. virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res)const=0;
  237. virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
  238. virtual error_code getSymbolType(DataRefImpl Symb,
  239. SymbolRef::Type &Res) const = 0;
  240. virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0;
  241. virtual error_code getSymbolFlags(DataRefImpl Symb,
  242. uint32_t &Res) const = 0;
  243. virtual error_code getSymbolSection(DataRefImpl Symb,
  244. section_iterator &Res) const = 0;
  245. virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const = 0;
  246. // Same as above for SectionRef.
  247. friend class SectionRef;
  248. virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0;
  249. virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0;
  250. virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0;
  251. virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0;
  252. virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0;
  253. virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res)const=0;
  254. virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
  255. virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0;
  256. virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0;
  257. virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
  258. bool &Res) const = 0;
  259. // A section is 'virtual' if its contents aren't present in the object image.
  260. virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const = 0;
  261. virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const = 0;
  262. virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const =0;
  263. virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
  264. bool &Result) const = 0;
  265. virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const = 0;
  266. virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const = 0;
  267. // Same as above for RelocationRef.
  268. friend class RelocationRef;
  269. virtual error_code getRelocationNext(DataRefImpl Rel,
  270. RelocationRef &Res) const = 0;
  271. virtual error_code getRelocationAddress(DataRefImpl Rel,
  272. uint64_t &Res) const =0;
  273. virtual error_code getRelocationOffset(DataRefImpl Rel,
  274. uint64_t &Res) const =0;
  275. virtual error_code getRelocationSymbol(DataRefImpl Rel,
  276. SymbolRef &Res) const = 0;
  277. virtual error_code getRelocationType(DataRefImpl Rel,
  278. uint64_t &Res) const = 0;
  279. virtual error_code getRelocationTypeName(DataRefImpl Rel,
  280. SmallVectorImpl<char> &Result) const = 0;
  281. virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
  282. int64_t &Res) const = 0;
  283. virtual error_code getRelocationValueString(DataRefImpl Rel,
  284. SmallVectorImpl<char> &Result) const = 0;
  285. virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const {
  286. Result = false;
  287. return object_error::success;
  288. }
  289. // Same for LibraryRef
  290. friend class LibraryRef;
  291. virtual error_code getLibraryNext(DataRefImpl Lib, LibraryRef &Res) const = 0;
  292. virtual error_code getLibraryPath(DataRefImpl Lib, StringRef &Res) const = 0;
  293. public:
  294. virtual symbol_iterator begin_symbols() const = 0;
  295. virtual symbol_iterator end_symbols() const = 0;
  296. virtual symbol_iterator begin_dynamic_symbols() const = 0;
  297. virtual symbol_iterator end_dynamic_symbols() const = 0;
  298. virtual section_iterator begin_sections() const = 0;
  299. virtual section_iterator end_sections() const = 0;
  300. virtual library_iterator begin_libraries_needed() const = 0;
  301. virtual library_iterator end_libraries_needed() const = 0;
  302. /// @brief The number of bytes used to represent an address in this object
  303. /// file format.
  304. virtual uint8_t getBytesInAddress() const = 0;
  305. virtual StringRef getFileFormatName() const = 0;
  306. virtual /* Triple::ArchType */ unsigned getArch() const = 0;
  307. /// For shared objects, returns the name which this object should be
  308. /// loaded from at runtime. This corresponds to DT_SONAME on ELF and
  309. /// LC_ID_DYLIB (install name) on MachO.
  310. virtual StringRef getLoadName() const = 0;
  311. /// @returns Pointer to ObjectFile subclass to handle this type of object.
  312. /// @param ObjectPath The path to the object file. ObjectPath.isObject must
  313. /// return true.
  314. /// @brief Create ObjectFile from path.
  315. static ObjectFile *createObjectFile(StringRef ObjectPath);
  316. static ObjectFile *createObjectFile(MemoryBuffer *Object);
  317. static inline bool classof(const Binary *v) {
  318. return v->isObject();
  319. }
  320. public:
  321. static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
  322. static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
  323. static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
  324. };
  325. // Inline function definitions.
  326. inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
  327. : SymbolPimpl(SymbolP)
  328. , OwningObject(Owner) {}
  329. inline bool SymbolRef::operator==(const SymbolRef &Other) const {
  330. return SymbolPimpl == Other.SymbolPimpl;
  331. }
  332. inline bool SymbolRef::operator<(const SymbolRef &Other) const {
  333. return SymbolPimpl < Other.SymbolPimpl;
  334. }
  335. inline error_code SymbolRef::getNext(SymbolRef &Result) const {
  336. return OwningObject->getSymbolNext(SymbolPimpl, Result);
  337. }
  338. inline error_code SymbolRef::getName(StringRef &Result) const {
  339. return OwningObject->getSymbolName(SymbolPimpl, Result);
  340. }
  341. inline error_code SymbolRef::getAddress(uint64_t &Result) const {
  342. return OwningObject->getSymbolAddress(SymbolPimpl, Result);
  343. }
  344. inline error_code SymbolRef::getFileOffset(uint64_t &Result) const {
  345. return OwningObject->getSymbolFileOffset(SymbolPimpl, Result);
  346. }
  347. inline error_code SymbolRef::getSize(uint64_t &Result) const {
  348. return OwningObject->getSymbolSize(SymbolPimpl, Result);
  349. }
  350. inline error_code SymbolRef::getNMTypeChar(char &Result) const {
  351. return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result);
  352. }
  353. inline error_code SymbolRef::getFlags(uint32_t &Result) const {
  354. return OwningObject->getSymbolFlags(SymbolPimpl, Result);
  355. }
  356. inline error_code SymbolRef::getSection(section_iterator &Result) const {
  357. return OwningObject->getSymbolSection(SymbolPimpl, Result);
  358. }
  359. inline error_code SymbolRef::getType(SymbolRef::Type &Result) const {
  360. return OwningObject->getSymbolType(SymbolPimpl, Result);
  361. }
  362. inline error_code SymbolRef::getValue(uint64_t &Val) const {
  363. return OwningObject->getSymbolValue(SymbolPimpl, Val);
  364. }
  365. inline DataRefImpl SymbolRef::getRawDataRefImpl() const {
  366. return SymbolPimpl;
  367. }
  368. /// SectionRef
  369. inline SectionRef::SectionRef(DataRefImpl SectionP,
  370. const ObjectFile *Owner)
  371. : SectionPimpl(SectionP)
  372. , OwningObject(Owner) {}
  373. inline bool SectionRef::operator==(const SectionRef &Other) const {
  374. return SectionPimpl == Other.SectionPimpl;
  375. }
  376. inline bool SectionRef::operator<(const SectionRef &Other) const {
  377. return SectionPimpl < Other.SectionPimpl;
  378. }
  379. inline error_code SectionRef::getNext(SectionRef &Result) const {
  380. return OwningObject->getSectionNext(SectionPimpl, Result);
  381. }
  382. inline error_code SectionRef::getName(StringRef &Result) const {
  383. return OwningObject->getSectionName(SectionPimpl, Result);
  384. }
  385. inline error_code SectionRef::getAddress(uint64_t &Result) const {
  386. return OwningObject->getSectionAddress(SectionPimpl, Result);
  387. }
  388. inline error_code SectionRef::getSize(uint64_t &Result) const {
  389. return OwningObject->getSectionSize(SectionPimpl, Result);
  390. }
  391. inline error_code SectionRef::getContents(StringRef &Result) const {
  392. return OwningObject->getSectionContents(SectionPimpl, Result);
  393. }
  394. inline error_code SectionRef::getAlignment(uint64_t &Result) const {
  395. return OwningObject->getSectionAlignment(SectionPimpl, Result);
  396. }
  397. inline error_code SectionRef::isText(bool &Result) const {
  398. return OwningObject->isSectionText(SectionPimpl, Result);
  399. }
  400. inline error_code SectionRef::isData(bool &Result) const {
  401. return OwningObject->isSectionData(SectionPimpl, Result);
  402. }
  403. inline error_code SectionRef::isBSS(bool &Result) const {
  404. return OwningObject->isSectionBSS(SectionPimpl, Result);
  405. }
  406. inline error_code SectionRef::isRequiredForExecution(bool &Result) const {
  407. return OwningObject->isSectionRequiredForExecution(SectionPimpl, Result);
  408. }
  409. inline error_code SectionRef::isVirtual(bool &Result) const {
  410. return OwningObject->isSectionVirtual(SectionPimpl, Result);
  411. }
  412. inline error_code SectionRef::isZeroInit(bool &Result) const {
  413. return OwningObject->isSectionZeroInit(SectionPimpl, Result);
  414. }
  415. inline error_code SectionRef::isReadOnlyData(bool &Result) const {
  416. return OwningObject->isSectionReadOnlyData(SectionPimpl, Result);
  417. }
  418. inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const {
  419. return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl,
  420. Result);
  421. }
  422. inline relocation_iterator SectionRef::begin_relocations() const {
  423. return OwningObject->getSectionRelBegin(SectionPimpl);
  424. }
  425. inline relocation_iterator SectionRef::end_relocations() const {
  426. return OwningObject->getSectionRelEnd(SectionPimpl);
  427. }
  428. inline DataRefImpl SectionRef::getRawDataRefImpl() const {
  429. return SectionPimpl;
  430. }
  431. /// RelocationRef
  432. inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
  433. const ObjectFile *Owner)
  434. : RelocationPimpl(RelocationP)
  435. , OwningObject(Owner) {}
  436. inline bool RelocationRef::operator==(const RelocationRef &Other) const {
  437. return RelocationPimpl == Other.RelocationPimpl;
  438. }
  439. inline error_code RelocationRef::getNext(RelocationRef &Result) const {
  440. return OwningObject->getRelocationNext(RelocationPimpl, Result);
  441. }
  442. inline error_code RelocationRef::getAddress(uint64_t &Result) const {
  443. return OwningObject->getRelocationAddress(RelocationPimpl, Result);
  444. }
  445. inline error_code RelocationRef::getOffset(uint64_t &Result) const {
  446. return OwningObject->getRelocationOffset(RelocationPimpl, Result);
  447. }
  448. inline error_code RelocationRef::getSymbol(SymbolRef &Result) const {
  449. return OwningObject->getRelocationSymbol(RelocationPimpl, Result);
  450. }
  451. inline error_code RelocationRef::getType(uint64_t &Result) const {
  452. return OwningObject->getRelocationType(RelocationPimpl, Result);
  453. }
  454. inline error_code RelocationRef::getTypeName(SmallVectorImpl<char> &Result)
  455. const {
  456. return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
  457. }
  458. inline error_code RelocationRef::getAdditionalInfo(int64_t &Result) const {
  459. return OwningObject->getRelocationAdditionalInfo(RelocationPimpl, Result);
  460. }
  461. inline error_code RelocationRef::getValueString(SmallVectorImpl<char> &Result)
  462. const {
  463. return OwningObject->getRelocationValueString(RelocationPimpl, Result);
  464. }
  465. inline error_code RelocationRef::getHidden(bool &Result) const {
  466. return OwningObject->getRelocationHidden(RelocationPimpl, Result);
  467. }
  468. inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
  469. return RelocationPimpl;
  470. }
  471. // Inline function definitions.
  472. inline LibraryRef::LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner)
  473. : LibraryPimpl(LibraryP)
  474. , OwningObject(Owner) {}
  475. inline bool LibraryRef::operator==(const LibraryRef &Other) const {
  476. return LibraryPimpl == Other.LibraryPimpl;
  477. }
  478. inline bool LibraryRef::operator<(const LibraryRef &Other) const {
  479. return LibraryPimpl < Other.LibraryPimpl;
  480. }
  481. inline error_code LibraryRef::getNext(LibraryRef &Result) const {
  482. return OwningObject->getLibraryNext(LibraryPimpl, Result);
  483. }
  484. inline error_code LibraryRef::getPath(StringRef &Result) const {
  485. return OwningObject->getLibraryPath(LibraryPimpl, Result);
  486. }
  487. } // end namespace object
  488. } // end namespace llvm
  489. #endif