LCOV - code coverage report
Current view: top level - include/llvm/Object - WindowsResource.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 4 26 15.4 %
Date: 2018-10-20 13:21:21 Functions: 0 19 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13