aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/lib/Object/Binary.cpp
blob: 66a5abc0c8d7762ff6e82dbc400383185044a08b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//===- Binary.cpp - A generic binary file ---------------------------------===// 
// 
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
// See https://llvm.org/LICENSE.txt for license information. 
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
// 
//===----------------------------------------------------------------------===// 
// 
// This file defines the Binary class. 
// 
//===----------------------------------------------------------------------===// 
 
#include "llvm/Object/Binary.h" 
#include "llvm/ADT/StringRef.h" 
#include "llvm/BinaryFormat/Magic.h" 
#include "llvm/Object/Archive.h" 
#include "llvm/Object/Error.h" 
#include "llvm/Object/MachOUniversal.h" 
#include "llvm/Object/Minidump.h" 
#include "llvm/Object/ObjectFile.h" 
#include "llvm/Object/TapiUniversal.h" 
#include "llvm/Object/WindowsResource.h" 
#include "llvm/Support/Error.h" 
#include "llvm/Support/ErrorHandling.h" 
#include "llvm/Support/ErrorOr.h" 
#include "llvm/Support/FileSystem.h" 
#include "llvm/Support/MemoryBuffer.h" 
#include <algorithm> 
#include <memory> 
#include <system_error> 
 
using namespace llvm; 
using namespace object; 
 
Binary::~Binary() = default; 
 
Binary::Binary(unsigned int Type, MemoryBufferRef Source) 
    : TypeID(Type), Data(Source) {} 
 
StringRef Binary::getData() const { return Data.getBuffer(); } 
 
StringRef Binary::getFileName() const { return Data.getBufferIdentifier(); } 
 
MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; } 
 
Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer, 
                                                       LLVMContext *Context,
                                                       bool InitContent) {
  file_magic Type = identify_magic(Buffer.getBuffer()); 
 
  switch (Type) { 
  case file_magic::archive: 
    return Archive::create(Buffer); 
  case file_magic::elf: 
  case file_magic::elf_relocatable: 
  case file_magic::elf_executable: 
  case file_magic::elf_shared_object: 
  case file_magic::elf_core: 
  case file_magic::macho_object: 
  case file_magic::macho_executable: 
  case file_magic::macho_fixed_virtual_memory_shared_lib: 
  case file_magic::macho_core: 
  case file_magic::macho_preload_executable: 
  case file_magic::macho_dynamically_linked_shared_lib: 
  case file_magic::macho_dynamic_linker: 
  case file_magic::macho_bundle: 
  case file_magic::macho_dynamically_linked_shared_lib_stub: 
  case file_magic::macho_dsym_companion: 
  case file_magic::macho_kext_bundle: 
  case file_magic::coff_object: 
  case file_magic::coff_import_library: 
  case file_magic::pecoff_executable: 
  case file_magic::bitcode: 
  case file_magic::xcoff_object_32: 
  case file_magic::xcoff_object_64: 
  case file_magic::wasm_object: 
    return ObjectFile::createSymbolicFile(Buffer, Type, Context, InitContent);
  case file_magic::macho_universal_binary: 
    return MachOUniversalBinary::create(Buffer); 
  case file_magic::windows_resource: 
    return WindowsResource::createWindowsResource(Buffer); 
  case file_magic::pdb: 
    // PDB does not support the Binary interface. 
    return errorCodeToError(object_error::invalid_file_type); 
  case file_magic::unknown: 
  case file_magic::coff_cl_gl_object: 
    // Unrecognized object file format. 
    return errorCodeToError(object_error::invalid_file_type); 
  case file_magic::minidump: 
    return MinidumpFile::create(Buffer); 
  case file_magic::tapi_file: 
    return TapiUniversal::create(Buffer); 
  } 
  llvm_unreachable("Unexpected Binary File Type"); 
} 
 
Expected<OwningBinary<Binary>>
object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = 
      MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1, 
                                   /*RequiresNullTerminator=*/false); 
  if (std::error_code EC = FileOrErr.getError()) 
    return errorCodeToError(EC); 
  std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get(); 
 
  Expected<std::unique_ptr<Binary>> BinOrErr = 
      createBinary(Buffer->getMemBufferRef(), Context, InitContent);
  if (!BinOrErr) 
    return BinOrErr.takeError(); 
  std::unique_ptr<Binary> &Bin = BinOrErr.get(); 
 
  return OwningBinary<Binary>(std::move(Bin), std::move(Buffer)); 
}