blob: 13989f696d9de2c93964af4bc51d8e2e3bec4ae3 [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);
59 } else
60 SW.printNumber("Resource type (int)", Ref.getTypeID());
61
62 if (Ref.checkNameString()) {
63 auto NarrowStr = stripUTF16(Ref.getNameString());
64 SW.printString("Resource name (string)", NarrowStr);
65 } else
66 SW.printNumber("Resource name (int)", Ref.getNameID());
67
68 SW.printNumber("Data version", Ref.getDataVersion());
69 SW.printHex("Memory flags", Ref.getMemoryFlags());
70 SW.printNumber("Language ID", Ref.getLanguage());
71 SW.printNumber("Version (major)", Ref.getMajorVersion());
72 SW.printNumber("Version (minor)", Ref.getMinorVersion());
73 SW.printNumber("Characteristics", Ref.getCharacteristics());
Marek Sokolowski1e72f652017-09-20 21:03:37 +000074 SW.printNumber("Data size", (uint64_t)Ref.getData().size());
Marek Sokolowskic2189b82017-09-20 18:33:35 +000075 SW.printBinary("Data:", Ref.getData());
76 SW.startLine() << "\n";
77}
78
79} // namespace WindowsRes
80} // namespace object
81} // namespace llvm