xref: /freebsd-src/contrib/llvm-project/llvm/tools/llvm-readobj/WindowsResourceDumper.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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 "llvm/Object/WindowsResource.h"
150b57cec5SDimitry Andric #include "llvm/Support/ConvertUTF.h"
160b57cec5SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric namespace llvm {
190b57cec5SDimitry Andric namespace object {
200b57cec5SDimitry Andric namespace WindowsRes {
210b57cec5SDimitry Andric 
stripUTF16(const ArrayRef<UTF16> & UTF16Str)220b57cec5SDimitry Andric std::string stripUTF16(const ArrayRef<UTF16> &UTF16Str) {
230b57cec5SDimitry Andric   std::string Result;
240b57cec5SDimitry Andric   Result.reserve(UTF16Str.size());
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric   for (UTF16 Ch : UTF16Str) {
270b57cec5SDimitry Andric     // UTF16Str will have swapped byte order in case of big-endian machines.
280b57cec5SDimitry Andric     // Swap it back in such a case.
29*5f757f3fSDimitry Andric     uint16_t ChValue = support::endian::byte_swap(Ch, llvm::endianness::little);
300b57cec5SDimitry Andric     if (ChValue <= 0xFF)
310b57cec5SDimitry Andric       Result += ChValue;
320b57cec5SDimitry Andric     else
330b57cec5SDimitry Andric       Result += '?';
340b57cec5SDimitry Andric   }
350b57cec5SDimitry Andric   return Result;
360b57cec5SDimitry Andric }
370b57cec5SDimitry Andric 
printData()380b57cec5SDimitry Andric Error Dumper::printData() {
390b57cec5SDimitry Andric   auto EntryPtrOrErr = WinRes->getHeadEntry();
400b57cec5SDimitry Andric   if (!EntryPtrOrErr)
410b57cec5SDimitry Andric     return EntryPtrOrErr.takeError();
420b57cec5SDimitry Andric   auto EntryPtr = *EntryPtrOrErr;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   bool IsEnd = false;
450b57cec5SDimitry Andric   while (!IsEnd) {
460b57cec5SDimitry Andric     printEntry(EntryPtr);
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric     if (auto Err = EntryPtr.moveNext(IsEnd))
490b57cec5SDimitry Andric       return Err;
500b57cec5SDimitry Andric   }
510b57cec5SDimitry Andric   return Error::success();
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric 
printEntry(const ResourceEntryRef & Ref)540b57cec5SDimitry Andric void Dumper::printEntry(const ResourceEntryRef &Ref) {
550b57cec5SDimitry Andric   if (Ref.checkTypeString()) {
560b57cec5SDimitry Andric     auto NarrowStr = stripUTF16(Ref.getTypeString());
570b57cec5SDimitry Andric     SW.printString("Resource type (string)", NarrowStr);
588bcb0991SDimitry Andric   } else {
598bcb0991SDimitry Andric     SmallString<20> IDStr;
608bcb0991SDimitry Andric     raw_svector_ostream OS(IDStr);
618bcb0991SDimitry Andric     printResourceTypeName(Ref.getTypeID(), OS);
628bcb0991SDimitry Andric     SW.printString("Resource type (int)", IDStr);
638bcb0991SDimitry Andric   }
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   if (Ref.checkNameString()) {
660b57cec5SDimitry Andric     auto NarrowStr = stripUTF16(Ref.getNameString());
670b57cec5SDimitry Andric     SW.printString("Resource name (string)", NarrowStr);
680b57cec5SDimitry Andric   } else
690b57cec5SDimitry Andric     SW.printNumber("Resource name (int)", Ref.getNameID());
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   SW.printNumber("Data version", Ref.getDataVersion());
720b57cec5SDimitry Andric   SW.printHex("Memory flags", Ref.getMemoryFlags());
730b57cec5SDimitry Andric   SW.printNumber("Language ID", Ref.getLanguage());
740b57cec5SDimitry Andric   SW.printNumber("Version (major)", Ref.getMajorVersion());
750b57cec5SDimitry Andric   SW.printNumber("Version (minor)", Ref.getMinorVersion());
760b57cec5SDimitry Andric   SW.printNumber("Characteristics", Ref.getCharacteristics());
770b57cec5SDimitry Andric   SW.printNumber("Data size", (uint64_t)Ref.getData().size());
780b57cec5SDimitry Andric   SW.printBinary("Data:", Ref.getData());
790b57cec5SDimitry Andric   SW.startLine() << "\n";
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric } // namespace WindowsRes
830b57cec5SDimitry Andric } // namespace object
840b57cec5SDimitry Andric } // namespace llvm
85