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