Binary.cpp revision f49d8fcbd594007ac6f25a1f1f90919221011f97
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/FileSystem.h"
18#include "llvm/Support/Path.h"
19
20// Include headers for createBinary.
21#include "llvm/Object/Archive.h"
22#include "llvm/Object/COFF.h"
23#include "llvm/Object/MachOUniversal.h"
24#include "llvm/Object/ObjectFile.h"
25
26using namespace llvm;
27using namespace object;
28
29Binary::~Binary() {
30  delete Data;
31}
32
33Binary::Binary(unsigned int Type, MemoryBuffer *Source)
34  : TypeID(Type)
35  , Data(Source) {}
36
37StringRef Binary::getData() const {
38  return Data->getBuffer();
39}
40
41StringRef Binary::getFileName() const {
42  return Data->getBufferIdentifier();
43}
44
45error_code object::createBinary(MemoryBuffer *Source,
46                                OwningPtr<Binary> &Result) {
47  OwningPtr<MemoryBuffer> scopedSource(Source);
48  if (!Source)
49    return make_error_code(errc::invalid_argument);
50  sys::fs::file_magic type = sys::fs::identify_magic(Source->getBuffer());
51  error_code ec;
52  switch (type) {
53    case sys::fs::file_magic::archive: {
54      OwningPtr<Binary> ret(new Archive(scopedSource.take(), ec));
55      if (ec) return ec;
56      Result.swap(ret);
57      return object_error::success;
58    }
59    case sys::fs::file_magic::elf_relocatable:
60    case sys::fs::file_magic::elf_executable:
61    case sys::fs::file_magic::elf_shared_object:
62    case sys::fs::file_magic::elf_core: {
63      OwningPtr<Binary> ret(
64        ObjectFile::createELFObjectFile(scopedSource.take()));
65      if (!ret)
66        return object_error::invalid_file_type;
67      Result.swap(ret);
68      return object_error::success;
69    }
70    case sys::fs::file_magic::macho_object:
71    case sys::fs::file_magic::macho_executable:
72    case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
73    case sys::fs::file_magic::macho_core:
74    case sys::fs::file_magic::macho_preload_executable:
75    case sys::fs::file_magic::macho_dynamically_linked_shared_lib:
76    case sys::fs::file_magic::macho_dynamic_linker:
77    case sys::fs::file_magic::macho_bundle:
78    case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
79    case sys::fs::file_magic::macho_dsym_companion: {
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::fs::file_magic::macho_universal_binary: {
88      OwningPtr<Binary> ret(new MachOUniversalBinary(scopedSource.take(), ec));
89      if (ec) return ec;
90      Result.swap(ret);
91      return object_error::success;
92    }
93    case sys::fs::file_magic::coff_object:
94    case sys::fs::file_magic::pecoff_executable: {
95      OwningPtr<Binary> ret(
96          ObjectFile::createCOFFObjectFile(scopedSource.take()));
97      if (!ret)
98        return object_error::invalid_file_type;
99      Result.swap(ret);
100      return object_error::success;
101    }
102    case sys::fs::file_magic::unknown:
103    case sys::fs::file_magic::bitcode: {
104      // Unrecognized object file format.
105      return object_error::invalid_file_type;
106    }
107  }
108  llvm_unreachable("Unexpected Binary File Type");
109}
110
111error_code object::createBinary(StringRef Path, OwningPtr<Binary> &Result) {
112  OwningPtr<MemoryBuffer> File;
113  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Path, File))
114    return ec;
115  return createBinary(File.take(), Result);
116}
117