Add disassembler option to show byte offset
The option is disabled by default. The offset is printed in hex, as a comment after each instruction.
This commit is contained in:
Родитель
961f5dc544
Коммит
c62f41e281
|
@ -251,6 +251,7 @@ typedef enum spv_binary_to_text_options_t {
|
|||
SPV_BINARY_TO_TEXT_OPTION_PRINT = SPV_BIT(1),
|
||||
SPV_BINARY_TO_TEXT_OPTION_COLOR = SPV_BIT(2),
|
||||
SPV_BINARY_TO_TEXT_OPTION_INDENT = SPV_BIT(3),
|
||||
SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET = SPV_BIT(4),
|
||||
SPV_FORCE_32_BIT_ENUM(spv_binary_to_text_options_t)
|
||||
} spv_binary_to_text_options_t;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "assembly_grammar.h"
|
||||
|
@ -48,8 +49,7 @@ namespace {
|
|||
// representation.
|
||||
class Disassembler {
|
||||
public:
|
||||
Disassembler(const libspirv::AssemblyGrammar& grammar,
|
||||
uint32_t options)
|
||||
Disassembler(const libspirv::AssemblyGrammar& grammar, uint32_t options)
|
||||
: grammar_(grammar),
|
||||
print_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_PRINT, options)),
|
||||
color_(print_ &&
|
||||
|
@ -59,7 +59,10 @@ class Disassembler {
|
|||
: 0),
|
||||
text_(),
|
||||
out_(print_ ? out_stream() : out_stream(text_)),
|
||||
stream_(out_.get()) {}
|
||||
stream_(out_.get()),
|
||||
show_byte_offset_(spvIsInBitfield(
|
||||
SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET, options)),
|
||||
byte_offset_(0) {}
|
||||
|
||||
// Emits the assembly header for the module, and sets up internal state
|
||||
// so subsequent callbacks can handle the cases where the entire module
|
||||
|
@ -120,6 +123,8 @@ class Disassembler {
|
|||
std::stringstream text_; // Captures the text, if not printing.
|
||||
out_stream out_; // The Output stream. Either to text_ or standard output.
|
||||
std::ostream& stream_; // The output std::stream.
|
||||
const bool show_byte_offset_; // Should we print byte offset, in hex?
|
||||
size_t byte_offset_; // The number of bytes processed so far.
|
||||
};
|
||||
|
||||
spv_result_t Disassembler::HandleHeader(spv_endianness_t endian,
|
||||
|
@ -145,6 +150,8 @@ spv_result_t Disassembler::HandleHeader(spv_endianness_t endian,
|
|||
<< "; Schema: " << schema << "\n";
|
||||
ResetColor();
|
||||
|
||||
byte_offset_ = SPV_INDEX_INSTRUCTION * sizeof(uint32_t);
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -185,6 +192,19 @@ spv_result_t Disassembler::HandleInstruction(
|
|||
EmitOperand(inst, i);
|
||||
}
|
||||
|
||||
if (show_byte_offset_) {
|
||||
SetGrey();
|
||||
auto saved_flags = stream_.flags();
|
||||
auto saved_fill = stream_.fill();
|
||||
stream_ << " ; 0x" << std::setw(8) << std::hex << std::setfill('0')
|
||||
<< byte_offset_;
|
||||
stream_.flags(saved_flags);
|
||||
stream_.fill(saved_fill);
|
||||
ResetColor();
|
||||
}
|
||||
|
||||
byte_offset_ += inst.num_words * sizeof(uint32_t);
|
||||
|
||||
stream_ << "\n";
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -392,6 +392,24 @@ OpStore %2 %3 Aligned|Volatile 4 ; bogus, but not indented
|
|||
expected);
|
||||
}
|
||||
|
||||
TEST_F(TextToBinaryTest, ShowByteOffsetsWhenRequested) {
|
||||
const std::string input = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
%1 = OpTypeInt 32 0
|
||||
%2 = OpTypeVoid
|
||||
)";
|
||||
const std::string expected =
|
||||
R"(OpCapability Shader ; 0x00000014
|
||||
OpMemoryModel Logical GLSL450 ; 0x0000001c
|
||||
%1 = OpTypeInt 32 0 ; 0x00000028
|
||||
%2 = OpTypeVoid ; 0x00000038
|
||||
)";
|
||||
EXPECT_THAT(EncodeAndDecodeSuccessfully(
|
||||
input, SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET),
|
||||
expected);
|
||||
}
|
||||
|
||||
// Test version string.
|
||||
TEST_F(TextToBinaryTest, VersionString) {
|
||||
auto words = CompileSuccessfully("");
|
||||
|
|
|
@ -52,6 +52,8 @@ Options:
|
|||
The default when output goes to a file.
|
||||
|
||||
--no-indent Don't indent instructions.
|
||||
|
||||
--offsets Show byte offsets for each instruction.
|
||||
)",
|
||||
argv0, argv0);
|
||||
}
|
||||
|
@ -65,6 +67,7 @@ int main(int argc, char** argv) {
|
|||
allow_color = true;
|
||||
#endif
|
||||
bool allow_indent = true;
|
||||
bool show_byte_offsets = false;
|
||||
|
||||
for (int argi = 1; argi < argc; ++argi) {
|
||||
if ('-' == argv[argi][0]) {
|
||||
|
@ -84,6 +87,7 @@ int main(int argc, char** argv) {
|
|||
// Long options
|
||||
if (0 == strcmp(argv[argi], "--no-color")) allow_color = false;
|
||||
if (0 == strcmp(argv[argi], "--no-indent")) allow_indent = false;
|
||||
if (0 == strcmp(argv[argi], "--offsets")) show_byte_offsets = true;
|
||||
if (0 == strcmp(argv[argi], "--help")) {
|
||||
print_usage(argv[0]);
|
||||
return 0;
|
||||
|
@ -114,8 +118,9 @@ int main(int argc, char** argv) {
|
|||
|
||||
uint32_t options = SPV_BINARY_TO_TEXT_OPTION_NONE;
|
||||
|
||||
if (allow_indent)
|
||||
options |= SPV_BINARY_TO_TEXT_OPTION_INDENT;
|
||||
if (allow_indent) options |= SPV_BINARY_TO_TEXT_OPTION_INDENT;
|
||||
|
||||
if (show_byte_offsets) options |= SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET;
|
||||
|
||||
if (!outFile || (0 == strcmp("-", outFile))) {
|
||||
// Print to standard output.
|
||||
|
|
Загрузка…
Ссылка в новой задаче