1224133Sdim//===- Binary.cpp - A generic binary file -----------------------*- C++ -*-===//
2224133Sdim//
3224133Sdim//                     The LLVM Compiler Infrastructure
4224133Sdim//
5224133Sdim// This file is distributed under the University of Illinois Open Source
6224133Sdim// License. See LICENSE.TXT for details.
7224133Sdim//
8224133Sdim//===----------------------------------------------------------------------===//
9224133Sdim//
10224133Sdim// This file defines the Binary class.
11224133Sdim//
12224133Sdim//===----------------------------------------------------------------------===//
13224133Sdim
14224133Sdim#include "llvm/Object/Binary.h"
15224133Sdim#include "llvm/ADT/StringRef.h"
16224133Sdim#include "llvm/Support/MemoryBuffer.h"
17263508Sdim#include "llvm/Support/FileSystem.h"
18224133Sdim#include "llvm/Support/Path.h"
19224133Sdim
20224133Sdim// Include headers for createBinary.
21226633Sdim#include "llvm/Object/Archive.h"
22226633Sdim#include "llvm/Object/COFF.h"
23263508Sdim#include "llvm/Object/MachOUniversal.h"
24224133Sdim#include "llvm/Object/ObjectFile.h"
25224133Sdim
26224133Sdimusing namespace llvm;
27224133Sdimusing namespace object;
28224133Sdim
29224133SdimBinary::~Binary() {
30224133Sdim  delete Data;
31224133Sdim}
32224133Sdim
33224133SdimBinary::Binary(unsigned int Type, MemoryBuffer *Source)
34224133Sdim  : TypeID(Type)
35224133Sdim  , Data(Source) {}
36224133Sdim
37224133SdimStringRef Binary::getData() const {
38224133Sdim  return Data->getBuffer();
39224133Sdim}
40224133Sdim
41224133SdimStringRef Binary::getFileName() const {
42224133Sdim  return Data->getBufferIdentifier();
43224133Sdim}
44224133Sdim
45224133Sdimerror_code object::createBinary(MemoryBuffer *Source,
46224133Sdim                                OwningPtr<Binary> &Result) {
47224133Sdim  OwningPtr<MemoryBuffer> scopedSource(Source);
48224133Sdim  if (!Source)
49224133Sdim    return make_error_code(errc::invalid_argument);
50263508Sdim  sys::fs::file_magic type = sys::fs::identify_magic(Source->getBuffer());
51224133Sdim  error_code ec;
52224133Sdim  switch (type) {
53263508Sdim    case sys::fs::file_magic::archive: {
54226633Sdim      OwningPtr<Binary> ret(new Archive(scopedSource.take(), ec));
55226633Sdim      if (ec) return ec;
56226633Sdim      Result.swap(ret);
57226633Sdim      return object_error::success;
58226633Sdim    }
59263508Sdim    case sys::fs::file_magic::elf_relocatable:
60263508Sdim    case sys::fs::file_magic::elf_executable:
61263508Sdim    case sys::fs::file_magic::elf_shared_object:
62263508Sdim    case sys::fs::file_magic::elf_core: {
63224133Sdim      OwningPtr<Binary> ret(
64224133Sdim        ObjectFile::createELFObjectFile(scopedSource.take()));
65224133Sdim      if (!ret)
66224133Sdim        return object_error::invalid_file_type;
67224133Sdim      Result.swap(ret);
68224133Sdim      return object_error::success;
69224133Sdim    }
70263508Sdim    case sys::fs::file_magic::macho_object:
71263508Sdim    case sys::fs::file_magic::macho_executable:
72263508Sdim    case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
73263508Sdim    case sys::fs::file_magic::macho_core:
74263508Sdim    case sys::fs::file_magic::macho_preload_executable:
75263508Sdim    case sys::fs::file_magic::macho_dynamically_linked_shared_lib:
76263508Sdim    case sys::fs::file_magic::macho_dynamic_linker:
77263508Sdim    case sys::fs::file_magic::macho_bundle:
78263508Sdim    case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
79263508Sdim    case sys::fs::file_magic::macho_dsym_companion: {
80224133Sdim      OwningPtr<Binary> ret(
81224133Sdim        ObjectFile::createMachOObjectFile(scopedSource.take()));
82224133Sdim      if (!ret)
83224133Sdim        return object_error::invalid_file_type;
84224133Sdim      Result.swap(ret);
85224133Sdim      return object_error::success;
86224133Sdim    }
87263508Sdim    case sys::fs::file_magic::macho_universal_binary: {
88263508Sdim      OwningPtr<Binary> ret(new MachOUniversalBinary(scopedSource.take(), ec));
89224133Sdim      if (ec) return ec;
90224133Sdim      Result.swap(ret);
91224133Sdim      return object_error::success;
92224133Sdim    }
93263508Sdim    case sys::fs::file_magic::coff_object:
94263508Sdim    case sys::fs::file_magic::coff_import_library:
95263508Sdim    case sys::fs::file_magic::pecoff_executable: {
96263508Sdim      OwningPtr<Binary> ret(
97263508Sdim          ObjectFile::createCOFFObjectFile(scopedSource.take()));
98263508Sdim      if (!ret)
99263508Sdim        return object_error::invalid_file_type;
100263508Sdim      Result.swap(ret);
101263508Sdim      return object_error::success;
102263508Sdim    }
103263508Sdim    case sys::fs::file_magic::unknown:
104263508Sdim    case sys::fs::file_magic::bitcode:
105263508Sdim    case sys::fs::file_magic::windows_resource: {
106263508Sdim      // Unrecognized object file format.
107224133Sdim      return object_error::invalid_file_type;
108263508Sdim    }
109224133Sdim  }
110263508Sdim  llvm_unreachable("Unexpected Binary File Type");
111224133Sdim}
112224133Sdim
113224133Sdimerror_code object::createBinary(StringRef Path, OwningPtr<Binary> &Result) {
114224133Sdim  OwningPtr<MemoryBuffer> File;
115226633Sdim  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Path, File))
116224133Sdim    return ec;
117224133Sdim  return createBinary(File.take(), Result);
118224133Sdim}
119