xref: /freebsd-src/contrib/llvm-project/llvm/lib/Object/Binary.cpp (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
10b57cec5SDimitry Andric //===- Binary.cpp - A generic binary file ---------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the Binary class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/Object/Binary.h"
140b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
150b57cec5SDimitry Andric #include "llvm/BinaryFormat/Magic.h"
160b57cec5SDimitry Andric #include "llvm/Object/Archive.h"
170b57cec5SDimitry Andric #include "llvm/Object/Error.h"
180b57cec5SDimitry Andric #include "llvm/Object/MachOUniversal.h"
190b57cec5SDimitry Andric #include "llvm/Object/Minidump.h"
200b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h"
2181ad6265SDimitry Andric #include "llvm/Object/OffloadBinary.h"
228bcb0991SDimitry Andric #include "llvm/Object/TapiUniversal.h"
230b57cec5SDimitry Andric #include "llvm/Object/WindowsResource.h"
240b57cec5SDimitry Andric #include "llvm/Support/Error.h"
250b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
260b57cec5SDimitry Andric #include "llvm/Support/ErrorOr.h"
270b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
280b57cec5SDimitry Andric #include <memory>
290b57cec5SDimitry Andric #include <system_error>
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric using namespace llvm;
320b57cec5SDimitry Andric using namespace object;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric Binary::~Binary() = default;
350b57cec5SDimitry Andric 
Binary(unsigned int Type,MemoryBufferRef Source)360b57cec5SDimitry Andric Binary::Binary(unsigned int Type, MemoryBufferRef Source)
370b57cec5SDimitry Andric     : TypeID(Type), Data(Source) {}
380b57cec5SDimitry Andric 
getData() const390b57cec5SDimitry Andric StringRef Binary::getData() const { return Data.getBuffer(); }
400b57cec5SDimitry Andric 
getFileName() const410b57cec5SDimitry Andric StringRef Binary::getFileName() const { return Data.getBufferIdentifier(); }
420b57cec5SDimitry Andric 
getMemoryBufferRef() const430b57cec5SDimitry Andric MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; }
440b57cec5SDimitry Andric 
createBinary(MemoryBufferRef Buffer,LLVMContext * Context,bool InitContent)450b57cec5SDimitry Andric Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
46e8d8bef9SDimitry Andric                                                        LLVMContext *Context,
47e8d8bef9SDimitry Andric                                                        bool InitContent) {
480b57cec5SDimitry Andric   file_magic Type = identify_magic(Buffer.getBuffer());
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   switch (Type) {
510b57cec5SDimitry Andric   case file_magic::archive:
520b57cec5SDimitry Andric     return Archive::create(Buffer);
530b57cec5SDimitry Andric   case file_magic::elf:
540b57cec5SDimitry Andric   case file_magic::elf_relocatable:
550b57cec5SDimitry Andric   case file_magic::elf_executable:
560b57cec5SDimitry Andric   case file_magic::elf_shared_object:
570b57cec5SDimitry Andric   case file_magic::elf_core:
58fe6060f1SDimitry Andric   case file_magic::goff_object:
590b57cec5SDimitry Andric   case file_magic::macho_object:
600b57cec5SDimitry Andric   case file_magic::macho_executable:
610b57cec5SDimitry Andric   case file_magic::macho_fixed_virtual_memory_shared_lib:
620b57cec5SDimitry Andric   case file_magic::macho_core:
630b57cec5SDimitry Andric   case file_magic::macho_preload_executable:
640b57cec5SDimitry Andric   case file_magic::macho_dynamically_linked_shared_lib:
650b57cec5SDimitry Andric   case file_magic::macho_dynamic_linker:
660b57cec5SDimitry Andric   case file_magic::macho_bundle:
670b57cec5SDimitry Andric   case file_magic::macho_dynamically_linked_shared_lib_stub:
680b57cec5SDimitry Andric   case file_magic::macho_dsym_companion:
690b57cec5SDimitry Andric   case file_magic::macho_kext_bundle:
70bdd1243dSDimitry Andric   case file_magic::macho_file_set:
710b57cec5SDimitry Andric   case file_magic::coff_object:
720b57cec5SDimitry Andric   case file_magic::coff_import_library:
730b57cec5SDimitry Andric   case file_magic::pecoff_executable:
740b57cec5SDimitry Andric   case file_magic::bitcode:
750b57cec5SDimitry Andric   case file_magic::xcoff_object_32:
760b57cec5SDimitry Andric   case file_magic::xcoff_object_64:
770b57cec5SDimitry Andric   case file_magic::wasm_object:
78e8d8bef9SDimitry Andric     return ObjectFile::createSymbolicFile(Buffer, Type, Context, InitContent);
790b57cec5SDimitry Andric   case file_magic::macho_universal_binary:
800b57cec5SDimitry Andric     return MachOUniversalBinary::create(Buffer);
810b57cec5SDimitry Andric   case file_magic::windows_resource:
820b57cec5SDimitry Andric     return WindowsResource::createWindowsResource(Buffer);
830b57cec5SDimitry Andric   case file_magic::pdb:
840b57cec5SDimitry Andric     // PDB does not support the Binary interface.
850b57cec5SDimitry Andric     return errorCodeToError(object_error::invalid_file_type);
860b57cec5SDimitry Andric   case file_magic::unknown:
87*7a6dacacSDimitry Andric   case file_magic::clang_ast:
8881ad6265SDimitry Andric   case file_magic::cuda_fatbinary:
890b57cec5SDimitry Andric   case file_magic::coff_cl_gl_object:
9081ad6265SDimitry Andric   case file_magic::dxcontainer_object:
915f757f3fSDimitry Andric   case file_magic::offload_bundle:
925f757f3fSDimitry Andric   case file_magic::offload_bundle_compressed:
935f757f3fSDimitry Andric   case file_magic::spirv_object:
940b57cec5SDimitry Andric     // Unrecognized object file format.
950b57cec5SDimitry Andric     return errorCodeToError(object_error::invalid_file_type);
9681ad6265SDimitry Andric   case file_magic::offload_binary:
9781ad6265SDimitry Andric     return OffloadBinary::create(Buffer);
980b57cec5SDimitry Andric   case file_magic::minidump:
990b57cec5SDimitry Andric     return MinidumpFile::create(Buffer);
1008bcb0991SDimitry Andric   case file_magic::tapi_file:
1018bcb0991SDimitry Andric     return TapiUniversal::create(Buffer);
1020b57cec5SDimitry Andric   }
1030b57cec5SDimitry Andric   llvm_unreachable("Unexpected Binary File Type");
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
106e8d8bef9SDimitry Andric Expected<OwningBinary<Binary>>
createBinary(StringRef Path,LLVMContext * Context,bool InitContent)107e8d8bef9SDimitry Andric object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
1080b57cec5SDimitry Andric   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
109fe6060f1SDimitry Andric       MemoryBuffer::getFileOrSTDIN(Path, /*IsText=*/false,
1100b57cec5SDimitry Andric                                    /*RequiresNullTerminator=*/false);
1110b57cec5SDimitry Andric   if (std::error_code EC = FileOrErr.getError())
1120b57cec5SDimitry Andric     return errorCodeToError(EC);
1130b57cec5SDimitry Andric   std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric   Expected<std::unique_ptr<Binary>> BinOrErr =
116e8d8bef9SDimitry Andric       createBinary(Buffer->getMemBufferRef(), Context, InitContent);
1170b57cec5SDimitry Andric   if (!BinOrErr)
1180b57cec5SDimitry Andric     return BinOrErr.takeError();
1190b57cec5SDimitry Andric   std::unique_ptr<Binary> &Bin = BinOrErr.get();
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   return OwningBinary<Binary>(std::move(Bin), std::move(Buffer));
1220b57cec5SDimitry Andric }
123