1326938Sdim//===-- WindowsResourceDumper.cpp - Windows Resource printer --------------===// 2326938Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6326938Sdim// 7326938Sdim//===----------------------------------------------------------------------===// 8326938Sdim// 9326938Sdim// This file implements the Windows resource (.res) dumper for llvm-readobj. 10326938Sdim// 11326938Sdim//===----------------------------------------------------------------------===// 12326938Sdim 13326938Sdim#include "WindowsResourceDumper.h" 14326938Sdim#include "Error.h" 15326938Sdim#include "llvm/Object/WindowsResource.h" 16326938Sdim#include "llvm/Support/ConvertUTF.h" 17326938Sdim#include "llvm/Support/ScopedPrinter.h" 18326938Sdim 19326938Sdimnamespace llvm { 20326938Sdimnamespace object { 21326938Sdimnamespace WindowsRes { 22326938Sdim 23326938Sdimstd::string stripUTF16(const ArrayRef<UTF16> &UTF16Str) { 24326938Sdim std::string Result; 25326938Sdim Result.reserve(UTF16Str.size()); 26326938Sdim 27326938Sdim for (UTF16 Ch : UTF16Str) { 28326938Sdim // UTF16Str will have swapped byte order in case of big-endian machines. 29326938Sdim // Swap it back in such a case. 30326938Sdim uint16_t ChValue = support::endian::byte_swap(Ch, support::little); 31326938Sdim if (ChValue <= 0xFF) 32326938Sdim Result += ChValue; 33326938Sdim else 34326938Sdim Result += '?'; 35326938Sdim } 36326938Sdim return Result; 37326938Sdim} 38326938Sdim 39326938SdimError Dumper::printData() { 40326938Sdim auto EntryPtrOrErr = WinRes->getHeadEntry(); 41326938Sdim if (!EntryPtrOrErr) 42326938Sdim return EntryPtrOrErr.takeError(); 43326938Sdim auto EntryPtr = *EntryPtrOrErr; 44326938Sdim 45326938Sdim bool IsEnd = false; 46326938Sdim while (!IsEnd) { 47326938Sdim printEntry(EntryPtr); 48326938Sdim 49326938Sdim if (auto Err = EntryPtr.moveNext(IsEnd)) 50326938Sdim return Err; 51326938Sdim } 52326938Sdim return Error::success(); 53326938Sdim} 54326938Sdim 55326938Sdimvoid Dumper::printEntry(const ResourceEntryRef &Ref) { 56326938Sdim if (Ref.checkTypeString()) { 57326938Sdim auto NarrowStr = stripUTF16(Ref.getTypeString()); 58326938Sdim SW.printString("Resource type (string)", NarrowStr); 59360784Sdim } else { 60360784Sdim SmallString<20> IDStr; 61360784Sdim raw_svector_ostream OS(IDStr); 62360784Sdim printResourceTypeName(Ref.getTypeID(), OS); 63360784Sdim SW.printString("Resource type (int)", IDStr); 64360784Sdim } 65326938Sdim 66326938Sdim if (Ref.checkNameString()) { 67326938Sdim auto NarrowStr = stripUTF16(Ref.getNameString()); 68326938Sdim SW.printString("Resource name (string)", NarrowStr); 69326938Sdim } else 70326938Sdim SW.printNumber("Resource name (int)", Ref.getNameID()); 71326938Sdim 72326938Sdim SW.printNumber("Data version", Ref.getDataVersion()); 73326938Sdim SW.printHex("Memory flags", Ref.getMemoryFlags()); 74326938Sdim SW.printNumber("Language ID", Ref.getLanguage()); 75326938Sdim SW.printNumber("Version (major)", Ref.getMajorVersion()); 76326938Sdim SW.printNumber("Version (minor)", Ref.getMinorVersion()); 77326938Sdim SW.printNumber("Characteristics", Ref.getCharacteristics()); 78326938Sdim SW.printNumber("Data size", (uint64_t)Ref.getData().size()); 79326938Sdim SW.printBinary("Data:", Ref.getData()); 80326938Sdim SW.startLine() << "\n"; 81326938Sdim} 82326938Sdim 83326938Sdim} // namespace WindowsRes 84326938Sdim} // namespace object 85326938Sdim} // namespace llvm 86