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:
David Neto 2016-01-18 15:29:15 -05:00
Родитель 961f5dc544
Коммит c62f41e281
4 изменённых файлов: 49 добавлений и 5 удалений

Просмотреть файл

@ -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.