STCompiler 加 --disasm:反汇编已编译的 .stb。

- STCompiler <name>.stb --disasm:读映像 → 校验 → 打印段摘要 + 函数表逐条反汇编(文件绝对偏移)+ 常量表 + 数据段 hex
- 映像无符号表,按 fn_id/槽号显示;损坏/缺失文件报错退出码 1
- 验证:line1.stb 完整反汇编(17 条 MAIN 指令)与损坏文件拒绝
This commit is contained in:
2026-08-21 13:49:06 +08:00
parent 17c62f0a1f
commit b18fd6014c
+70
View File
@@ -14,16 +14,79 @@
#include "compiler/Linker.h" #include "compiler/Linker.h"
#include "compiler/Project.h" #include "compiler/Project.h"
#include "compiler/Typecheck.h" #include "compiler/Typecheck.h"
#include "isa/Encode.h"
#include "isa/Image.h" #include "isa/Image.h"
namespace { namespace {
void usage() { void usage() {
std::printf("usage: STCompiler <project.toml> [-o <name>.stb]\n" std::printf("usage: STCompiler <project.toml> [-o <name>.stb]\n"
" STCompiler <name>.stb --disasm\n"
" 解析工程并编译(词法 → 语法 → 链接 → 类型 → 寄存器码)\n" " 解析工程并编译(词法 → 语法 → 链接 → 类型 → 寄存器码)\n"
" -o <name>.stb 编译并写出映像文件\n" " -o <name>.stb 编译并写出映像文件\n"
" 无 -o 只打印文件集合与工程哈希(12.3 阶段)\n" " 无 -o 只打印文件集合与工程哈希(12.3 阶段)\n"
" --disasm 反汇编一个已编译的 .stb 映像\n"
" --help 打印本帮助\n"); " --help 打印本帮助\n");
} }
// 反汇编一个已编译映像(函数表逐条 + 常量表 + 数据段摘要)。
// 映像无符号表,按 fn_id / 槽号显示;指令偏移为文件绝对字节偏移。
int dump_image(const char* path) {
std::vector<uint8_t> bytes;
std::string err;
if (!isa::read_stb_file(path, &bytes, &err)) {
std::fprintf(stderr, "error: %s\n", err.c_str());
return 1;
}
const isa::ImageView v = isa::ImageView::from(bytes);
if (!v.ok()) {
std::fprintf(stderr, "error: %s\n", v.error().c_str());
return 1;
}
const isa::ImageHeader& h = v.header();
std::printf("image: %s (%zu bytes, %u functions, %u globals, entry fn %u)\n",
path, bytes.size(), h.n_funcs, h.n_globals, h.entry_fn_id);
std::printf(" dt_ms=%u cycle_limit=%u hash=0x%016llx\n", h.dt_ms,
h.cycle_limit, static_cast<unsigned long long>(h.project_hash));
if (h.n_consts) {
std::printf("constants:\n");
for (uint32_t i = 0; i < h.n_consts; ++i) {
const isa::ConstEntry c = v.const_entry(i);
const char* tag = c.tag == isa::types::Bool ? "BOOL"
: c.tag == isa::types::Int ? "INT"
: "TIME";
std::printf(" [%u] %s %llu\n", i, tag,
static_cast<unsigned long long>(c.value));
}
}
std::printf("functions:\n");
for (uint32_t i = 0; i < h.n_funcs; ++i) {
const isa::FuncRow r = v.func_row(i);
std::printf(" fn %u: nregs=%u, offset=%u, len=%u\n", i, r.nregs,
r.code_offset, r.code_len);
const uint8_t* base = v.code_bytes() + r.code_offset;
for (uint32_t j = 0; j < r.code_len; ++j) {
char buf[64];
isa::disasm(reinterpret_cast<const uint32_t*>(base)[j], buf, sizeof buf);
std::printf(" 0x%04x %s\n",
h.offset_code + r.code_offset + j * 4, buf);
}
}
if (v.data_len()) {
std::printf("data (%zu bytes):\n", v.data_len());
const uint8_t* d = v.data_bytes();
for (size_t i = 0; i < v.data_len(); i += 16) {
std::printf(" 0x%04x:", static_cast<unsigned>(i));
for (size_t j = 0; j < 16 && i + j < v.data_len(); ++j) {
std::printf(" %02x", d[i + j]);
}
std::printf("\n");
}
}
return 0;
}
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
@@ -37,6 +100,13 @@ int main(int argc, char** argv) {
return 0; return 0;
} }
// --disasm:第一参数是 .stb 路径,不重新编译
for (int i = 1; i < argc; ++i) {
if (std::strcmp(argv[i], "--disasm") == 0) {
return dump_image(argv[1]);
}
}
const std::string toml_path = argv[1]; const std::string toml_path = argv[1];
std::string out_path; std::string out_path;
for (int i = 2; i + 1 < argc; ++i) { for (int i = 2; i + 1 < argc; ++i) {