#include "source/disassemble.h"
#include <algorithm>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <memory>
#include <set>
#include <stack>
#include <unordered_map>
#include <utility>
#include "source/assembly_grammar.h"
#include "source/binary.h"
#include "source/diagnostic.h"
#include "source/ext_inst.h"
#include "source/opcode.h"
#include "source/parsed_operand.h"
#include "source/print.h"
#include "source/spirv_constant.h"
#include "source/spirv_endian.h"
#include "source/util/hex_float.h"
#include "source/util/make_unique.h"
#include "spirv-tools/libspirv.h"
namespace spvtools {
namespace {
struct BlockSuccessors { … };
class ParsedInstruction { … };
struct SingleBlock { … };
struct ControlFlowGraph { … };
class Disassembler { … };
spv_result_t Disassembler::HandleHeader(spv_endianness_t endian,
uint32_t version, uint32_t generator,
uint32_t id_bound, uint32_t schema) { … }
spv_result_t Disassembler::HandleInstruction(
const spv_parsed_instruction_t& inst) { … }
uint32_t GetOperand(const spv_parsed_instruction_t* instruction,
uint32_t operand) { … }
std::unordered_map<uint32_t, uint32_t> BuildControlFlowGraph(
ControlFlowGraph& cfg) { … }
void Nest(ControlFlowGraph& cfg,
const std::unordered_map<uint32_t, uint32_t>& id_to_index,
uint32_t id, uint32_t level) { … }
void NestSuccessors(ControlFlowGraph& cfg, const SingleBlock& block,
const std::unordered_map<uint32_t, uint32_t>& id_to_index) { … }
struct StackEntry { … };
void VisitSuccesor(std::stack<StackEntry>* dfs_stack,
const std::unordered_map<uint32_t, uint32_t>& id_to_index,
uint32_t id) { … }
std::vector<uint32_t> OrderBlocks(
ControlFlowGraph& cfg,
const std::unordered_map<uint32_t, uint32_t>& id_to_index) { … }
void Disassembler::EmitCFG() { … }
spv_result_t Disassembler::SaveTextResult(spv_text* text_result) const { … }
spv_result_t DisassembleHeader(void* user_data, spv_endianness_t endian,
uint32_t , uint32_t version,
uint32_t generator, uint32_t id_bound,
uint32_t schema) { … }
spv_result_t DisassembleInstruction(
void* user_data, const spv_parsed_instruction_t* parsed_instruction) { … }
class WrappedDisassembler { … };
spv_result_t DisassembleTargetHeader(void* user_data, spv_endianness_t endian,
uint32_t , uint32_t version,
uint32_t generator, uint32_t id_bound,
uint32_t schema) { … }
spv_result_t DisassembleTargetInstruction(
void* user_data, const spv_parsed_instruction_t* parsed_instruction) { … }
uint32_t GetLineLengthWithoutColor(const std::string line) { … }
constexpr int kStandardIndent = …;
constexpr int kBlockNestIndent = …;
constexpr int kBlockBodyIndentOffset = …;
constexpr uint32_t kCommentColumn = …;
}
namespace disassemble {
InstructionDisassembler::InstructionDisassembler(const AssemblyGrammar& grammar,
std::ostream& stream,
uint32_t options,
NameMapper name_mapper)
: … { … }
void InstructionDisassembler::EmitHeaderSpirv() { … }
void InstructionDisassembler::EmitHeaderVersion(uint32_t version) { … }
void InstructionDisassembler::EmitHeaderGenerator(uint32_t generator) { … }
void InstructionDisassembler::EmitHeaderIdBound(uint32_t id_bound) { … }
void InstructionDisassembler::EmitHeaderSchema(uint32_t schema) { … }
void InstructionDisassembler::EmitInstruction(
const spv_parsed_instruction_t& inst, size_t inst_byte_offset) { … }
void InstructionDisassembler::EmitInstructionInBlock(
const spv_parsed_instruction_t& inst, size_t inst_byte_offset,
uint32_t block_indent) { … }
void InstructionDisassembler::EmitInstructionImpl(
const spv_parsed_instruction_t& inst, size_t inst_byte_offset,
uint32_t block_indent, bool is_in_block) { … }
void InstructionDisassembler::GenerateCommentForDecoratedId(
const spv_parsed_instruction_t& inst) { … }
void InstructionDisassembler::EmitSectionComment(
const spv_parsed_instruction_t& inst, bool& inserted_decoration_space,
bool& inserted_debug_space, bool& inserted_type_space) { … }
void InstructionDisassembler::EmitOperand(std::ostream& stream,
const spv_parsed_instruction_t& inst,
const uint16_t operand_index) const { … }
void InstructionDisassembler::EmitMaskOperand(std::ostream& stream,
const spv_operand_type_t type,
const uint32_t word) const { … }
void InstructionDisassembler::ResetColor(std::ostream& stream) const { … }
void InstructionDisassembler::SetGrey(std::ostream& stream) const { … }
void InstructionDisassembler::SetBlue(std::ostream& stream) const { … }
void InstructionDisassembler::SetYellow(std::ostream& stream) const { … }
void InstructionDisassembler::SetRed(std::ostream& stream) const { … }
void InstructionDisassembler::SetGreen(std::ostream& stream) const { … }
void InstructionDisassembler::ResetColor() { … }
void InstructionDisassembler::SetGrey() { … }
void InstructionDisassembler::SetBlue() { … }
void InstructionDisassembler::SetYellow() { … }
void InstructionDisassembler::SetRed() { … }
void InstructionDisassembler::SetGreen() { … }
}
std::string spvInstructionBinaryToText(const spv_target_env env,
const uint32_t* instCode,
const size_t instWordCount,
const uint32_t* code,
const size_t wordCount,
const uint32_t options) { … }
}
spv_result_t spvBinaryToText(const spv_const_context context,
const uint32_t* code, const size_t wordCount,
const uint32_t options, spv_text* pText,
spv_diagnostic* pDiagnostic) { … }