Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-- WindowsResource.h ---------------------------------------*- C++-*-===//
  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 declares the .res file class.  .res files are intermediate
  10. // products of the typical resource-compilation process on Windows.  This
  11. // process is as follows:
  12. //
  13. // .rc file(s) ---(rc.exe)---> .res file(s) ---(cvtres.exe)---> COFF file
  14. //
  15. // .rc files are human-readable scripts that list all resources a program uses.
  16. //
  17. // They are compiled into .res files, which are a list of the resources in
  18. // binary form.
  19. //
  20. // Finally the data stored in the .res is compiled into a COFF file, where it
  21. // is organized in a directory tree structure for optimized access by the
  22. // program during runtime.
  23. //
  24. // Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx
  25. //
  26. //===---------------------------------------------------------------------===//
  27.  
  28. #ifndef LLVM_OBJECT_WINDOWSRESOURCE_H
  29. #define LLVM_OBJECT_WINDOWSRESOURCE_H
  30.  
  31. #include "llvm/ADT/ArrayRef.h"
  32. #include "llvm/BinaryFormat/COFF.h"
  33. #include "llvm/Object/Binary.h"
  34. #include "llvm/Object/Error.h"
  35. #include "llvm/Support/BinaryByteStream.h"
  36. #include "llvm/Support/BinaryStreamReader.h"
  37. #include "llvm/Support/ConvertUTF.h"
  38. #include "llvm/Support/Endian.h"
  39. #include "llvm/Support/Error.h"
  40.  
  41. #include <map>
  42.  
  43. namespace llvm {
  44.  
  45. class raw_ostream;
  46. class ScopedPrinter;
  47.  
  48. namespace object {
  49.  
  50. class WindowsResource;
  51. class ResourceSectionRef;
  52. struct coff_resource_dir_table;
  53.  
  54. const size_t WIN_RES_MAGIC_SIZE = 16;
  55. const size_t WIN_RES_NULL_ENTRY_SIZE = 16;
  56. const uint32_t WIN_RES_HEADER_ALIGNMENT = 4;
  57. const uint32_t WIN_RES_DATA_ALIGNMENT = 4;
  58. const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030;
  59.  
  60. struct WinResHeaderPrefix {
  61.   support::ulittle32_t DataSize;
  62.   support::ulittle32_t HeaderSize;
  63. };
  64.  
  65. // Type and Name may each either be an integer ID or a string.  This struct is
  66. // only used in the case where they are both IDs.
  67. struct WinResIDs {
  68.   uint16_t TypeFlag;
  69.   support::ulittle16_t TypeID;
  70.   uint16_t NameFlag;
  71.   support::ulittle16_t NameID;
  72.  
  73.   void setType(uint16_t ID) {
  74.     TypeFlag = 0xffff;
  75.     TypeID = ID;
  76.   }
  77.  
  78.   void setName(uint16_t ID) {
  79.     NameFlag = 0xffff;
  80.     NameID = ID;
  81.   }
  82. };
  83.  
  84. struct WinResHeaderSuffix {
  85.   support::ulittle32_t DataVersion;
  86.   support::ulittle16_t MemoryFlags;
  87.   support::ulittle16_t Language;
  88.   support::ulittle32_t Version;
  89.   support::ulittle32_t Characteristics;
  90. };
  91.  
  92. class EmptyResError : public GenericBinaryError {
  93. public:
  94.   EmptyResError(Twine Msg, object_error ECOverride)
  95.       : GenericBinaryError(Msg, ECOverride) {}
  96. };
  97.  
  98. class ResourceEntryRef {
  99. public:
  100.   Error moveNext(bool &End);
  101.   bool checkTypeString() const { return IsStringType; }
  102.   ArrayRef<UTF16> getTypeString() const { return Type; }
  103.   uint16_t getTypeID() const { return TypeID; }
  104.   bool checkNameString() const { return IsStringName; }
  105.   ArrayRef<UTF16> getNameString() const { return Name; }
  106.   uint16_t getNameID() const { return NameID; }
  107.   uint16_t getDataVersion() const { return Suffix->DataVersion; }
  108.   uint16_t getLanguage() const { return Suffix->Language; }
  109.   uint16_t getMemoryFlags() const { return Suffix->MemoryFlags; }
  110.   uint16_t getMajorVersion() const { return Suffix->Version >> 16; }
  111.   uint16_t getMinorVersion() const { return Suffix->Version; }
  112.   uint32_t getCharacteristics() const { return Suffix->Characteristics; }
  113.   ArrayRef<uint8_t> getData() const { return Data; }
  114.  
  115. private:
  116.   friend class WindowsResource;
  117.  
  118.   ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner);
  119.   Error loadNext();
  120.  
  121.   static Expected<ResourceEntryRef> create(BinaryStreamRef Ref,
  122.                                            const WindowsResource *Owner);
  123.  
  124.   BinaryStreamReader Reader;
  125.   const WindowsResource *Owner;
  126.   bool IsStringType;
  127.   ArrayRef<UTF16> Type;
  128.   uint16_t TypeID;
  129.   bool IsStringName;
  130.   ArrayRef<UTF16> Name;
  131.   uint16_t NameID;
  132.   const WinResHeaderSuffix *Suffix = nullptr;
  133.   ArrayRef<uint8_t> Data;
  134. };
  135.  
  136. class WindowsResource : public Binary {
  137. public:
  138.   Expected<ResourceEntryRef> getHeadEntry();
  139.  
  140.   static bool classof(const Binary *V) { return V->isWinRes(); }
  141.  
  142.   static Expected<std::unique_ptr<WindowsResource>>
  143.   createWindowsResource(MemoryBufferRef Source);
  144.  
  145. private:
  146.   friend class ResourceEntryRef;
  147.  
  148.   WindowsResource(MemoryBufferRef Source);
  149.  
  150.   BinaryByteStream BBS;
  151. };
  152.  
  153. class WindowsResourceParser {
  154. public:
  155.   class TreeNode;
  156.   WindowsResourceParser(bool MinGW = false);
  157.   Error parse(WindowsResource *WR, std::vector<std::string> &Duplicates);
  158.   Error parse(ResourceSectionRef &RSR, StringRef Filename,
  159.               std::vector<std::string> &Duplicates);
  160.   void cleanUpManifests(std::vector<std::string> &Duplicates);
  161.   void printTree(raw_ostream &OS) const;
  162.   const TreeNode &getTree() const { return Root; }
  163.   ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
  164.   ArrayRef<std::vector<UTF16>> getStringTable() const { return StringTable; }
  165.  
  166.   class TreeNode {
  167.   public:
  168.     template <typename T>
  169.     using Children = std::map<T, std::unique_ptr<TreeNode>>;
  170.  
  171.     void print(ScopedPrinter &Writer, StringRef Name) const;
  172.     uint32_t getTreeSize() const;
  173.     uint32_t getStringIndex() const { return StringIndex; }
  174.     uint32_t getDataIndex() const { return DataIndex; }
  175.     uint16_t getMajorVersion() const { return MajorVersion; }
  176.     uint16_t getMinorVersion() const { return MinorVersion; }
  177.     uint32_t getCharacteristics() const { return Characteristics; }
  178.     bool checkIsDataNode() const { return IsDataNode; }
  179.     const Children<uint32_t> &getIDChildren() const { return IDChildren; }
  180.     const Children<std::string> &getStringChildren() const {
  181.       return StringChildren;
  182.     }
  183.  
  184.   private:
  185.     friend class WindowsResourceParser;
  186.  
  187.     // Index is the StringTable vector index for this node's name.
  188.     static std::unique_ptr<TreeNode> createStringNode(uint32_t Index);
  189.     static std::unique_ptr<TreeNode> createIDNode();
  190.     // DataIndex is the Data vector index that the data node points at.
  191.     static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
  192.                                                     uint16_t MinorVersion,
  193.                                                     uint32_t Characteristics,
  194.                                                     uint32_t Origin,
  195.                                                     uint32_t DataIndex);
  196.  
  197.     explicit TreeNode(uint32_t StringIndex);
  198.     TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
  199.              uint32_t Characteristics, uint32_t Origin, uint32_t DataIndex);
  200.  
  201.     bool addEntry(const ResourceEntryRef &Entry, uint32_t Origin,
  202.                   std::vector<std::vector<uint8_t>> &Data,
  203.                   std::vector<std::vector<UTF16>> &StringTable,
  204.                   TreeNode *&Result);
  205.     TreeNode &addTypeNode(const ResourceEntryRef &Entry,
  206.                           std::vector<std::vector<UTF16>> &StringTable);
  207.     TreeNode &addNameNode(const ResourceEntryRef &Entry,
  208.                           std::vector<std::vector<UTF16>> &StringTable);
  209.     bool addLanguageNode(const ResourceEntryRef &Entry, uint32_t Origin,
  210.                          std::vector<std::vector<uint8_t>> &Data,
  211.                          TreeNode *&Result);
  212.     bool addDataChild(uint32_t ID, uint16_t MajorVersion, uint16_t MinorVersion,
  213.                       uint32_t Characteristics, uint32_t Origin,
  214.                       uint32_t DataIndex, TreeNode *&Result);
  215.     TreeNode &addIDChild(uint32_t ID);
  216.     TreeNode &addNameChild(ArrayRef<UTF16> NameRef,
  217.                            std::vector<std::vector<UTF16>> &StringTable);
  218.     void shiftDataIndexDown(uint32_t Index);
  219.  
  220.     bool IsDataNode = false;
  221.     uint32_t StringIndex;
  222.     uint32_t DataIndex;
  223.     Children<uint32_t> IDChildren;
  224.     Children<std::string> StringChildren;
  225.     uint16_t MajorVersion = 0;
  226.     uint16_t MinorVersion = 0;
  227.     uint32_t Characteristics = 0;
  228.  
  229.     // The .res file that defined this TreeNode, for diagnostics.
  230.     // Index into InputFilenames.
  231.     uint32_t Origin;
  232.   };
  233.  
  234.   struct StringOrID {
  235.     bool IsString;
  236.     ArrayRef<UTF16> String;
  237.     uint32_t ID;
  238.  
  239.     StringOrID(uint32_t ID) : IsString(false), ID(ID) {}
  240.     StringOrID(ArrayRef<UTF16> String) : IsString(true), String(String) {}
  241.   };
  242.  
  243. private:
  244.   Error addChildren(TreeNode &Node, ResourceSectionRef &RSR,
  245.                     const coff_resource_dir_table &Table, uint32_t Origin,
  246.                     std::vector<StringOrID> &Context,
  247.                     std::vector<std::string> &Duplicates);
  248.   bool shouldIgnoreDuplicate(const ResourceEntryRef &Entry) const;
  249.   bool shouldIgnoreDuplicate(const std::vector<StringOrID> &Context) const;
  250.  
  251.   TreeNode Root;
  252.   std::vector<std::vector<uint8_t>> Data;
  253.   std::vector<std::vector<UTF16>> StringTable;
  254.  
  255.   std::vector<std::string> InputFilenames;
  256.  
  257.   bool MinGW;
  258. };
  259.  
  260. Expected<std::unique_ptr<MemoryBuffer>>
  261. writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
  262.                          const WindowsResourceParser &Parser,
  263.                          uint32_t TimeDateStamp);
  264.  
  265. void printResourceTypeName(uint16_t TypeID, raw_ostream &OS);
  266. } // namespace object
  267. } // namespace llvm
  268.  
  269. #endif
  270.