10b57cec5SDimitry Andric //===-- WindowsResourceDumper.cpp - Windows Resource printer --------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the Windows resource (.res) dumper for llvm-readobj. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "WindowsResourceDumper.h" 140b57cec5SDimitry Andric #include "Error.h" 150b57cec5SDimitry Andric #include "llvm/Object/WindowsResource.h" 160b57cec5SDimitry Andric #include "llvm/Support/ConvertUTF.h" 170b57cec5SDimitry Andric #include "llvm/Support/ScopedPrinter.h" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric namespace llvm { 200b57cec5SDimitry Andric namespace object { 210b57cec5SDimitry Andric namespace WindowsRes { 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric std::string stripUTF16(const ArrayRef<UTF16> &UTF16Str) { 240b57cec5SDimitry Andric std::string Result; 250b57cec5SDimitry Andric Result.reserve(UTF16Str.size()); 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric for (UTF16 Ch : UTF16Str) { 280b57cec5SDimitry Andric // UTF16Str will have swapped byte order in case of big-endian machines. 290b57cec5SDimitry Andric // Swap it back in such a case. 300b57cec5SDimitry Andric uint16_t ChValue = support::endian::byte_swap(Ch, support::little); 310b57cec5SDimitry Andric if (ChValue <= 0xFF) 320b57cec5SDimitry Andric Result += ChValue; 330b57cec5SDimitry Andric else 340b57cec5SDimitry Andric Result += '?'; 350b57cec5SDimitry Andric } 360b57cec5SDimitry Andric return Result; 370b57cec5SDimitry Andric } 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric Error Dumper::printData() { 400b57cec5SDimitry Andric auto EntryPtrOrErr = WinRes->getHeadEntry(); 410b57cec5SDimitry Andric if (!EntryPtrOrErr) 420b57cec5SDimitry Andric return EntryPtrOrErr.takeError(); 430b57cec5SDimitry Andric auto EntryPtr = *EntryPtrOrErr; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric bool IsEnd = false; 460b57cec5SDimitry Andric while (!IsEnd) { 470b57cec5SDimitry Andric printEntry(EntryPtr); 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric if (auto Err = EntryPtr.moveNext(IsEnd)) 500b57cec5SDimitry Andric return Err; 510b57cec5SDimitry Andric } 520b57cec5SDimitry Andric return Error::success(); 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric void Dumper::printEntry(const ResourceEntryRef &Ref) { 560b57cec5SDimitry Andric if (Ref.checkTypeString()) { 570b57cec5SDimitry Andric auto NarrowStr = stripUTF16(Ref.getTypeString()); 580b57cec5SDimitry Andric SW.printString("Resource type (string)", NarrowStr); 59*8bcb0991SDimitry Andric } else { 60*8bcb0991SDimitry Andric SmallString<20> IDStr; 61*8bcb0991SDimitry Andric raw_svector_ostream OS(IDStr); 62*8bcb0991SDimitry Andric printResourceTypeName(Ref.getTypeID(), OS); 63*8bcb0991SDimitry Andric SW.printString("Resource type (int)", IDStr); 64*8bcb0991SDimitry Andric } 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric if (Ref.checkNameString()) { 670b57cec5SDimitry Andric auto NarrowStr = stripUTF16(Ref.getNameString()); 680b57cec5SDimitry Andric SW.printString("Resource name (string)", NarrowStr); 690b57cec5SDimitry Andric } else 700b57cec5SDimitry Andric SW.printNumber("Resource name (int)", Ref.getNameID()); 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric SW.printNumber("Data version", Ref.getDataVersion()); 730b57cec5SDimitry Andric SW.printHex("Memory flags", Ref.getMemoryFlags()); 740b57cec5SDimitry Andric SW.printNumber("Language ID", Ref.getLanguage()); 750b57cec5SDimitry Andric SW.printNumber("Version (major)", Ref.getMajorVersion()); 760b57cec5SDimitry Andric SW.printNumber("Version (minor)", Ref.getMinorVersion()); 770b57cec5SDimitry Andric SW.printNumber("Characteristics", Ref.getCharacteristics()); 780b57cec5SDimitry Andric SW.printNumber("Data size", (uint64_t)Ref.getData().size()); 790b57cec5SDimitry Andric SW.printBinary("Data:", Ref.getData()); 800b57cec5SDimitry Andric SW.startLine() << "\n"; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric } // namespace WindowsRes 840b57cec5SDimitry Andric } // namespace object 850b57cec5SDimitry Andric } // namespace llvm 86