diff options
Diffstat (limited to 'llvm/tools/llvm-readobj/WindowsResourceDumper.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/WindowsResourceDumper.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/llvm/tools/llvm-readobj/WindowsResourceDumper.cpp b/llvm/tools/llvm-readobj/WindowsResourceDumper.cpp new file mode 100644 index 000000000000..a2fb6aac3f93 --- /dev/null +++ b/llvm/tools/llvm-readobj/WindowsResourceDumper.cpp @@ -0,0 +1,85 @@ +//===-- WindowsResourceDumper.cpp - Windows Resource printer --------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the Windows resource (.res) dumper for llvm-readobj. +// +//===----------------------------------------------------------------------===// + +#include "WindowsResourceDumper.h" +#include "Error.h" +#include "llvm/Object/WindowsResource.h" +#include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/ScopedPrinter.h" + +namespace llvm { +namespace object { +namespace WindowsRes { + +std::string stripUTF16(const ArrayRef<UTF16> &UTF16Str) { + std::string Result; + Result.reserve(UTF16Str.size()); + + for (UTF16 Ch : UTF16Str) { + // UTF16Str will have swapped byte order in case of big-endian machines. + // Swap it back in such a case. + uint16_t ChValue = support::endian::byte_swap(Ch, support::little); + if (ChValue <= 0xFF) + Result += ChValue; + else + Result += '?'; + } + return Result; +} + +Error Dumper::printData() { + auto EntryPtrOrErr = WinRes->getHeadEntry(); + if (!EntryPtrOrErr) + return EntryPtrOrErr.takeError(); + auto EntryPtr = *EntryPtrOrErr; + + bool IsEnd = false; + while (!IsEnd) { + printEntry(EntryPtr); + + if (auto Err = EntryPtr.moveNext(IsEnd)) + return Err; + } + return Error::success(); +} + +void Dumper::printEntry(const ResourceEntryRef &Ref) { + if (Ref.checkTypeString()) { + auto NarrowStr = stripUTF16(Ref.getTypeString()); + SW.printString("Resource type (string)", NarrowStr); + } else { + SmallString<20> IDStr; + raw_svector_ostream OS(IDStr); + printResourceTypeName(Ref.getTypeID(), OS); + SW.printString("Resource type (int)", IDStr); + } + + if (Ref.checkNameString()) { + auto NarrowStr = stripUTF16(Ref.getNameString()); + SW.printString("Resource name (string)", NarrowStr); + } else + SW.printNumber("Resource name (int)", Ref.getNameID()); + + SW.printNumber("Data version", Ref.getDataVersion()); + SW.printHex("Memory flags", Ref.getMemoryFlags()); + SW.printNumber("Language ID", Ref.getLanguage()); + SW.printNumber("Version (major)", Ref.getMajorVersion()); + SW.printNumber("Version (minor)", Ref.getMinorVersion()); + SW.printNumber("Characteristics", Ref.getCharacteristics()); + SW.printNumber("Data size", (uint64_t)Ref.getData().size()); + SW.printBinary("Data:", Ref.getData()); + SW.startLine() << "\n"; +} + +} // namespace WindowsRes +} // namespace object +} // namespace llvm |