1c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer//===- Binary.cpp - 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 defines the Binary class. 11c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer// 12c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer//===----------------------------------------------------------------------===// 13c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer 14c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer#include "llvm/Object/Binary.h" 15c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer#include "llvm/ADT/StringRef.h" 16c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer#include "llvm/Support/MemoryBuffer.h" 17c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer#include "llvm/Support/Path.h" 18c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer 19001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer// Include headers for createBinary. 20a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer#include "llvm/Object/Archive.h" 21001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer#include "llvm/Object/COFF.h" 22a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer#include "llvm/Object/ObjectFile.h" 23001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer 24c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencerusing namespace llvm; 25c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencerusing namespace object; 26c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer 27c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. SpencerBinary::~Binary() { 28c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer delete Data; 29c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer} 30c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer 31c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. SpencerBinary::Binary(unsigned int Type, MemoryBuffer *Source) 32c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer : TypeID(Type) 33c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer , Data(Source) {} 34c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer 35c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. SpencerStringRef Binary::getData() const { 36c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer return Data->getBuffer(); 37c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer} 38c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer 39c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. SpencerStringRef Binary::getFileName() const { 40c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer return Data->getBufferIdentifier(); 41c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer} 42c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer 43c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencererror_code object::createBinary(MemoryBuffer *Source, 44c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer OwningPtr<Binary> &Result) { 45001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer OwningPtr<MemoryBuffer> scopedSource(Source); 46001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer if (!Source) 47001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer return make_error_code(errc::invalid_argument); 48001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer if (Source->getBufferSize() < 64) 49001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer return object_error::invalid_file_type; 50001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer sys::LLVMFileType type = sys::IdentifyFileType(Source->getBufferStart(), 51001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer static_cast<unsigned>(Source->getBufferSize())); 52001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer error_code ec; 53001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer switch (type) { 54a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer case sys::Archive_FileType: { 55a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer OwningPtr<Binary> ret(new Archive(scopedSource.take(), ec)); 56a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer if (ec) return ec; 57a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer Result.swap(ret); 58a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer return object_error::success; 59a51d7d97b0b8187ed68d4cbad2374f514d2cd168Michael J. Spencer } 60001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::ELF_Relocatable_FileType: 61001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::ELF_Executable_FileType: 62001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::ELF_SharedObject_FileType: 63001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::ELF_Core_FileType: { 64001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer OwningPtr<Binary> ret( 65001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer ObjectFile::createELFObjectFile(scopedSource.take())); 66001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer if (!ret) 67001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer return object_error::invalid_file_type; 68001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer Result.swap(ret); 69001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer return object_error::success; 70001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer } 71001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::Mach_O_Object_FileType: 72001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::Mach_O_Executable_FileType: 73001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::Mach_O_FixedVirtualMemorySharedLib_FileType: 74001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::Mach_O_Core_FileType: 75001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::Mach_O_PreloadExecutable_FileType: 76001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::Mach_O_DynamicallyLinkedSharedLib_FileType: 77001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::Mach_O_DynamicLinker_FileType: 78001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::Mach_O_Bundle_FileType: 79001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType: { 80001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer OwningPtr<Binary> ret( 81001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer ObjectFile::createMachOObjectFile(scopedSource.take())); 82001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer if (!ret) 83001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer return object_error::invalid_file_type; 84001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer Result.swap(ret); 85001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer return object_error::success; 86001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer } 87001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer case sys::COFF_FileType: { 88001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer OwningPtr<Binary> ret(new COFFObjectFile(scopedSource.take(), ec)); 89001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer if (ec) return ec; 90001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer Result.swap(ret); 91001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer return object_error::success; 92001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer } 93001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer default: // Unrecognized object file format. 94001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer return object_error::invalid_file_type; 95001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer } 96c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer} 97c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer 98c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencererror_code object::createBinary(StringRef Path, OwningPtr<Binary> &Result) { 99c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer OwningPtr<MemoryBuffer> File; 100c6500a5d77159e9c9a9f1f8f56307a0016f229a0Michael J. Spencer if (error_code ec = MemoryBuffer::getFileOrSTDIN(Path, File)) 101c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer return ec; 102c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer return createBinary(File.take(), Result); 103c44c915372ee453bd63a8b6b3eca586ab6f18545Michael J. Spencer} 104