From 6c61dd51be3d56ae3fecb3110abbee4f997250bf Mon Sep 17 00:00:00 2001
From: dd86k
Date: Fri, 3 Nov 2023 07:46:44 -0400
Subject: [PATCH] Fix dumper disasm stats
---
app/dump/elf.d | 2 +-
app/dump/pe.d | 2 +-
app/dumper.d | 62 ++++++++++++++++++++++++++----------------------
app/main.d | 6 ++++-
src/adbg/error.d | 4 +---
5 files changed, 41 insertions(+), 35 deletions(-)
diff --git a/app/dump/elf.d b/app/dump/elf.d
index 01a27bb2..8b77ddc9 100644
--- a/app/dump/elf.d
+++ b/app/dump/elf.d
@@ -22,7 +22,7 @@ int dump_elf(adbg_object_t *o, uint flags) {
if (flags & DumpOpt.sections)
dump_elf_sections(o);
- if (flags & DumpOpt.disasm)
+ if (flags & DumpOpt.disasm_any)
dump_elf_disasm(o, flags);
return 0;
diff --git a/app/dump/pe.d b/app/dump/pe.d
index 31ba1142..68aa64f1 100644
--- a/app/dump/pe.d
+++ b/app/dump/pe.d
@@ -45,7 +45,7 @@ int dump_pe(adbg_object_t *o, uint flags) {
if (flags & DumpOpt.debug_)
dump_pe_debug(o);
- if (flags & DumpOpt.disasm)
+ if (flags & DumpOpt.disasm_any)
dump_pe_disasm(o, flags);
return EXIT_SUCCESS;
diff --git a/app/dumper.d b/app/dumper.d
index 31c881cb..df04e879 100644
--- a/app/dumper.d
+++ b/app/dumper.d
@@ -50,7 +50,7 @@ enum DumpOpt {
dynrelocs = BIT!13,
/// Disassemble executable sections
- disasm_code = BIT!22,
+ disasm = BIT!22,
/// Disassembly statistics
disasm_stats = BIT!23,
/// Disassemble all sections
@@ -64,8 +64,8 @@ enum DumpOpt {
symbols | debug_ | tls | loadcfg |
exports | imports | sections,
- /// Wants to disassemble at least something
- disasm = disasm_code | disasm_stats | disasm_all,
+ /// Any form of dissasembler is requested
+ disasm_any = disasm | disasm_stats | disasm_all,
}
/// Dump given file to stdout.
@@ -121,6 +121,8 @@ int app_dump() {
// or dprint(group_name, // header, program_header, etc.
// spec, name, value, ...)
// or consider struct DumperPrinter or similar
+//TODO: object aware dumps
+// generic: dump_import(lib, name), etc.
private enum FORMAT_FIELD = " %-30s: ";
@@ -136,8 +138,9 @@ void dprint_warn(const(char) *message) {
printf("warning: %s\n", message);
}
void dprint_error(const(char) *message) {
+ import core.stdc.stdlib : exit;
printf("error: %s\n", message);
- panic();
+ exit(1);
}
void dprint_section(uint count, const(char) *section, uint max) {
@@ -288,9 +291,7 @@ int dprint_disassemble_object(adbg_object_t *o,
void* data, ulong size,
uint flags) {
- if (size >= o.buffer_size ||
- data < o.buffer ||
- data + size >= o.buffer) {
+ if (data + size >= o.buffer + o.file_size) {
dprint_error("Buffer outside file");
}
@@ -309,7 +310,6 @@ int dprint_disassemble(AdbgMachine machine,
adbg_disassembler_t *dasm = cast(adbg_disassembler_t*)malloc(adbg_disassembler_t.sizeof);
if (dasm == null)
panic(AdbgError.crt);
-
scope(exit) free(dasm);
if (adbg_dasm_open(dasm, machine))
@@ -323,37 +323,41 @@ int dprint_disassemble(AdbgMachine machine,
// stats mode
if (flags & DumpOpt.disasm_stats) {
- uint s_avg; /// instruction average size
- uint s_min; /// smallest instruction size
- uint s_max; /// longest instruction size
- uint s_cnt; /// instruction count
- uint s_ill; /// Number of illegal instructions
+ uint stat_avg; /// instruction average size
+ uint stat_min = uint.max; /// smallest instruction size
+ uint stat_max; /// longest instruction size
+ uint stat_total; /// total instruction count
+ uint stat_illegal; /// Number of illegal instructions
L_STAT:
switch (adbg_dasm(dasm, &op)) with (AdbgError) {
case success:
- s_avg += op.size;
- ++s_cnt;
- if (op.size > s_max)
- s_max = op.size;
- if (op.size < s_min)
- s_min = op.size;
+ stat_avg += op.size;
+ ++stat_total;
+ if (op.size > stat_max) stat_max = op.size;
+ if (op.size < stat_min) stat_min = op.size;
goto L_STAT;
case illegalInstruction:
- s_avg += op.size;
- ++s_cnt;
- ++s_ill;
- goto L_DISASM;
+ stat_avg += op.size;
+ ++stat_total;
+ ++stat_illegal;
+ goto L_STAT;
case outOfData: break;
default: panic();
}
printf(
"Opcode statistics\n"~
- "average size : %.3f\n"~
- "smallest size: %u\n"~
- "biggest size : %u\n"~
- "illegal : %u\n"~
- "total : %u\n",
- cast(float)s_avg / s_cnt, s_min, s_max, s_ill, s_cnt
+ "average size : %.3f Bytes\n"~
+ "shortest : %u Bytes\n"~
+ "largest : %u Bytes\n"~
+ "illegal : %u instructions\n"~
+ "valid : %u instructions\n"~
+ "total : %u instructions\n",
+ cast(float)stat_avg / stat_total,
+ stat_min,
+ stat_max,
+ stat_illegal,
+ stat_total - stat_illegal,
+ stat_total
);
return 0;
}
diff --git a/app/main.d b/app/main.d
index 357149d8..dd64a800 100644
--- a/app/main.d
+++ b/app/main.d
@@ -83,6 +83,10 @@ struct option_t {
extern(C) int function(const(char)*) fa;
}
}
+//TODO: --dump-offset/--dump-seek/--dump-start - Starting offset for raw blob
+//TODO: --dump-length/--dump-end - Length or end
+//TODO: --dump-imports-names - Shared library names only
+//TODO: --dump-imports-all - Dependency walker
immutable option_t[] options = [
// general
{ 'a', "arch", "Select architecture for disassembler (default=platform)", true, fa: &cli_march },
@@ -104,7 +108,7 @@ immutable option_t[] options = [
// { 0, "dump-debug", "Dump object's debug information", false, &cli_dump_debug },
{ 0, "dump-disasm", "Dump object's disassembly", false, &cli_dump_disasm },
{ 0, "dump-disasm-all", "Dump object's disassembly for all sections", false, &cli_dump_disasm_all },
- { 0, "dump-disasm-stats", "Dump object's disassembly statistics", false, &cli_dump_disasm_stats },
+ { 0, "dump-disasm-stats", "Dump object's disassembly statistics for executable sections", false, &cli_dump_disasm_stats },
{ 0, "dump-blob", "Dump as raw binary blob", false, &cli_dump_blob },
// pages
{ 'h', "help", "Show this help screen and exit", false, &cli_help },
diff --git a/src/adbg/error.d b/src/adbg/error.d
index b9d0e7c5..b3d4bb8c 100644
--- a/src/adbg/error.d
+++ b/src/adbg/error.d
@@ -29,8 +29,6 @@ version (Windows) {
extern (C):
/// Error codes.
-///
-/// These aren't really meant to be used directly.
enum AdbgError {
//
// 0-99: Generic
@@ -143,7 +141,7 @@ private immutable adbg_error_msg_t[] errors_msg = [
{ AdbgError.invalidOption, "Invalid disassembler option." },
{ AdbgError.invalidOptionValue, "Invalid value for disassembler option." },
{ AdbgError.illegalInstruction, "Illegal instruction." },
- { AdbgError.outOfData, "The input buffer has been depleted in an unexpected fashion." },
+ { AdbgError.outOfData, "The input buffer has been depleted." },
{ AdbgError.opcodeLimit, "The opcode exhausted its architectural limit." },
//
// Object server