diff options
Diffstat (limited to 'include/llvm/Object')
-rw-r--r-- | include/llvm/Object/Binary.h | 4 | ||||
-rw-r--r-- | include/llvm/Object/COFFImportFile.h | 34 | ||||
-rw-r--r-- | include/llvm/Object/COFFModuleDefinition.h | 49 | ||||
-rw-r--r-- | include/llvm/Object/Decompressor.h | 5 | ||||
-rw-r--r-- | include/llvm/Object/ELF.h | 5 | ||||
-rw-r--r-- | include/llvm/Object/RelocVisitor.h | 231 | ||||
-rw-r--r-- | include/llvm/Object/WindowsResource.h | 82 |
7 files changed, 269 insertions, 141 deletions
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index f42048e48ee3..cf5d93ee9ed7 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -57,6 +57,8 @@ protected: ID_MachO64L, // MachO 64-bit, little endian ID_MachO64B, // MachO 64-bit, big endian + ID_WinRes, // Windows resource (.res) file. + ID_Wasm, ID_EndObjects @@ -132,6 +134,8 @@ public: TypeID == ID_MachO32B || TypeID == ID_MachO64B); } + bool isWinRes() const { return TypeID == ID_WinRes; } + Triple::ObjectFormatType getTripleObjectFormat() const { if (isCOFF()) return Triple::COFF; diff --git a/include/llvm/Object/COFFImportFile.h b/include/llvm/Object/COFFImportFile.h index 78d9d679acd3..78044a2832fa 100644 --- a/include/llvm/Object/COFFImportFile.h +++ b/include/llvm/Object/COFFImportFile.h @@ -9,13 +9,15 @@ // // COFF short import file is a special kind of file which contains // only symbol names for DLL-exported symbols. This class implements -// SymbolicFile interface for the file. +// exporting of Symbols to create libraries and a SymbolicFile +// interface for the file type. // //===----------------------------------------------------------------------===// #ifndef LLVM_OBJECT_COFF_IMPORT_FILE_H #define LLVM_OBJECT_COFF_IMPORT_FILE_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/Object/COFF.h" #include "llvm/Object/IRObjectFile.h" #include "llvm/Object/ObjectFile.h" @@ -68,6 +70,36 @@ private: } }; +struct COFFShortExport { + std::string Name; + std::string ExtName; + + uint16_t Ordinal = 0; + bool Noname = false; + bool Data = false; + bool Private = false; + bool Constant = false; + + bool isWeak() { + return ExtName.size() && ExtName != Name; + } + + friend bool operator==(const COFFShortExport &L, const COFFShortExport &R) { + return L.Name == R.Name && L.ExtName == R.ExtName && + L.Ordinal == R.Ordinal && L.Noname == R.Noname && + L.Data == R.Data && L.Private == R.Private; + } + + friend bool operator!=(const COFFShortExport &L, const COFFShortExport &R) { + return !(L == R); + } +}; + +std::error_code writeImportLibrary(StringRef DLLName, + StringRef Path, + ArrayRef<COFFShortExport> Exports, + COFF::MachineTypes Machine); + } // namespace object } // namespace llvm diff --git a/include/llvm/Object/COFFModuleDefinition.h b/include/llvm/Object/COFFModuleDefinition.h new file mode 100644 index 000000000000..0428283fdc88 --- /dev/null +++ b/include/llvm/Object/COFFModuleDefinition.h @@ -0,0 +1,49 @@ +//===--- COFFModuleDefinition.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Windows-specific. +// A parser for the module-definition file (.def file). +// Parsed results are directly written to Config global variable. +// +// The format of module-definition files are described in this document: +// https://msdn.microsoft.com/en-us/library/28d6s79h.aspx +// +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_OBJECT_COFF_MODULE_DEFINITION_H +#define LLVM_OBJECT_COFF_MODULE_DEFINITION_H + +#include "llvm/Object/COFFImportFile.h" +#include "llvm/Object/COFF.h" + +namespace llvm { +namespace object { + +struct COFFModuleDefinition { + std::vector<COFFShortExport> Exports; + std::string OutputFile; + uint64_t ImageBase = 0; + uint64_t StackReserve = 0; + uint64_t StackCommit = 0; + uint64_t HeapReserve = 0; + uint64_t HeapCommit = 0; + uint32_t MajorImageVersion = 0; + uint32_t MinorImageVersion = 0; + uint32_t MajorOSVersion = 0; + uint32_t MinorOSVersion = 0; +}; + +Expected<COFFModuleDefinition> +parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine); + +} // End namespace object. +} // End namespace llvm. + +#endif diff --git a/include/llvm/Object/Decompressor.h b/include/llvm/Object/Decompressor.h index a11857d546aa..0f63f8b821b7 100644 --- a/include/llvm/Object/Decompressor.h +++ b/include/llvm/Object/Decompressor.h @@ -30,7 +30,10 @@ public: /// @brief Resize the buffer and uncompress section data into it. /// @param Out Destination buffer. - Error decompress(SmallString<32> &Out); + template <class T> Error resizeAndDecompress(T &Out) { + Out.resize(DecompressedSize); + return decompress({Out.data(), (size_t)DecompressedSize}); + } /// @brief Uncompress section data to raw buffer provided. /// @param Buffer Destination buffer. diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 42fdfe3e5a74..a4d431b6cbe7 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -235,10 +235,7 @@ ELFFile<ELFT>::getSection(const Elf_Sym *Sym, Elf_Sym_Range Symbols, uint32_t Index = *IndexOrErr; if (Index == 0) return nullptr; - auto SectionsOrErr = sections(); - if (!SectionsOrErr) - return SectionsOrErr.takeError(); - return object::getSection<ELFT>(*SectionsOrErr, Index); + return getSection(Index); } template <class ELFT> diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 73c7ce367cb0..86579b7c3e3a 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -32,18 +32,6 @@ namespace llvm { namespace object { -struct RelocToApply { - // The computed value after applying the relevant relocations. - int64_t Value = 0; - - // The width of the value; how many bytes to touch when applying the - // relocation. - char Width = 0; - - RelocToApply() = default; - RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {} -}; - /// @brief Base class for object file relocation visitors. class RelocVisitor { public: @@ -52,7 +40,7 @@ public: // TODO: Should handle multiple applied relocations via either passing in the // previously computed value or just count paired relocations as a single // visit. - RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t Value = 0) { + uint64_t visit(uint32_t RelocType, RelocationRef R, uint64_t Value = 0) { if (isa<ELFObjectFileBase>(ObjToVisit)) return visitELF(RelocType, R, Value); if (isa<COFFObjectFile>(ObjToVisit)) @@ -61,7 +49,7 @@ public: return visitMachO(RelocType, R, Value); HasError = true; - return RelocToApply(); + return 0; } bool error() { return HasError; } @@ -70,7 +58,7 @@ private: const ObjectFile &ObjToVisit; bool HasError = false; - RelocToApply visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) { + uint64_t visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) { if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file switch (ObjToVisit.getArch()) { case Triple::x86_64: @@ -87,7 +75,7 @@ private: return visitELF_X86_64_32S(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::aarch64: case Triple::aarch64_be: @@ -98,7 +86,7 @@ private: return visitELF_AARCH64_ABS64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::bpfel: case Triple::bpfeb: @@ -109,7 +97,7 @@ private: return visitELF_BPF_64_32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::mips64el: case Triple::mips64: @@ -120,7 +108,7 @@ private: return visitELF_MIPS64_64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::ppc64le: case Triple::ppc64: @@ -131,7 +119,7 @@ private: return visitELF_PPC64_ADDR64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::systemz: switch (RelocType) { @@ -141,7 +129,7 @@ private: return visitELF_390_64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::sparcv9: switch (RelocType) { @@ -153,7 +141,7 @@ private: return visitELF_SPARCV9_64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::amdgcn: switch (RelocType) { @@ -163,11 +151,11 @@ private: return visitELF_AMDGPU_ABS64(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } default: HasError = true; - return RelocToApply(); + return 0; } } else if (ObjToVisit.getBytesInAddress() == 4) { // 32-bit object file switch (ObjToVisit.getArch()) { @@ -181,7 +169,7 @@ private: return visitELF_386_PC32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::ppc: switch (RelocType) { @@ -189,14 +177,14 @@ private: return visitELF_PPC_ADDR32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::arm: case Triple::armeb: switch (RelocType) { default: HasError = true; - return RelocToApply(); + return 0; case ELF::R_ARM_ABS32: return visitELF_ARM_ABS32(R, Value); } @@ -206,7 +194,7 @@ private: return visitELF_Lanai_32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::mipsel: case Triple::mips: @@ -215,7 +203,7 @@ private: return visitELF_MIPS_32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::sparc: switch (RelocType) { @@ -224,7 +212,7 @@ private: return visitELF_SPARC_32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } case Triple::hexagon: switch (RelocType) { @@ -232,18 +220,18 @@ private: return visitELF_HEX_32(R, Value); default: HasError = true; - return RelocToApply(); + return 0; } default: HasError = true; - return RelocToApply(); + return 0; } } else { report_fatal_error("Invalid word size in object file"); } } - RelocToApply visitCOFF(uint32_t RelocType, RelocationRef R, uint64_t Value) { + uint64_t visitCOFF(uint32_t RelocType, RelocationRef R, uint64_t Value) { switch (ObjToVisit.getArch()) { case Triple::x86: switch (RelocType) { @@ -263,10 +251,10 @@ private: break; } HasError = true; - return RelocToApply(); + return 0; } - RelocToApply visitMachO(uint32_t RelocType, RelocationRef R, uint64_t Value) { + uint64_t visitMachO(uint32_t RelocType, RelocationRef R, uint64_t Value) { switch (ObjToVisit.getArch()) { default: break; case Triple::x86_64: @@ -277,7 +265,7 @@ private: } } HasError = true; - return RelocToApply(); + return 0; } int64_t getELFAddend(RelocationRef R) { @@ -287,108 +275,88 @@ private: return *AddendOrErr; } - uint8_t getLengthMachO64(RelocationRef R) { - const MachOObjectFile *Obj = cast<MachOObjectFile>(R.getObject()); - return Obj->getRelocationLength(R.getRawDataRefImpl()); - } - /// Operations /// 386-ELF - RelocToApply visitELF_386_NONE(RelocationRef R) { - return RelocToApply(0, 0); + uint64_t visitELF_386_NONE(RelocationRef R) { + return 0; } // Ideally the Addend here will be the addend in the data for // the relocation. It's not actually the case for Rel relocations. - RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) { - return RelocToApply(Value, 4); + uint64_t visitELF_386_32(RelocationRef R, uint64_t Value) { + return Value; } - RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value) { - uint64_t Address = R.getOffset(); - return RelocToApply(Value - Address, 4); + uint64_t visitELF_386_PC32(RelocationRef R, uint64_t Value) { + return Value - R.getOffset(); } /// X86-64 ELF - RelocToApply visitELF_X86_64_NONE(RelocationRef R) { - return RelocToApply(0, 0); + uint64_t visitELF_X86_64_NONE(RelocationRef R) { + return 0; } - RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + + uint64_t visitELF_X86_64_64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } - RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint64_t Address = R.getOffset(); - return RelocToApply(Value + Addend - Address, 4); + + uint64_t visitELF_X86_64_PC32(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R) - R.getOffset(); } - RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + + uint64_t visitELF_X86_64_32(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } - RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - int32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + + uint64_t visitELF_X86_64_32S(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } /// BPF ELF - RelocToApply visitELF_BPF_64_32(RelocationRef R, uint64_t Value) { - uint32_t Res = Value & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_BPF_64_32(RelocationRef R, uint64_t Value) { + return Value & 0xFFFFFFFF; } - RelocToApply visitELF_BPF_64_64(RelocationRef R, uint64_t Value) { - return RelocToApply(Value, 8); + + uint64_t visitELF_BPF_64_64(RelocationRef R, uint64_t Value) { + return Value; } /// PPC64 ELF - RelocToApply visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } - RelocToApply visitELF_PPC64_ADDR64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + + uint64_t visitELF_PPC64_ADDR64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } /// PPC32 ELF - RelocToApply visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } /// Lanai ELF - RelocToApply visitELF_Lanai_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_Lanai_32(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } /// MIPS ELF - RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) { - uint32_t Res = Value & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_MIPS_32(RelocationRef R, uint64_t Value) { + return Value & 0xFFFFFFFF; } /// MIPS64 ELF - RelocToApply visitELF_MIPS64_32(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint32_t Res = (Value + Addend) & 0xFFFFFFFF; - return RelocToApply(Res, 4); + uint64_t visitELF_MIPS64_32(RelocationRef R, uint64_t Value) { + return (Value + getELFAddend(R)) & 0xFFFFFFFF; } - RelocToApply visitELF_MIPS64_64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - uint64_t Res = (Value + Addend); - return RelocToApply(Res, 8); + uint64_t visitELF_MIPS64_64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } // AArch64 ELF - RelocToApply visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) { + uint64_t visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); int64_t Res = Value + Addend; @@ -396,16 +364,15 @@ private: if (Res < INT32_MIN || Res > UINT32_MAX) HasError = true; - return RelocToApply(static_cast<uint32_t>(Res), 4); + return static_cast<uint32_t>(Res); } - RelocToApply visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + uint64_t visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } // SystemZ ELF - RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) { + uint64_t visitELF_390_32(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); int64_t Res = Value + Addend; @@ -413,77 +380,71 @@ private: if (Res < INT32_MIN || Res > UINT32_MAX) HasError = true; - return RelocToApply(static_cast<uint32_t>(Res), 4); + return static_cast<uint32_t>(Res); } - RelocToApply visitELF_390_64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + uint64_t visitELF_390_64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } - RelocToApply visitELF_SPARC_32(RelocationRef R, uint32_t Value) { - int32_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 4); + uint64_t visitELF_SPARC_32(RelocationRef R, uint32_t Value) { + return Value + getELFAddend(R); } - RelocToApply visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) { - int32_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 4); + uint64_t visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } - RelocToApply visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) { - int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + uint64_t visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) { + return Value + getELFAddend(R); } - RelocToApply visitELF_ARM_ABS32(RelocationRef R, uint64_t Value) { + uint64_t visitELF_ARM_ABS32(RelocationRef R, uint64_t Value) { int64_t Res = Value; // Overflow check allows for both signed and unsigned interpretation. if (Res < INT32_MIN || Res > UINT32_MAX) HasError = true; - return RelocToApply(static_cast<uint32_t>(Res), 4); + return static_cast<uint32_t>(Res); } - RelocToApply visitELF_HEX_32(RelocationRef R, uint64_t Value) { + uint64_t visitELF_HEX_32(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 4); + return Value + Addend; } - RelocToApply visitELF_AMDGPU_ABS32(RelocationRef R, uint64_t Value) { + uint64_t visitELF_AMDGPU_ABS32(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 4); + return Value + Addend; } - RelocToApply visitELF_AMDGPU_ABS64(RelocationRef R, uint64_t Value) { + uint64_t visitELF_AMDGPU_ABS64(RelocationRef R, uint64_t Value) { int64_t Addend = getELFAddend(R); - return RelocToApply(Value + Addend, 8); + return Value + Addend; } /// I386 COFF - RelocToApply visitCOFF_I386_SECREL(RelocationRef R, uint64_t Value) { - return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4); + uint64_t visitCOFF_I386_SECREL(RelocationRef R, uint64_t Value) { + return static_cast<uint32_t>(Value); } - RelocToApply visitCOFF_I386_DIR32(RelocationRef R, uint64_t Value) { - return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4); + uint64_t visitCOFF_I386_DIR32(RelocationRef R, uint64_t Value) { + return static_cast<uint32_t>(Value); } /// AMD64 COFF - RelocToApply visitCOFF_AMD64_SECREL(RelocationRef R, uint64_t Value) { - return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4); + uint64_t visitCOFF_AMD64_SECREL(RelocationRef R, uint64_t Value) { + return static_cast<uint32_t>(Value); } - RelocToApply visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) { - return RelocToApply(Value, /*Width=*/8); + uint64_t visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) { + return Value; } // X86_64 MachO - RelocToApply visitMACHO_X86_64_UNSIGNED(RelocationRef R, uint64_t Value) { - uint8_t Length = getLengthMachO64(R); - Length = 1<<Length; - return RelocToApply(Value, Length); + uint64_t visitMACHO_X86_64_UNSIGNED(RelocationRef R, uint64_t Value) { + return Value; } }; diff --git a/include/llvm/Object/WindowsResource.h b/include/llvm/Object/WindowsResource.h new file mode 100644 index 000000000000..f94ad09ce0c6 --- /dev/null +++ b/include/llvm/Object/WindowsResource.h @@ -0,0 +1,82 @@ +//===-- WindowsResource.h ---------------------------------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// This file declares the .res file class. .res files are intermediate +// products of the typical resource-compilation process on Windows. This +// process is as follows: +// +// .rc file(s) ---(rc.exe)---> .res file(s) ---(cvtres.exe)---> COFF file +// +// .rc files are human-readable scripts that list all resources a program uses. +// +// They are compiled into .res files, which are a list of the resources in +// binary form. +// +// Finally the data stored in the .res is compiled into a COFF file, where it +// is organized in a directory tree structure for optimized access by the +// program during runtime. +// +// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx +// +//===---------------------------------------------------------------------===// + +#ifndef LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H +#define LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Object/Binary.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace object { + +class WindowsResource; + +class ResourceEntryRef { +public: + Error moveNext(bool &End); + +private: + friend class WindowsResource; + + ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner, + Error &Err); + Error loadNext(); + + BinaryStreamReader Reader; + BinaryStreamRef HeaderBytes; + BinaryStreamRef DataBytes; + const WindowsResource *OwningRes = nullptr; +}; + +class WindowsResource : public Binary { +public: + ~WindowsResource() override; + Expected<ResourceEntryRef> getHeadEntry(); + + static bool classof(const Binary *V) { return V->isWinRes(); } + + static Expected<std::unique_ptr<WindowsResource>> + createWindowsResource(MemoryBufferRef Source); + +private: + friend class ResourceEntryRef; + + WindowsResource(MemoryBufferRef Source); + + BinaryByteStream BBS; +}; + +} // namespace object +} // namespace llvm + +#endif |