LCOV - code coverage report
Current view: top level - include/llvm/Object - WindowsResource.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 13 19 68.4 %
Date: 2017-09-14 15:23:50 Functions: 5 8 62.5 %
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           0 :     TypeID = ID;
      72             :   }
      73             : 
      74             :   void setName(uint16_t ID) {
      75           0 :     NameFlag = 0xffff;
      76           0 :     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           0 : class EmptyResError : public GenericBinaryError {
      89             : public:
      90             :   EmptyResError(Twine Msg, object_error ECOverride)
      91           0 :       : GenericBinaryError(Msg, ECOverride) {}
      92             : };
      93             : 
      94         170 : class ResourceEntryRef {
      95             : public:
      96             :   Error moveNext(bool &End);
      97             :   bool checkTypeString() const { return IsStringType; }
      98             :   ArrayRef<UTF16> getTypeString() const { return Type; }
      99             :   uint16_t getTypeID() const { return TypeID; }
     100             :   bool checkNameString() const { return IsStringName; }
     101             :   ArrayRef<UTF16> getNameString() const { return Name; }
     102             :   uint16_t getNameID() const { return NameID; }
     103         148 :   uint16_t getLanguage() const { return Suffix->Language; }
     104         148 :   uint16_t getMajorVersion() const { return Suffix->Version >> 16; }
     105         148 :   uint16_t getMinorVersion() const { return Suffix->Version; }
     106         148 :   uint32_t getCharacteristics() const { return Suffix->Characteristics; }
     107             :   ArrayRef<uint8_t> getData() const { return Data; }
     108             : 
     109             : private:
     110             :   friend class WindowsResource;
     111             : 
     112             :   ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner);
     113             :   Error loadNext();
     114             : 
     115             :   static Expected<ResourceEntryRef> create(BinaryStreamRef Ref,
     116             :                                            const WindowsResource *Owner);
     117             : 
     118             :   BinaryStreamReader Reader;
     119             :   bool IsStringType;
     120             :   ArrayRef<UTF16> Type;
     121             :   uint16_t TypeID;
     122             :   bool IsStringName;
     123             :   ArrayRef<UTF16> Name;
     124             :   uint16_t NameID;
     125             :   const WinResHeaderSuffix *Suffix = nullptr;
     126             :   ArrayRef<uint8_t> Data;
     127             :   const WindowsResource *OwningRes = nullptr;
     128             : };
     129             : 
     130          24 : class WindowsResource : public Binary {
     131             : public:
     132             :   Expected<ResourceEntryRef> getHeadEntry();
     133             : 
     134             :   static bool classof(const Binary *V) { return V->isWinRes(); }
     135             : 
     136             :   static Expected<std::unique_ptr<WindowsResource>>
     137             :   createWindowsResource(MemoryBufferRef Source);
     138             : 
     139             : private:
     140             :   friend class ResourceEntryRef;
     141             : 
     142             :   WindowsResource(MemoryBufferRef Source);
     143             : 
     144             :   BinaryByteStream BBS;
     145             : };
     146             : 
     147           9 : class WindowsResourceParser {
     148             : public:
     149             :   class TreeNode;
     150             :   WindowsResourceParser();
     151             :   Error parse(WindowsResource *WR);
     152             :   void printTree(raw_ostream &OS) const;
     153           9 :   const TreeNode &getTree() const { return Root; }
     154          18 :   const ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
     155             :   const ArrayRef<std::vector<UTF16>> getStringTable() const {
     156          18 :     return StringTable;
     157             :   }
     158             : 
     159         585 :   class TreeNode {
     160             :   public:
     161             :     template <typename T>
     162             :     using Children = std::map<T, std::unique_ptr<TreeNode>>;
     163             : 
     164             :     void print(ScopedPrinter &Writer, StringRef Name) const;
     165             :     uint32_t getTreeSize() const;
     166             :     uint32_t getStringIndex() const { return StringIndex; }
     167             :     uint32_t getDataIndex() const { return DataIndex; }
     168             :     uint16_t getMajorVersion() const { return MajorVersion; }
     169             :     uint16_t getMinorVersion() const { return MinorVersion; }
     170             :     uint32_t getCharacteristics() const { return Characteristics; }
     171             :     bool checkIsDataNode() const { return IsDataNode; }
     172         121 :     const Children<uint32_t> &getIDChildren() const { return IDChildren; }
     173             :     const Children<std::string> &getStringChildren() const {
     174         121 :       return StringChildren;
     175             :     }
     176             : 
     177             :   private:
     178             :     friend class WindowsResourceParser;
     179             : 
     180             :     static uint32_t StringCount;
     181             :     static uint32_t DataCount;
     182             : 
     183             :     static std::unique_ptr<TreeNode> createStringNode();
     184             :     static std::unique_ptr<TreeNode> createIDNode();
     185             :     static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
     186             :                                                     uint16_t MinorVersion,
     187             :                                                     uint32_t Characteristics);
     188             : 
     189             :     explicit TreeNode(bool IsStringNode);
     190             :     TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
     191             :              uint32_t Characteristics);
     192             : 
     193             :     void addEntry(const ResourceEntryRef &Entry, bool &IsNewTypeString,
     194             :                   bool &IsNewNameString);
     195             :     TreeNode &addTypeNode(const ResourceEntryRef &Entry, bool &IsNewTypeString);
     196             :     TreeNode &addNameNode(const ResourceEntryRef &Entry, bool &IsNewNameString);
     197             :     TreeNode &addLanguageNode(const ResourceEntryRef &Entry);
     198             :     TreeNode &addChild(uint32_t ID, bool IsDataNode = false,
     199             :                        uint16_t MajorVersion = 0, uint16_t MinorVersion = 0,
     200             :                        uint32_t Characteristics = 0);
     201             :     TreeNode &addChild(ArrayRef<UTF16> NameRef, bool &IsNewString);
     202             : 
     203             :     bool IsDataNode = false;
     204             :     uint32_t StringIndex;
     205             :     uint32_t DataIndex;
     206             :     Children<uint32_t> IDChildren;
     207             :     Children<std::string> StringChildren;
     208             :     uint16_t MajorVersion = 0;
     209             :     uint16_t MinorVersion = 0;
     210             :     uint32_t Characteristics = 0;
     211             :   };
     212             : 
     213             : private:
     214             :   TreeNode Root;
     215             :   std::vector<std::vector<uint8_t>> Data;
     216             :   std::vector<std::vector<UTF16>> StringTable;
     217             : };
     218             : 
     219             : Expected<std::unique_ptr<MemoryBuffer>>
     220             : writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
     221             :                          const WindowsResourceParser &Parser);
     222             : 
     223             : } // namespace object
     224             : } // namespace llvm
     225             : 
     226             : #endif

Generated by: LCOV version 1.13