ObjectFile.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  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/SymbolicFile.h"
  17. #include "llvm/Support/DataTypes.h"
  18. #include "llvm/Support/ErrorHandling.h"
  19. #include "llvm/Support/FileSystem.h"
  20. #include "llvm/Support/MemoryBuffer.h"
  21. #include <cstring>
  22. #include <vector>
  23. namespace llvm {
  24. namespace object {
  25. class ObjectFile;
  26. class COFFObjectFile;
  27. class MachOObjectFile;
  28. class SymbolRef;
  29. class symbol_iterator;
  30. class SectionRef;
  31. typedef content_iterator<SectionRef> section_iterator;
  32. /// This is a value type class that represents a single relocation in the list
  33. /// of relocations in the object file.
  34. class RelocationRef {
  35. DataRefImpl RelocationPimpl;
  36. const ObjectFile *OwningObject;
  37. public:
  38. RelocationRef() : OwningObject(nullptr) { }
  39. RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
  40. bool operator==(const RelocationRef &Other) const;
  41. void moveNext();
  42. std::error_code getAddress(uint64_t &Result) const;
  43. std::error_code getOffset(uint64_t &Result) const;
  44. symbol_iterator getSymbol() const;
  45. std::error_code getType(uint64_t &Result) const;
  46. /// @brief Indicates whether this relocation should hidden when listing
  47. /// relocations, usually because it is the trailing part of a multipart
  48. /// relocation that will be printed as part of the leading relocation.
  49. std::error_code getHidden(bool &Result) const;
  50. /// @brief Get a string that represents the type of this relocation.
  51. ///
  52. /// This is for display purposes only.
  53. std::error_code getTypeName(SmallVectorImpl<char> &Result) const;
  54. DataRefImpl getRawDataRefImpl() const;
  55. const ObjectFile *getObjectFile() const;
  56. };
  57. typedef content_iterator<RelocationRef> relocation_iterator;
  58. /// This is a value type class that represents a single section in the list of
  59. /// sections in the object file.
  60. class SectionRef {
  61. friend class SymbolRef;
  62. DataRefImpl SectionPimpl;
  63. const ObjectFile *OwningObject;
  64. public:
  65. SectionRef() : OwningObject(nullptr) { }
  66. SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
  67. bool operator==(const SectionRef &Other) const;
  68. bool operator!=(const SectionRef &Other) const;
  69. bool operator<(const SectionRef &Other) const;
  70. void moveNext();
  71. std::error_code getName(StringRef &Result) const;
  72. uint64_t getAddress() const;
  73. uint64_t getSize() const;
  74. std::error_code getContents(StringRef &Result) const;
  75. /// @brief Get the alignment of this section as the actual value (not log 2).
  76. uint64_t getAlignment() const;
  77. bool isText() const;
  78. bool isData() const;
  79. bool isBSS() const;
  80. bool isVirtual() const;
  81. bool containsSymbol(SymbolRef S) const;
  82. relocation_iterator relocation_begin() const;
  83. relocation_iterator relocation_end() const;
  84. iterator_range<relocation_iterator> relocations() const {
  85. return iterator_range<relocation_iterator>(relocation_begin(),
  86. relocation_end());
  87. }
  88. section_iterator getRelocatedSection() const;
  89. DataRefImpl getRawDataRefImpl() const;
  90. const ObjectFile *getObject() const;
  91. };
  92. /// This is a value type class that represents a single symbol in the list of
  93. /// symbols in the object file.
  94. class SymbolRef : public BasicSymbolRef {
  95. friend class SectionRef;
  96. public:
  97. SymbolRef() : BasicSymbolRef() {}
  98. enum Type {
  99. ST_Unknown, // Type not specified
  100. ST_Data,
  101. ST_Debug,
  102. ST_File,
  103. ST_Function,
  104. ST_Other
  105. };
  106. SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
  107. std::error_code getName(StringRef &Result) const;
  108. /// Returns the symbol virtual address (i.e. address at which it will be
  109. /// mapped).
  110. std::error_code getAddress(uint64_t &Result) const;
  111. /// Return the value of the symbol depending on the object this can be an
  112. /// offset or a virtual address.
  113. uint64_t getValue() const;
  114. /// @brief Get the alignment of this symbol as the actual value (not log 2).
  115. uint32_t getAlignment() const;
  116. uint64_t getCommonSize() const;
  117. std::error_code getType(SymbolRef::Type &Result) const;
  118. std::error_code getOther(uint8_t &Result) const;
  119. /// @brief Get section this symbol is defined in reference to. Result is
  120. /// end_sections() if it is undefined or is an absolute symbol.
  121. std::error_code getSection(section_iterator &Result) const;
  122. const ObjectFile *getObject() const;
  123. };
  124. class symbol_iterator : public basic_symbol_iterator {
  125. public:
  126. symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
  127. symbol_iterator(const basic_symbol_iterator &B)
  128. : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
  129. cast<ObjectFile>(B->getObject()))) {}
  130. const SymbolRef *operator->() const {
  131. const BasicSymbolRef &P = basic_symbol_iterator::operator *();
  132. return static_cast<const SymbolRef*>(&P);
  133. }
  134. const SymbolRef &operator*() const {
  135. const BasicSymbolRef &P = basic_symbol_iterator::operator *();
  136. return static_cast<const SymbolRef&>(P);
  137. }
  138. };
  139. /// This class is the base class for all object file types. Concrete instances
  140. /// of this object are created by createObjectFile, which figures out which type
  141. /// to create.
  142. class ObjectFile : public SymbolicFile {
  143. virtual void anchor();
  144. ObjectFile() = delete;
  145. ObjectFile(const ObjectFile &other) = delete;
  146. protected:
  147. ObjectFile(unsigned int Type, MemoryBufferRef Source);
  148. const uint8_t *base() const {
  149. return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
  150. }
  151. // These functions are for SymbolRef to call internally. The main goal of
  152. // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
  153. // entry in the memory mapped object file. SymbolPimpl cannot contain any
  154. // virtual functions because then it could not point into the memory mapped
  155. // file.
  156. //
  157. // Implementations assume that the DataRefImpl is valid and has not been
  158. // modified externally. It's UB otherwise.
  159. friend class SymbolRef;
  160. virtual std::error_code getSymbolName(DataRefImpl Symb,
  161. StringRef &Res) const = 0;
  162. std::error_code printSymbolName(raw_ostream &OS,
  163. DataRefImpl Symb) const override;
  164. virtual std::error_code getSymbolAddress(DataRefImpl Symb,
  165. uint64_t &Res) const = 0;
  166. virtual uint64_t getSymbolValue(DataRefImpl Symb) const = 0;
  167. virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
  168. virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
  169. virtual std::error_code getSymbolType(DataRefImpl Symb,
  170. SymbolRef::Type &Res) const = 0;
  171. virtual std::error_code getSymbolSection(DataRefImpl Symb,
  172. section_iterator &Res) const = 0;
  173. virtual std::error_code getSymbolOther(DataRefImpl Symb,
  174. uint8_t &Res) const {
  175. return object_error::invalid_file_type;
  176. }
  177. // Same as above for SectionRef.
  178. friend class SectionRef;
  179. virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
  180. virtual std::error_code getSectionName(DataRefImpl Sec,
  181. StringRef &Res) const = 0;
  182. virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
  183. virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
  184. virtual std::error_code getSectionContents(DataRefImpl Sec,
  185. StringRef &Res) const = 0;
  186. virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
  187. virtual bool isSectionText(DataRefImpl Sec) const = 0;
  188. virtual bool isSectionData(DataRefImpl Sec) const = 0;
  189. virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
  190. // A section is 'virtual' if its contents aren't present in the object image.
  191. virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
  192. virtual bool sectionContainsSymbol(DataRefImpl Sec,
  193. DataRefImpl Symb) const = 0;
  194. virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
  195. virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
  196. virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
  197. // Same as above for RelocationRef.
  198. friend class RelocationRef;
  199. virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
  200. virtual std::error_code getRelocationAddress(DataRefImpl Rel,
  201. uint64_t &Res) const = 0;
  202. virtual std::error_code getRelocationOffset(DataRefImpl Rel,
  203. uint64_t &Res) const = 0;
  204. virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
  205. virtual std::error_code getRelocationType(DataRefImpl Rel,
  206. uint64_t &Res) const = 0;
  207. virtual std::error_code
  208. getRelocationTypeName(DataRefImpl Rel,
  209. SmallVectorImpl<char> &Result) const = 0;
  210. virtual std::error_code getRelocationHidden(DataRefImpl Rel,
  211. bool &Result) const {
  212. Result = false;
  213. return std::error_code();
  214. }
  215. public:
  216. uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
  217. assert(getSymbolFlags(Symb) & SymbolRef::SF_Common);
  218. return getCommonSymbolSizeImpl(Symb);
  219. }
  220. typedef iterator_range<symbol_iterator> symbol_iterator_range;
  221. symbol_iterator_range symbols() const {
  222. return symbol_iterator_range(symbol_begin(), symbol_end());
  223. }
  224. virtual section_iterator section_begin() const = 0;
  225. virtual section_iterator section_end() const = 0;
  226. typedef iterator_range<section_iterator> section_iterator_range;
  227. section_iterator_range sections() const {
  228. return section_iterator_range(section_begin(), section_end());
  229. }
  230. /// @brief The number of bytes used to represent an address in this object
  231. /// file format.
  232. virtual uint8_t getBytesInAddress() const = 0;
  233. virtual StringRef getFileFormatName() const = 0;
  234. virtual /* Triple::ArchType */ unsigned getArch() const = 0;
  235. /// Returns platform-specific object flags, if any.
  236. virtual std::error_code getPlatformFlags(unsigned &Result) const {
  237. Result = 0;
  238. return object_error::invalid_file_type;
  239. }
  240. /// True if this is a relocatable object (.o/.obj).
  241. virtual bool isRelocatableObject() const = 0;
  242. /// @returns Pointer to ObjectFile subclass to handle this type of object.
  243. /// @param ObjectPath The path to the object file. ObjectPath.isObject must
  244. /// return true.
  245. /// @brief Create ObjectFile from path.
  246. static ErrorOr<OwningBinary<ObjectFile>>
  247. createObjectFile(StringRef ObjectPath);
  248. static ErrorOr<std::unique_ptr<ObjectFile>>
  249. createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type);
  250. static ErrorOr<std::unique_ptr<ObjectFile>>
  251. createObjectFile(MemoryBufferRef Object) {
  252. return createObjectFile(Object, sys::fs::file_magic::unknown);
  253. }
  254. static inline bool classof(const Binary *v) {
  255. return v->isObject();
  256. }
  257. static ErrorOr<std::unique_ptr<COFFObjectFile>>
  258. createCOFFObjectFile(MemoryBufferRef Object);
  259. static ErrorOr<std::unique_ptr<ObjectFile>>
  260. createELFObjectFile(MemoryBufferRef Object);
  261. static ErrorOr<std::unique_ptr<MachOObjectFile>>
  262. createMachOObjectFile(MemoryBufferRef Object);
  263. };
  264. // Inline function definitions.
  265. inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
  266. : BasicSymbolRef(SymbolP, Owner) {}
  267. inline std::error_code SymbolRef::getName(StringRef &Result) const {
  268. return getObject()->getSymbolName(getRawDataRefImpl(), Result);
  269. }
  270. inline std::error_code SymbolRef::getAddress(uint64_t &Result) const {
  271. return getObject()->getSymbolAddress(getRawDataRefImpl(), Result);
  272. }
  273. inline uint64_t SymbolRef::getValue() const {
  274. return getObject()->getSymbolValue(getRawDataRefImpl());
  275. }
  276. inline uint32_t SymbolRef::getAlignment() const {
  277. return getObject()->getSymbolAlignment(getRawDataRefImpl());
  278. }
  279. inline uint64_t SymbolRef::getCommonSize() const {
  280. return getObject()->getCommonSymbolSize(getRawDataRefImpl());
  281. }
  282. inline std::error_code SymbolRef::getSection(section_iterator &Result) const {
  283. return getObject()->getSymbolSection(getRawDataRefImpl(), Result);
  284. }
  285. inline std::error_code SymbolRef::getType(SymbolRef::Type &Result) const {
  286. return getObject()->getSymbolType(getRawDataRefImpl(), Result);
  287. }
  288. inline std::error_code SymbolRef::getOther(uint8_t &Result) const {
  289. return getObject()->getSymbolOther(getRawDataRefImpl(), Result);
  290. }
  291. inline const ObjectFile *SymbolRef::getObject() const {
  292. const SymbolicFile *O = BasicSymbolRef::getObject();
  293. return cast<ObjectFile>(O);
  294. }
  295. /// SectionRef
  296. inline SectionRef::SectionRef(DataRefImpl SectionP,
  297. const ObjectFile *Owner)
  298. : SectionPimpl(SectionP)
  299. , OwningObject(Owner) {}
  300. inline bool SectionRef::operator==(const SectionRef &Other) const {
  301. return SectionPimpl == Other.SectionPimpl;
  302. }
  303. inline bool SectionRef::operator!=(const SectionRef &Other) const {
  304. return SectionPimpl != Other.SectionPimpl;
  305. }
  306. inline bool SectionRef::operator<(const SectionRef &Other) const {
  307. return SectionPimpl < Other.SectionPimpl;
  308. }
  309. inline void SectionRef::moveNext() {
  310. return OwningObject->moveSectionNext(SectionPimpl);
  311. }
  312. inline std::error_code SectionRef::getName(StringRef &Result) const {
  313. return OwningObject->getSectionName(SectionPimpl, Result);
  314. }
  315. inline uint64_t SectionRef::getAddress() const {
  316. return OwningObject->getSectionAddress(SectionPimpl);
  317. }
  318. inline uint64_t SectionRef::getSize() const {
  319. return OwningObject->getSectionSize(SectionPimpl);
  320. }
  321. inline std::error_code SectionRef::getContents(StringRef &Result) const {
  322. return OwningObject->getSectionContents(SectionPimpl, Result);
  323. }
  324. inline uint64_t SectionRef::getAlignment() const {
  325. return OwningObject->getSectionAlignment(SectionPimpl);
  326. }
  327. inline bool SectionRef::isText() const {
  328. return OwningObject->isSectionText(SectionPimpl);
  329. }
  330. inline bool SectionRef::isData() const {
  331. return OwningObject->isSectionData(SectionPimpl);
  332. }
  333. inline bool SectionRef::isBSS() const {
  334. return OwningObject->isSectionBSS(SectionPimpl);
  335. }
  336. inline bool SectionRef::isVirtual() const {
  337. return OwningObject->isSectionVirtual(SectionPimpl);
  338. }
  339. inline bool SectionRef::containsSymbol(SymbolRef S) const {
  340. return OwningObject->sectionContainsSymbol(SectionPimpl,
  341. S.getRawDataRefImpl());
  342. }
  343. inline relocation_iterator SectionRef::relocation_begin() const {
  344. return OwningObject->section_rel_begin(SectionPimpl);
  345. }
  346. inline relocation_iterator SectionRef::relocation_end() const {
  347. return OwningObject->section_rel_end(SectionPimpl);
  348. }
  349. inline section_iterator SectionRef::getRelocatedSection() const {
  350. return OwningObject->getRelocatedSection(SectionPimpl);
  351. }
  352. inline DataRefImpl SectionRef::getRawDataRefImpl() const {
  353. return SectionPimpl;
  354. }
  355. inline const ObjectFile *SectionRef::getObject() const {
  356. return OwningObject;
  357. }
  358. /// RelocationRef
  359. inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
  360. const ObjectFile *Owner)
  361. : RelocationPimpl(RelocationP)
  362. , OwningObject(Owner) {}
  363. inline bool RelocationRef::operator==(const RelocationRef &Other) const {
  364. return RelocationPimpl == Other.RelocationPimpl;
  365. }
  366. inline void RelocationRef::moveNext() {
  367. return OwningObject->moveRelocationNext(RelocationPimpl);
  368. }
  369. inline std::error_code RelocationRef::getAddress(uint64_t &Result) const {
  370. return OwningObject->getRelocationAddress(RelocationPimpl, Result);
  371. }
  372. inline std::error_code RelocationRef::getOffset(uint64_t &Result) const {
  373. return OwningObject->getRelocationOffset(RelocationPimpl, Result);
  374. }
  375. inline symbol_iterator RelocationRef::getSymbol() const {
  376. return OwningObject->getRelocationSymbol(RelocationPimpl);
  377. }
  378. inline std::error_code RelocationRef::getType(uint64_t &Result) const {
  379. return OwningObject->getRelocationType(RelocationPimpl, Result);
  380. }
  381. inline std::error_code
  382. RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
  383. return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
  384. }
  385. inline std::error_code RelocationRef::getHidden(bool &Result) const {
  386. return OwningObject->getRelocationHidden(RelocationPimpl, Result);
  387. }
  388. inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
  389. return RelocationPimpl;
  390. }
  391. inline const ObjectFile *RelocationRef::getObjectFile() const {
  392. return OwningObject;
  393. }
  394. } // end namespace object
  395. } // end namespace llvm
  396. #endif