blob: fe41987f5c277c66e39388819071f40476d2c63e [file] [log] [blame]
Eugene Zelenko86bfc782017-04-19 23:02:10 +00001//===- Binary.cpp - A generic binary file ---------------------------------===//
Michael J. Spencerc44c9152011-06-25 17:54:29 +00002//
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
Chandler Carruthe3e43d92017-06-06 11:49:48 +000014#include "llvm/Object/Binary.h"
Michael J. Spencerc44c9152011-06-25 17:54:29 +000015#include "llvm/ADT/StringRef.h"
Zachary Turner19ca2b02017-06-07 03:48:56 +000016#include "llvm/BinaryFormat/Magic.h"
Michael J. Spencera51d7d92011-09-27 19:36:55 +000017#include "llvm/Object/Archive.h"
Eugene Zelenko86bfc782017-04-19 23:02:10 +000018#include "llvm/Object/Error.h"
Alexey Samsonov9c22f872013-06-18 15:03:28 +000019#include "llvm/Object/MachOUniversal.h"
Michael J. Spencera51d7d92011-09-27 19:36:55 +000020#include "llvm/Object/ObjectFile.h"
Eric Beckmann836dd8e2017-05-20 01:49:19 +000021#include "llvm/Object/WindowsResource.h"
Eugene Zelenko86bfc782017-04-19 23:02:10 +000022#include "llvm/Support/Error.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/ErrorOr.h"
25#include "llvm/Support/FileSystem.h"
26#include "llvm/Support/MemoryBuffer.h"
27#include <algorithm>
28#include <memory>
29#include <system_error>
Michael J. Spencer001c9202011-06-25 17:54:50 +000030
Michael J. Spencerc44c9152011-06-25 17:54:29 +000031using namespace llvm;
32using namespace object;
33
Eugene Zelenko86bfc782017-04-19 23:02:10 +000034Binary::~Binary() = default;
Michael J. Spencerc44c9152011-06-25 17:54:29 +000035
Rafael Espindola548f2b62014-08-19 18:44:46 +000036Binary::Binary(unsigned int Type, MemoryBufferRef Source)
37 : TypeID(Type), Data(Source) {}
Michael J. Spencerc44c9152011-06-25 17:54:29 +000038
Rafael Espindola548f2b62014-08-19 18:44:46 +000039StringRef Binary::getData() const { return Data.getBuffer(); }
Michael J. Spencerc44c9152011-06-25 17:54:29 +000040
Rafael Espindola548f2b62014-08-19 18:44:46 +000041StringRef Binary::getFileName() const { return Data.getBufferIdentifier(); }
Michael J. Spencerc44c9152011-06-25 17:54:29 +000042
Rafael Espindola548f2b62014-08-19 18:44:46 +000043MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; }
44
Kevin Enderbyc6bf9be2016-04-06 22:14:09 +000045Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
Rafael Espindola548f2b62014-08-19 18:44:46 +000046 LLVMContext *Context) {
Zachary Turner19ca2b02017-06-07 03:48:56 +000047 file_magic Type = identify_magic(Buffer.getBuffer());
Rafael Espindola2edc3a62014-01-22 16:04:52 +000048
49 switch (Type) {
Zachary Turner19ca2b02017-06-07 03:48:56 +000050 case file_magic::archive:
51 return Archive::create(Buffer);
52 case file_magic::elf:
53 case file_magic::elf_relocatable:
54 case file_magic::elf_executable:
55 case file_magic::elf_shared_object:
56 case file_magic::elf_core:
57 case file_magic::macho_object:
58 case file_magic::macho_executable:
59 case file_magic::macho_fixed_virtual_memory_shared_lib:
60 case file_magic::macho_core:
61 case file_magic::macho_preload_executable:
62 case file_magic::macho_dynamically_linked_shared_lib:
63 case file_magic::macho_dynamic_linker:
64 case file_magic::macho_bundle:
65 case file_magic::macho_dynamically_linked_shared_lib_stub:
66 case file_magic::macho_dsym_companion:
67 case file_magic::macho_kext_bundle:
68 case file_magic::coff_object:
69 case file_magic::coff_import_library:
70 case file_magic::pecoff_executable:
71 case file_magic::bitcode:
72 case file_magic::wasm_object:
73 return ObjectFile::createSymbolicFile(Buffer, Type, Context);
74 case file_magic::macho_universal_binary:
75 return MachOUniversalBinary::create(Buffer);
76 case file_magic::windows_resource:
77 return WindowsResource::createWindowsResource(Buffer);
Zachary Turnera896ada2018-03-07 18:58:33 +000078 case file_magic::pdb:
79 // PDB does not support the Binary interface.
80 return errorCodeToError(object_error::invalid_file_type);
Zachary Turner19ca2b02017-06-07 03:48:56 +000081 case file_magic::unknown:
82 case file_magic::coff_cl_gl_object:
83 // Unrecognized object file format.
84 return errorCodeToError(object_error::invalid_file_type);
Michael J. Spencer001c9202011-06-25 17:54:50 +000085 }
Alexey Samsonovf49d8fc2013-06-28 09:44:05 +000086 llvm_unreachable("Unexpected Binary File Type");
Michael J. Spencerc44c9152011-06-25 17:54:29 +000087}
88
Kevin Enderbyc6bf9be2016-04-06 22:14:09 +000089Expected<OwningBinary<Binary>> object::createBinary(StringRef Path) {
Rafael Espindola7cba2a92014-07-06 17:43:13 +000090 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
David Majoraf085b42019-01-09 23:36:32 +000091 MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1,
92 /*RequiresNullTerminator=*/false);
Rafael Espindola7cba2a92014-07-06 17:43:13 +000093 if (std::error_code EC = FileOrErr.getError())
Kevin Enderbyc6bf9be2016-04-06 22:14:09 +000094 return errorCodeToError(EC);
Rafael Espindola548f2b62014-08-19 18:44:46 +000095 std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
96
Kevin Enderbyc6bf9be2016-04-06 22:14:09 +000097 Expected<std::unique_ptr<Binary>> BinOrErr =
Rafael Espindola548f2b62014-08-19 18:44:46 +000098 createBinary(Buffer->getMemBufferRef());
Kevin Enderbyc6bf9be2016-04-06 22:14:09 +000099 if (!BinOrErr)
100 return BinOrErr.takeError();
Rafael Espindola548f2b62014-08-19 18:44:46 +0000101 std::unique_ptr<Binary> &Bin = BinOrErr.get();
102
103 return OwningBinary<Binary>(std::move(Bin), std::move(Buffer));
Michael J. Spencerc44c9152011-06-25 17:54:29 +0000104}