// // This file is distributed under the MIT License. See LICENSE.md for details. // #include "llvm/Object/Archive.h" #include "llvm/Object/Binary.h" #include "llvm/Object/COFF.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" #include "revng/Model/Importer/Binary/BinaryImporter.h" #include "revng/Model/Importer/Binary/Options.h" #include "Importers.h" using namespace llvm; Error importBinary(TupleTree &Model, llvm::object::ObjectFile &ObjectFile, llvm::StringRef Filepath, const ImporterOptions &Options, model::BinaryReference &BinaryReference) { using namespace llvm::object; using namespace model::Architecture; // If we have segments, we already imported a binary, bail out. if (Model->Segments().size() > 0) return Error::success(); Model->Architecture() = fromLLVMArchitecture(ObjectFile.getArch()); if (Model->Architecture() == model::Architecture::Invalid) return revng::createError("Invalid architecture"); llvm::Error Result = Error::success(); revng_check(not Result); if (auto *TheBinary = dyn_cast(&ObjectFile)) { ELFBinary Binary(*TheBinary, ObjectFile.getMemoryBufferRef(), Filepath, BinaryReference); Result = importELF(Model, Binary, Options); } else if (auto *TheBinary = dyn_cast(&ObjectFile)) { COFFBinary Binary(*TheBinary, ObjectFile.getMemoryBufferRef(), Filepath, BinaryReference); Result = importPECOFF(Model, Binary, Options); } else if (auto *TheBinary = dyn_cast(&ObjectFile)) { MachOBinary Binary(*TheBinary, ObjectFile.getMemoryBufferRef(), Filepath, BinaryReference); Result = importMachO(Model, Binary, Options); } else { return revng::createError("Unsupported binary format"); } if (Result) return Result; // If we got an EntryPoint, ensure we also have Function for it if (Model->EntryPoint().isValid()) Model->Functions()[Model->EntryPoint()]; return Result; } Error importBinary(TupleTree &Model, llvm::MemoryBuffer &Buffer, llvm::StringRef Filepath, const ImporterOptions &Options, model::BinaryReference &BinaryReference) { auto BinaryOrError = object::createBinary(Buffer); if (not BinaryOrError) return BinaryOrError.takeError(); llvm::object::Binary &Binary = *BinaryOrError->get(); if (isa(Binary)) { return revng::createError("Unsupported format: MachO universal binary."); } else if (isa(Binary)) { return revng::createError("Unsupported format: archive."); } else if (not isa(Binary)) { return revng::createError("Unsupported format"); } return importBinary(Model, cast(Binary), Filepath, Options, BinaryReference); }