* Add basic disassembler sample

* Improve disassembler out_of_range exception

* Remove double-0x, unnecessary space

* Align instruction count
This commit is contained in:
Eddy Ashton 2019-08-30 18:01:32 +01:00 коммит произвёл GitHub
Родитель 36ca7e32ea
Коммит e5e35c7e84
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 42 добавлений и 4 удалений

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

@ -121,3 +121,4 @@ endfunction()
add_sample(hello_world)
add_sample(sum)
add_sample(erc20)
add_sample(disassembler)

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

@ -71,14 +71,15 @@ namespace eevm
inline std::ostream& operator<<(std::ostream& os, const Instr& i)
{
os << fmt::format(
"{}: {}{} ({:02x} {:02x}); {}",
"{:>5}: {}{} [{:02x}{}]; {}",
i.pc,
i.op.mnemonic,
i.op.has_immediate() ?
fmt::format(" 0x{}", to_lower_hex_str(i.get_immediate())) :
fmt::format(" {}", to_lower_hex_str(i.get_immediate())) :
"",
(int)i.op.opcode,
fmt::join(i.raw_imm, " "),
i.raw_imm.size() > 0 ? fmt::format(" {:02x}", fmt::join(i.raw_imm, " ")) :
"",
i.comment);
return os;
}
@ -124,7 +125,13 @@ namespace eevm
const auto op = getOp((Opcode)opcode);
const auto bytes_left = prog.cend() - it;
if (bytes_left < op.immediate_bytes)
throw std::out_of_range("Immediate exceeds instruction stream.");
throw std::out_of_range(fmt::format(
"Immediate exceeds instruction stream (op {} at "
"instruction {} wants {} bytes, only {} remain)",
op.mnemonic,
(size_t)(it - prog.cbegin()),
op.immediate_bytes,
bytes_left));
auto instr = std::make_unique<Instr>(
op, pc, std::vector<uint8_t>(it, it + op.immediate_bytes));

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

@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "eEVM/disassembler.h"
#include <fmt/format_header_only.h>
#include <iostream>
int usage(const char* bin_name)
{
std::cout << fmt::format("Usage: {} hex_bytecode", bin_name) << std::endl;
std::cout << "Prints disassembly of argument" << std::endl;
return 1;
}
int main(int argc, char** argv)
{
if (argc != 2)
{
return usage(argv[0]);
}
const std::vector<uint8_t> code = eevm::to_bytes(argv[1]);
const auto dis = eevm::Disassembler::dis(code);
std::cout << dis << std::endl;
return 0;
}