1c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer//===- Binary.h - A generic binary file -------------------------*- C++ -*-===//
2c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer//
3c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer//                     The LLVM Compiler Infrastructure
4c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer//
5c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer// This file is distributed under the University of Illinois Open Source
6c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer// License. See LICENSE.TXT for details.
7c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer//
8c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer//===----------------------------------------------------------------------===//
9c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer//
10c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer// This file declares the Binary class.
11c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer//
12c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer//===----------------------------------------------------------------------===//
13c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
14c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer#ifndef LLVM_OBJECT_BINARY_H
15c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer#define LLVM_OBJECT_BINARY_H
16c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
17c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer#include "llvm/Object/Error.h"
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ErrorOr.h"
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/FileSystem.h"
20c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
21c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencernamespace llvm {
22c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass LLVMContext;
24c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencerclass MemoryBuffer;
25c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencerclass StringRef;
26c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
27c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencernamespace object {
28c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
29c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencerclass Binary {
30c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencerprivate:
319f9ce61972871efcf794bdc6125835c2c32cd863Craig Topper  Binary() LLVM_DELETED_FUNCTION;
329f9ce61972871efcf794bdc6125835c2c32cd863Craig Topper  Binary(const Binary &other) LLVM_DELETED_FUNCTION;
33c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
34c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer  unsigned int TypeID;
35c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
36c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencerprotected:
37cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::unique_ptr<MemoryBuffer> Data;
38c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
39cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Binary(unsigned int Type, std::unique_ptr<MemoryBuffer> Source);
40c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
41c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer  enum {
426f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    ID_Archive,
439c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov    ID_MachOUniversalBinary,
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ID_IR, // LLVM IR
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
46001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    // Object and children.
476f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    ID_StartObjects,
486f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    ID_COFF,
499d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola
506f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    ID_ELF32L, // ELF 32-bit, little endian
516f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    ID_ELF32B, // ELF 32-bit, big endian
526f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    ID_ELF64L, // ELF 64-bit, little endian
536f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    ID_ELF64B, // ELF 64-bit, big endian
549d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola
559d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola    ID_MachO32L, // MachO 32-bit, little endian
569d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola    ID_MachO32B, // MachO 32-bit, big endian
579d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola    ID_MachO64L, // MachO 64-bit, little endian
589d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola    ID_MachO64B, // MachO 64-bit, big endian
599d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola
606f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    ID_EndObjects
61c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer  };
62c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
632af949ddddfaf2feb4a446c754e09d2d8c207ce4NAKAMURA Takumi  static inline unsigned int getELFType(bool isLE, bool is64Bits) {
642af949ddddfaf2feb4a446c754e09d2d8c207ce4NAKAMURA Takumi    if (isLE)
656f9489a86f33624f9ff5388411d12359ce9cef20David Meyer      return is64Bits ? ID_ELF64L : ID_ELF32L;
666f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    else
676f9489a86f33624f9ff5388411d12359ce9cef20David Meyer      return is64Bits ? ID_ELF64B : ID_ELF32B;
686f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  }
696f9489a86f33624f9ff5388411d12359ce9cef20David Meyer
709d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola  static unsigned int getMachOType(bool isLE, bool is64Bits) {
719d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola    if (isLE)
729d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola      return is64Bits ? ID_MachO64L : ID_MachO32L;
739d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola    else
749d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola      return is64Bits ? ID_MachO64B : ID_MachO32B;
759d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola  }
769d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola
77c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencerpublic:
78c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer  virtual ~Binary();
79c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
80c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer  StringRef getData() const;
81cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MemoryBuffer *releaseBuffer() { return Data.release(); }
82c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer  StringRef getFileName() const;
83c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
84c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer  // Cast methods.
85c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer  unsigned int getType() const { return TypeID; }
866f9489a86f33624f9ff5388411d12359ce9cef20David Meyer
876f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  // Convenience methods
886f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  bool isObject() const {
896f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
906f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  }
916f9489a86f33624f9ff5388411d12359ce9cef20David Meyer
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isSymbolic() const {
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isIR() || isObject();
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
966f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  bool isArchive() const {
976f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    return TypeID == ID_Archive;
986f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  }
996f9489a86f33624f9ff5388411d12359ce9cef20David Meyer
1009c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov  bool isMachOUniversalBinary() const {
1019c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov    return TypeID == ID_MachOUniversalBinary;
1029c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov  }
1039c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov
1046f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  bool isELF() const {
1056f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
1066f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  }
1076f9489a86f33624f9ff5388411d12359ce9cef20David Meyer
1086f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  bool isMachO() const {
1099d55c099d628d7835dd1b502cb29c96cae350099Rafael Espindola    return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
1106f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  }
1116f9489a86f33624f9ff5388411d12359ce9cef20David Meyer
1126f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  bool isCOFF() const {
1136f9489a86f33624f9ff5388411d12359ce9cef20David Meyer    return TypeID == ID_COFF;
1146f9489a86f33624f9ff5388411d12359ce9cef20David Meyer  }
1152af949ddddfaf2feb4a446c754e09d2d8c207ce4NAKAMURA Takumi
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isIR() const {
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return TypeID == ID_IR;
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1202af949ddddfaf2feb4a446c754e09d2d8c207ce4NAKAMURA Takumi  bool isLittleEndian() const {
121fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola    return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
122fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola             TypeID == ID_MachO32B || TypeID == ID_MachO64B);
1232af949ddddfaf2feb4a446c754e09d2d8c207ce4NAKAMURA Takumi  }
124c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer};
125c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
126b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer/// @brief Create a Binary from Source, autodetecting the file type.
127b35a896e072ff46c38905419b7f55aaccdb1d702Michael J. Spencer///
128d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer/// @param Source The data to create the Binary from. Ownership is transferred
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///        to the Binary if successful. If an error is returned,
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///        Source is destroyed by createBinary before returning.
131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesErrorOr<Binary *> createBinary(std::unique_ptr<MemoryBuffer> &Source,
132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               LLVMContext *Context = nullptr);
133c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesErrorOr<Binary *> createBinary(StringRef Path);
135c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer}
136c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer}
137c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer
138c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer#endif
139