Binary.cpp 4.1 KB

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