blob: a2fb6aac3f931fdb261d3327dbf09aa8a06e454c [file] [log] [blame]
Marek Sokolowskic2189b82017-09-20 18:33:35 +00001//===-- WindowsResourceDumper.cpp - Windows Resource printer --------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Marek Sokolowskic2189b82017-09-20 18:33:35 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the Windows resource (.res) dumper for llvm-readobj.
10//
11//===----------------------------------------------------------------------===//
12
13#include "WindowsResourceDumper.h"
14#include "Error.h"
Marek Sokolowskic2189b82017-09-20 18:33:35 +000015#include "llvm/Object/WindowsResource.h"
Marek Sokolowski43e90612017-09-20 23:26:05 +000016#include "llvm/Support/ConvertUTF.h"
Marek Sokolowskic2189b82017-09-20 18:33:35 +000017#include "llvm/Support/ScopedPrinter.h"
18
19namespace llvm {
20namespace object {
21namespace WindowsRes {
22
23std::string stripUTF16(const ArrayRef<UTF16> &UTF16Str) {
24 std::string Result;
25 Result.reserve(UTF16Str.size());
26
27 for (UTF16 Ch : UTF16Str) {
Marek Sokolowskiab9ee732017-09-20 23:07:39 +000028 // UTF16Str will have swapped byte order in case of big-endian machines.
29 // Swap it back in such a case.
Marek Sokolowskib63355e2017-09-21 20:36:38 +000030 uint16_t ChValue = support::endian::byte_swap(Ch, support::little);
Marek Sokolowskiab9ee732017-09-20 23:07:39 +000031 if (ChValue <= 0xFF)
32 Result += ChValue;
Marek Sokolowskic2189b82017-09-20 18:33:35 +000033 else
34 Result += '?';
35 }
36 return Result;
37}
38
39Error Dumper::printData() {
40 auto EntryPtrOrErr = WinRes->getHeadEntry();
41 if (!EntryPtrOrErr)
42 return EntryPtrOrErr.takeError();
43 auto EntryPtr = *EntryPtrOrErr;
44
45 bool IsEnd = false;
46 while (!IsEnd) {
47 printEntry(EntryPtr);
48
49 if (auto Err = EntryPtr.moveNext(IsEnd))
50 return Err;
51 }
52 return Error::success();
53}
54
55void Dumper::printEntry(const ResourceEntryRef &Ref) {
56 if (Ref.checkTypeString()) {
57 auto NarrowStr = stripUTF16(Ref.getTypeString());
58 SW.printString("Resource type (string)", NarrowStr);
Martin Storsjoe3e88742019-08-29 08:59:31 +000059 } else {
60 SmallString<20> IDStr;
61 raw_svector_ostream OS(IDStr);
62 printResourceTypeName(Ref.getTypeID(), OS);
63 SW.printString("Resource type (int)", IDStr);
64 }
Marek Sokolowskic2189b82017-09-20 18:33:35 +000065
66 if (Ref.checkNameString()) {
67 auto NarrowStr = stripUTF16(Ref.getNameString());
68 SW.printString("Resource name (string)", NarrowStr);
69 } else
70 SW.printNumber("Resource name (int)", Ref.getNameID());
71
72 SW.printNumber("Data version", Ref.getDataVersion());
73 SW.printHex("Memory flags", Ref.getMemoryFlags());
74 SW.printNumber("Language ID", Ref.getLanguage());
75 SW.printNumber("Version (major)", Ref.getMajorVersion());
76 SW.printNumber("Version (minor)", Ref.getMinorVersion());
77 SW.printNumber("Characteristics", Ref.getCharacteristics());
Marek Sokolowski1e72f652017-09-20 21:03:37 +000078 SW.printNumber("Data size", (uint64_t)Ref.getData().size());
Marek Sokolowskic2189b82017-09-20 18:33:35 +000079 SW.printBinary("Data:", Ref.getData());
80 SW.startLine() << "\n";
81}
82
83} // namespace WindowsRes
84} // namespace object
85} // namespace llvm