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