10b57cec5SDimitry Andric //===- SymbolicFile.cpp - Interface that only provides symbols ------------===//
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 a file format independent SymbolicFile class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm/Object/SymbolicFile.h"
140b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
150b57cec5SDimitry Andric #include "llvm/BinaryFormat/Magic.h"
160b57cec5SDimitry Andric #include "llvm/Object/COFFImportFile.h"
170b57cec5SDimitry Andric #include "llvm/Object/Error.h"
180b57cec5SDimitry Andric #include "llvm/Object/IRObjectFile.h"
190b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h"
200b57cec5SDimitry Andric #include "llvm/Support/Error.h"
210b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
220b57cec5SDimitry Andric #include <memory>
230b57cec5SDimitry Andric
240b57cec5SDimitry Andric using namespace llvm;
250b57cec5SDimitry Andric using namespace object;
260b57cec5SDimitry Andric
2781ad6265SDimitry Andric namespace llvm {
2881ad6265SDimitry Andric class LLVMContext;
2981ad6265SDimitry Andric }
3081ad6265SDimitry Andric
SymbolicFile(unsigned int Type,MemoryBufferRef Source)310b57cec5SDimitry Andric SymbolicFile::SymbolicFile(unsigned int Type, MemoryBufferRef Source)
320b57cec5SDimitry Andric : Binary(Type, Source) {}
330b57cec5SDimitry Andric
340b57cec5SDimitry Andric SymbolicFile::~SymbolicFile() = default;
350b57cec5SDimitry Andric
360b57cec5SDimitry Andric Expected<std::unique_ptr<SymbolicFile>>
createSymbolicFile(MemoryBufferRef Object,file_magic Type,LLVMContext * Context,bool InitContent)370b57cec5SDimitry Andric SymbolicFile::createSymbolicFile(MemoryBufferRef Object, file_magic Type,
38e8d8bef9SDimitry Andric LLVMContext *Context, bool InitContent) {
390b57cec5SDimitry Andric StringRef Data = Object.getBuffer();
400b57cec5SDimitry Andric if (Type == file_magic::unknown)
410b57cec5SDimitry Andric Type = identify_magic(Data);
420b57cec5SDimitry Andric
43e8d8bef9SDimitry Andric if (!isSymbolicFile(Type, Context))
44e8d8bef9SDimitry Andric return errorCodeToError(object_error::invalid_file_type);
45e8d8bef9SDimitry Andric
460b57cec5SDimitry Andric switch (Type) {
470b57cec5SDimitry Andric case file_magic::bitcode:
48e8d8bef9SDimitry Andric // Context is guaranteed to be non-null here, because bitcode magic only
49e8d8bef9SDimitry Andric // indicates a symbolic file when Context is non-null.
500b57cec5SDimitry Andric return IRObjectFile::create(Object, *Context);
510b57cec5SDimitry Andric case file_magic::elf:
520b57cec5SDimitry Andric case file_magic::elf_executable:
530b57cec5SDimitry Andric case file_magic::elf_shared_object:
540b57cec5SDimitry Andric case file_magic::elf_core:
55fe6060f1SDimitry Andric case file_magic::goff_object:
560b57cec5SDimitry Andric case file_magic::macho_executable:
570b57cec5SDimitry Andric case file_magic::macho_fixed_virtual_memory_shared_lib:
580b57cec5SDimitry Andric case file_magic::macho_core:
590b57cec5SDimitry Andric case file_magic::macho_preload_executable:
600b57cec5SDimitry Andric case file_magic::macho_dynamically_linked_shared_lib:
610b57cec5SDimitry Andric case file_magic::macho_dynamic_linker:
620b57cec5SDimitry Andric case file_magic::macho_bundle:
630b57cec5SDimitry Andric case file_magic::macho_dynamically_linked_shared_lib_stub:
640b57cec5SDimitry Andric case file_magic::macho_dsym_companion:
650b57cec5SDimitry Andric case file_magic::macho_kext_bundle:
66*bdd1243dSDimitry Andric case file_magic::macho_file_set:
670b57cec5SDimitry Andric case file_magic::pecoff_executable:
680b57cec5SDimitry Andric case file_magic::xcoff_object_32:
690b57cec5SDimitry Andric case file_magic::xcoff_object_64:
700b57cec5SDimitry Andric case file_magic::wasm_object:
71e8d8bef9SDimitry Andric return ObjectFile::createObjectFile(Object, Type, InitContent);
720b57cec5SDimitry Andric case file_magic::coff_import_library:
730b57cec5SDimitry Andric return std::unique_ptr<SymbolicFile>(new COFFImportFile(Object));
740b57cec5SDimitry Andric case file_magic::elf_relocatable:
750b57cec5SDimitry Andric case file_magic::macho_object:
760b57cec5SDimitry Andric case file_magic::coff_object: {
770b57cec5SDimitry Andric Expected<std::unique_ptr<ObjectFile>> Obj =
78e8d8bef9SDimitry Andric ObjectFile::createObjectFile(Object, Type, InitContent);
790b57cec5SDimitry Andric if (!Obj || !Context)
800b57cec5SDimitry Andric return std::move(Obj);
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric Expected<MemoryBufferRef> BCData =
830b57cec5SDimitry Andric IRObjectFile::findBitcodeInObject(*Obj->get());
840b57cec5SDimitry Andric if (!BCData) {
850b57cec5SDimitry Andric consumeError(BCData.takeError());
860b57cec5SDimitry Andric return std::move(Obj);
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric return IRObjectFile::create(
900b57cec5SDimitry Andric MemoryBufferRef(BCData->getBuffer(), Object.getBufferIdentifier()),
910b57cec5SDimitry Andric *Context);
920b57cec5SDimitry Andric }
93e8d8bef9SDimitry Andric default:
940b57cec5SDimitry Andric llvm_unreachable("Unexpected Binary File Type");
950b57cec5SDimitry Andric }
96e8d8bef9SDimitry Andric }
97e8d8bef9SDimitry Andric
isSymbolicFile(file_magic Type,const LLVMContext * Context)98e8d8bef9SDimitry Andric bool SymbolicFile::isSymbolicFile(file_magic Type, const LLVMContext *Context) {
99e8d8bef9SDimitry Andric switch (Type) {
100e8d8bef9SDimitry Andric case file_magic::bitcode:
101e8d8bef9SDimitry Andric return Context != nullptr;
102e8d8bef9SDimitry Andric case file_magic::elf:
103e8d8bef9SDimitry Andric case file_magic::elf_executable:
104e8d8bef9SDimitry Andric case file_magic::elf_shared_object:
105e8d8bef9SDimitry Andric case file_magic::elf_core:
106fe6060f1SDimitry Andric case file_magic::goff_object:
107e8d8bef9SDimitry Andric case file_magic::macho_executable:
108e8d8bef9SDimitry Andric case file_magic::macho_fixed_virtual_memory_shared_lib:
109e8d8bef9SDimitry Andric case file_magic::macho_core:
110e8d8bef9SDimitry Andric case file_magic::macho_preload_executable:
111e8d8bef9SDimitry Andric case file_magic::macho_dynamically_linked_shared_lib:
112e8d8bef9SDimitry Andric case file_magic::macho_dynamic_linker:
113e8d8bef9SDimitry Andric case file_magic::macho_bundle:
114e8d8bef9SDimitry Andric case file_magic::macho_dynamically_linked_shared_lib_stub:
115e8d8bef9SDimitry Andric case file_magic::macho_dsym_companion:
116e8d8bef9SDimitry Andric case file_magic::macho_kext_bundle:
117*bdd1243dSDimitry Andric case file_magic::macho_file_set:
118e8d8bef9SDimitry Andric case file_magic::pecoff_executable:
119e8d8bef9SDimitry Andric case file_magic::xcoff_object_32:
120e8d8bef9SDimitry Andric case file_magic::xcoff_object_64:
121e8d8bef9SDimitry Andric case file_magic::wasm_object:
122e8d8bef9SDimitry Andric case file_magic::coff_import_library:
123e8d8bef9SDimitry Andric case file_magic::elf_relocatable:
124e8d8bef9SDimitry Andric case file_magic::macho_object:
125e8d8bef9SDimitry Andric case file_magic::coff_object:
126e8d8bef9SDimitry Andric return true;
127e8d8bef9SDimitry Andric default:
128e8d8bef9SDimitry Andric return false;
129e8d8bef9SDimitry Andric }
130e8d8bef9SDimitry Andric }
131