1 //===-- WindowsResourceDumper.cpp - Windows Resource printer --------------===//
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 implements the Windows resource (.res) dumper for llvm-readobj.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "WindowsResourceDumper.h"
15 #include "Error.h"
16 #include "llvm-readobj.h"
17 #include "llvm/Object/WindowsResource.h"
18 #include "llvm/Support/ConvertUTF.h"
19 #include "llvm/Support/ScopedPrinter.h"
20 
21 namespace llvm {
22 namespace object {
23 namespace WindowsRes {
24 
25 std::string stripUTF16(const ArrayRef<UTF16> &UTF16Str) {
26   std::string Result;
27   Result.reserve(UTF16Str.size());
28 
29   for (UTF16 Ch : UTF16Str) {
30     // UTF16Str will have swapped byte order in case of big-endian machines.
31     // Swap it back in such a case.
32     uint16_t ChValue = support::endian::byte_swap(Ch, support::little);
33     if (ChValue <= 0xFF)
34       Result += ChValue;
35     else
36       Result += '?';
37   }
38   return Result;
39 }
40 
41 Error Dumper::printData() {
42   auto EntryPtrOrErr = WinRes->getHeadEntry();
43   if (!EntryPtrOrErr)
44     return EntryPtrOrErr.takeError();
45   auto EntryPtr = *EntryPtrOrErr;
46 
47   bool IsEnd = false;
48   while (!IsEnd) {
49     printEntry(EntryPtr);
50 
51     if (auto Err = EntryPtr.moveNext(IsEnd))
52       return Err;
53   }
54   return Error::success();
55 }
56 
57 void Dumper::printEntry(const ResourceEntryRef &Ref) {
58   if (Ref.checkTypeString()) {
59     auto NarrowStr = stripUTF16(Ref.getTypeString());
60     SW.printString("Resource type (string)", NarrowStr);
61   } else
62     SW.printNumber("Resource type (int)", Ref.getTypeID());
63 
64   if (Ref.checkNameString()) {
65     auto NarrowStr = stripUTF16(Ref.getNameString());
66     SW.printString("Resource name (string)", NarrowStr);
67   } else
68     SW.printNumber("Resource name (int)", Ref.getNameID());
69 
70   SW.printNumber("Data version", Ref.getDataVersion());
71   SW.printHex("Memory flags", Ref.getMemoryFlags());
72   SW.printNumber("Language ID", Ref.getLanguage());
73   SW.printNumber("Version (major)", Ref.getMajorVersion());
74   SW.printNumber("Version (minor)", Ref.getMinorVersion());
75   SW.printNumber("Characteristics", Ref.getCharacteristics());
76   SW.printNumber("Data size", (uint64_t)Ref.getData().size());
77   SW.printBinary("Data:", Ref.getData());
78   SW.startLine() << "\n";
79 }
80 
81 } // namespace WindowsRes
82 } // namespace object
83 } // namespace llvm
84