[llvm-readobj] Teach readobj to dump .res files (WindowsResource).
This enables readobj to output Windows resource files (.res). This way,
we'll be able to test .res outputs without comparing them byte-by-byte
with "magic binary files" generated by MS toolchain.
Differential Revision: https://reviews.llvm.org/D38058
llvm-svn: 313790
diff --git a/llvm/tools/llvm-readobj/CMakeLists.txt b/llvm/tools/llvm-readobj/CMakeLists.txt
index f5b1a5b..5447167 100644
--- a/llvm/tools/llvm-readobj/CMakeLists.txt
+++ b/llvm/tools/llvm-readobj/CMakeLists.txt
@@ -19,6 +19,7 @@
ObjDumper.cpp
WasmDumper.cpp
Win64EHDumper.cpp
+ WindowsResourceDumper.cpp
)
add_llvm_tool_symlink(llvm-readelf llvm-readobj)
diff --git a/llvm/tools/llvm-readobj/WindowsResourceDumper.cpp b/llvm/tools/llvm-readobj/WindowsResourceDumper.cpp
new file mode 100644
index 0000000..6733f71
--- /dev/null
+++ b/llvm/tools/llvm-readobj/WindowsResourceDumper.cpp
@@ -0,0 +1,79 @@
+//===-- WindowsResourceDumper.cpp - Windows Resource printer --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Windows resource (.res) dumper for llvm-readobj.
+//
+//===----------------------------------------------------------------------===//
+
+#include "WindowsResourceDumper.h"
+#include "Error.h"
+#include "llvm-readobj.h"
+#include "llvm/Object/WindowsResource.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) {
+ if (Ch <= 0xFF)
+ Result += Ch;
+ 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
+ SW.printNumber("Resource type (int)", Ref.getTypeID());
+
+ 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", Ref.getData().size());
+ SW.printBinary("Data:", Ref.getData());
+ SW.startLine() << "\n";
+}
+
+} // namespace WindowsRes
+} // namespace object
+} // namespace llvm
diff --git a/llvm/tools/llvm-readobj/WindowsResourceDumper.h b/llvm/tools/llvm-readobj/WindowsResourceDumper.h
new file mode 100644
index 0000000..ca6da40
--- /dev/null
+++ b/llvm/tools/llvm-readobj/WindowsResourceDumper.h
@@ -0,0 +1,37 @@
+//===- WindowsResourceDumper.h - Windows Resource printer -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_READOBJ_WINDOWSRESOURCEDUMPER_H
+#define LLVM_TOOLS_LLVM_READOBJ_WINDOWSRESOURCEDUMPER_H
+
+#include "llvm/Object/WindowsResource.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+namespace llvm {
+namespace object {
+namespace WindowsRes {
+
+class Dumper {
+public:
+ Dumper(WindowsResource *Res, ScopedPrinter &SW) : SW(SW), WinRes(Res) {}
+
+ Error printData();
+
+private:
+ ScopedPrinter &SW;
+ WindowsResource *WinRes;
+
+ void printEntry(const ResourceEntryRef &Ref);
+};
+
+} // namespace WindowsRes
+} // namespace object
+} // namespace llvm
+
+#endif
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 7bfb18f..f24ce67 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -22,12 +22,14 @@
#include "llvm-readobj.h"
#include "Error.h"
#include "ObjDumper.h"
+#include "WindowsResourceDumper.h"
#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/WindowsResource.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DataTypes.h"
@@ -522,6 +524,15 @@
}
}
+/// @brief Dumps \a WinRes, Windows Resource (.res) file;
+static void dumpWindowsResourceFile(WindowsResource *WinRes) {
+ ScopedPrinter Printer{outs()};
+ WindowsRes::Dumper Dumper(WinRes, Printer);
+ if (auto Err = Dumper.printData())
+ reportError(WinRes->getFileName(), std::move(Err));
+}
+
+
/// @brief Opens \a File and dumps it.
static void dumpInput(StringRef File) {
@@ -540,6 +551,8 @@
dumpObject(Obj);
else if (COFFImportFile *Import = dyn_cast<COFFImportFile>(&Binary))
dumpCOFFImportFile(Import);
+ else if (WindowsResource *WinRes = dyn_cast<WindowsResource>(&Binary))
+ dumpWindowsResourceFile(WinRes);
else
reportError(File, readobj_error::unrecognized_file_format);
}