1c2189b83SMarek Sokolowski //===-- WindowsResourceDumper.cpp - Windows Resource printer --------------===//
2c2189b83SMarek Sokolowski //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c2189b83SMarek Sokolowski //
7c2189b83SMarek Sokolowski //===----------------------------------------------------------------------===//
8c2189b83SMarek Sokolowski //
9c2189b83SMarek Sokolowski // This file implements the Windows resource (.res) dumper for llvm-readobj.
10c2189b83SMarek Sokolowski //
11c2189b83SMarek Sokolowski //===----------------------------------------------------------------------===//
12c2189b83SMarek Sokolowski 
13c2189b83SMarek Sokolowski #include "WindowsResourceDumper.h"
14c2189b83SMarek Sokolowski #include "llvm/Object/WindowsResource.h"
1543e90610SMarek Sokolowski #include "llvm/Support/ConvertUTF.h"
16c2189b83SMarek Sokolowski #include "llvm/Support/ScopedPrinter.h"
17c2189b83SMarek Sokolowski 
18c2189b83SMarek Sokolowski namespace llvm {
19c2189b83SMarek Sokolowski namespace object {
20c2189b83SMarek Sokolowski namespace WindowsRes {
21c2189b83SMarek Sokolowski 
stripUTF16(const ArrayRef<UTF16> & UTF16Str)22c2189b83SMarek Sokolowski std::string stripUTF16(const ArrayRef<UTF16> &UTF16Str) {
23c2189b83SMarek Sokolowski   std::string Result;
24c2189b83SMarek Sokolowski   Result.reserve(UTF16Str.size());
25c2189b83SMarek Sokolowski 
26c2189b83SMarek Sokolowski   for (UTF16 Ch : UTF16Str) {
27ab9ee73eSMarek Sokolowski     // UTF16Str will have swapped byte order in case of big-endian machines.
28ab9ee73eSMarek Sokolowski     // Swap it back in such a case.
29b63355efSMarek Sokolowski     uint16_t ChValue = support::endian::byte_swap(Ch, support::little);
30ab9ee73eSMarek Sokolowski     if (ChValue <= 0xFF)
31ab9ee73eSMarek Sokolowski       Result += ChValue;
32c2189b83SMarek Sokolowski     else
33c2189b83SMarek Sokolowski       Result += '?';
34c2189b83SMarek Sokolowski   }
35c2189b83SMarek Sokolowski   return Result;
36c2189b83SMarek Sokolowski }
37c2189b83SMarek Sokolowski 
printData()38c2189b83SMarek Sokolowski Error Dumper::printData() {
39c2189b83SMarek Sokolowski   auto EntryPtrOrErr = WinRes->getHeadEntry();
40c2189b83SMarek Sokolowski   if (!EntryPtrOrErr)
41c2189b83SMarek Sokolowski     return EntryPtrOrErr.takeError();
42c2189b83SMarek Sokolowski   auto EntryPtr = *EntryPtrOrErr;
43c2189b83SMarek Sokolowski 
44c2189b83SMarek Sokolowski   bool IsEnd = false;
45c2189b83SMarek Sokolowski   while (!IsEnd) {
46c2189b83SMarek Sokolowski     printEntry(EntryPtr);
47c2189b83SMarek Sokolowski 
48c2189b83SMarek Sokolowski     if (auto Err = EntryPtr.moveNext(IsEnd))
49c2189b83SMarek Sokolowski       return Err;
50c2189b83SMarek Sokolowski   }
51c2189b83SMarek Sokolowski   return Error::success();
52c2189b83SMarek Sokolowski }
53c2189b83SMarek Sokolowski 
printEntry(const ResourceEntryRef & Ref)54c2189b83SMarek Sokolowski void Dumper::printEntry(const ResourceEntryRef &Ref) {
55c2189b83SMarek Sokolowski   if (Ref.checkTypeString()) {
56c2189b83SMarek Sokolowski     auto NarrowStr = stripUTF16(Ref.getTypeString());
57c2189b83SMarek Sokolowski     SW.printString("Resource type (string)", NarrowStr);
58*e3e8874bSMartin Storsjo   } else {
59*e3e8874bSMartin Storsjo     SmallString<20> IDStr;
60*e3e8874bSMartin Storsjo     raw_svector_ostream OS(IDStr);
61*e3e8874bSMartin Storsjo     printResourceTypeName(Ref.getTypeID(), OS);
62*e3e8874bSMartin Storsjo     SW.printString("Resource type (int)", IDStr);
63*e3e8874bSMartin Storsjo   }
64c2189b83SMarek Sokolowski 
65c2189b83SMarek Sokolowski   if (Ref.checkNameString()) {
66c2189b83SMarek Sokolowski     auto NarrowStr = stripUTF16(Ref.getNameString());
67c2189b83SMarek Sokolowski     SW.printString("Resource name (string)", NarrowStr);
68c2189b83SMarek Sokolowski   } else
69c2189b83SMarek Sokolowski     SW.printNumber("Resource name (int)", Ref.getNameID());
70c2189b83SMarek Sokolowski 
71c2189b83SMarek Sokolowski   SW.printNumber("Data version", Ref.getDataVersion());
72c2189b83SMarek Sokolowski   SW.printHex("Memory flags", Ref.getMemoryFlags());
73c2189b83SMarek Sokolowski   SW.printNumber("Language ID", Ref.getLanguage());
74c2189b83SMarek Sokolowski   SW.printNumber("Version (major)", Ref.getMajorVersion());
75c2189b83SMarek Sokolowski   SW.printNumber("Version (minor)", Ref.getMinorVersion());
76c2189b83SMarek Sokolowski   SW.printNumber("Characteristics", Ref.getCharacteristics());
771e72f650SMarek Sokolowski   SW.printNumber("Data size", (uint64_t)Ref.getData().size());
78c2189b83SMarek Sokolowski   SW.printBinary("Data:", Ref.getData());
79c2189b83SMarek Sokolowski   SW.startLine() << "\n";
80c2189b83SMarek Sokolowski }
81c2189b83SMarek Sokolowski 
82c2189b83SMarek Sokolowski } // namespace WindowsRes
83c2189b83SMarek Sokolowski } // namespace object
84c2189b83SMarek Sokolowski } // namespace llvm
85