Binary.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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/OffloadBinary.h"
  21. #include "llvm/Object/TapiUniversal.h"
  22. #include "llvm/Object/WindowsResource.h"
  23. #include "llvm/Support/Error.h"
  24. #include "llvm/Support/ErrorHandling.h"
  25. #include "llvm/Support/ErrorOr.h"
  26. #include "llvm/Support/MemoryBuffer.h"
  27. #include <memory>
  28. #include <system_error>
  29. using namespace llvm;
  30. using namespace object;
  31. Binary::~Binary() = default;
  32. Binary::Binary(unsigned int Type, MemoryBufferRef Source)
  33. : TypeID(Type), Data(Source) {}
  34. StringRef Binary::getData() const { return Data.getBuffer(); }
  35. StringRef Binary::getFileName() const { return Data.getBufferIdentifier(); }
  36. MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; }
  37. Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
  38. LLVMContext *Context,
  39. bool InitContent) {
  40. file_magic Type = identify_magic(Buffer.getBuffer());
  41. switch (Type) {
  42. case file_magic::archive:
  43. return Archive::create(Buffer);
  44. case file_magic::elf:
  45. case file_magic::elf_relocatable:
  46. case file_magic::elf_executable:
  47. case file_magic::elf_shared_object:
  48. case file_magic::elf_core:
  49. case file_magic::goff_object:
  50. case file_magic::macho_object:
  51. case file_magic::macho_executable:
  52. case file_magic::macho_fixed_virtual_memory_shared_lib:
  53. case file_magic::macho_core:
  54. case file_magic::macho_preload_executable:
  55. case file_magic::macho_dynamically_linked_shared_lib:
  56. case file_magic::macho_dynamic_linker:
  57. case file_magic::macho_bundle:
  58. case file_magic::macho_dynamically_linked_shared_lib_stub:
  59. case file_magic::macho_dsym_companion:
  60. case file_magic::macho_kext_bundle:
  61. case file_magic::macho_file_set:
  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::cuda_fatbinary:
  79. case file_magic::coff_cl_gl_object:
  80. case file_magic::dxcontainer_object:
  81. // Unrecognized object file format.
  82. return errorCodeToError(object_error::invalid_file_type);
  83. case file_magic::offload_binary:
  84. return OffloadBinary::create(Buffer);
  85. case file_magic::minidump:
  86. return MinidumpFile::create(Buffer);
  87. case file_magic::tapi_file:
  88. return TapiUniversal::create(Buffer);
  89. }
  90. llvm_unreachable("Unexpected Binary File Type");
  91. }
  92. Expected<OwningBinary<Binary>>
  93. object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
  94. ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
  95. MemoryBuffer::getFileOrSTDIN(Path, /*IsText=*/false,
  96. /*RequiresNullTerminator=*/false);
  97. if (std::error_code EC = FileOrErr.getError())
  98. return errorCodeToError(EC);
  99. std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
  100. Expected<std::unique_ptr<Binary>> BinOrErr =
  101. createBinary(Buffer->getMemBufferRef(), Context, InitContent);
  102. if (!BinOrErr)
  103. return BinOrErr.takeError();
  104. std::unique_ptr<Binary> &Bin = BinOrErr.get();
  105. return OwningBinary<Binary>(std::move(Bin), std::move(Buffer));
  106. }