Home | History | Annotate | Download | only in Object
      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