1 //===- Binary.cpp - A generic binary 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 defines the Binary class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Object/Binary.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/Support/MemoryBuffer.h" 17 #include "llvm/Support/Path.h" 18 19 // Include headers for createBinary. 20 #include "llvm/Object/Archive.h" 21 #include "llvm/Object/COFF.h" 22 #include "llvm/Object/ObjectFile.h" 23 24 using namespace llvm; 25 using namespace object; 26 27 Binary::~Binary() { 28 delete Data; 29 } 30 31 Binary::Binary(unsigned int Type, MemoryBuffer *Source) 32 : TypeID(Type) 33 , Data(Source) {} 34 35 StringRef Binary::getData() const { 36 return Data->getBuffer(); 37 } 38 39 StringRef Binary::getFileName() const { 40 return Data->getBufferIdentifier(); 41 } 42 43 error_code object::createBinary(MemoryBuffer *Source, 44 OwningPtr<Binary> &Result) { 45 OwningPtr<MemoryBuffer> scopedSource(Source); 46 if (!Source) 47 return make_error_code(errc::invalid_argument); 48 if (Source->getBufferSize() < 64) 49 return object_error::invalid_file_type; 50 sys::LLVMFileType type = sys::IdentifyFileType(Source->getBufferStart(), 51 static_cast<unsigned>(Source->getBufferSize())); 52 error_code ec; 53 switch (type) { 54 case sys::Archive_FileType: { 55 OwningPtr<Binary> ret(new Archive(scopedSource.take(), ec)); 56 if (ec) return ec; 57 Result.swap(ret); 58 return object_error::success; 59 } 60 case sys::ELF_Relocatable_FileType: 61 case sys::ELF_Executable_FileType: 62 case sys::ELF_SharedObject_FileType: 63 case sys::ELF_Core_FileType: { 64 OwningPtr<Binary> ret( 65 ObjectFile::createELFObjectFile(scopedSource.take())); 66 if (!ret) 67 return object_error::invalid_file_type; 68 Result.swap(ret); 69 return object_error::success; 70 } 71 case sys::Mach_O_Object_FileType: 72 case sys::Mach_O_Executable_FileType: 73 case sys::Mach_O_FixedVirtualMemorySharedLib_FileType: 74 case sys::Mach_O_Core_FileType: 75 case sys::Mach_O_PreloadExecutable_FileType: 76 case sys::Mach_O_DynamicallyLinkedSharedLib_FileType: 77 case sys::Mach_O_DynamicLinker_FileType: 78 case sys::Mach_O_Bundle_FileType: 79 case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType: { 80 OwningPtr<Binary> ret( 81 ObjectFile::createMachOObjectFile(scopedSource.take())); 82 if (!ret) 83 return object_error::invalid_file_type; 84 Result.swap(ret); 85 return object_error::success; 86 } 87 case sys::COFF_FileType: { 88 OwningPtr<Binary> ret(new COFFObjectFile(scopedSource.take(), ec)); 89 if (ec) return ec; 90 Result.swap(ret); 91 return object_error::success; 92 } 93 default: // Unrecognized object file format. 94 return object_error::invalid_file_type; 95 } 96 } 97 98 error_code object::createBinary(StringRef Path, OwningPtr<Binary> &Result) { 99 OwningPtr<MemoryBuffer> File; 100 if (error_code ec = MemoryBuffer::getFileOrSTDIN(Path, File)) 101 return ec; 102 return createBinary(File.take(), Result); 103 } 104