diff --git a/common/cli.d b/common/cli.d
index badc371..a88a6a0 100644
--- a/common/cli.d
+++ b/common/cli.d
@@ -19,7 +19,7 @@
enum COPYRIGHT = "Copyright (c) 2019-2024 dd86k
";
/// License string
-immutable(char) *page_license =
+immutable char *page_license =
COPYRIGHT~`
All rights reserved.
@@ -117,6 +117,40 @@
/// Default option for --license
enum option_license = option_t(0, "license", "Show the license page and exit", &cli_license);
+private
+immutable(option_t)* getoptlong(const(char)* arg, immutable(option_t)[] options) {
+ foreach (ref opt; options) {
+ if (strncmp(arg, opt.longname.ptr, opt.longname.length))
+ continue;
+ return &opt;
+ }
+ return null;
+}
+private
+immutable(option_t)* getoptshort(char arg, immutable(option_t)[] options) {
+ foreach (ref opt; options) {
+ if (arg != opt.shortname)
+ continue;
+ return &opt;
+ }
+ return null;
+}
+private
+int getoptexec(immutable(option_t)* option, int argc, const(char) **argv, int index) {
+ final switch (option.argtype) {
+ case ARG_NONE:
+ if (option.f()) return -1;
+ return 0;
+ case ARG_STRING: // with argument
+ if (++index >= argc)
+ return getoptEmissingLong(option.longname.ptr);
+ const(char) *val = argv[index];
+ if (option.fa(val))
+ return getoptEinvValLong(option.longname.ptr, val);
+ return 1;
+ }
+}
+
//TODO: Return error
// <0 -> error
// 0 -> no args left
@@ -125,109 +159,106 @@
/// Interpret options
int getopt(int argc, const(char) **argv, immutable(option_t)[] options) {
// On re-entry, clear extras and error buffers
- if (getoptextras) {
- free(getoptextras);
- getoptextras = null;
- }
- if (getopterrbuf) {
- free(getopterrbuf);
- getopterrbuf = null;
- }
+ getoptreset();
- const(char) *arg = void;
- const(char) *val = void;
- CLI: for (int argi = 1; argi < argc; ++argi) {
- arg = argv[argi];
+ int i = 1;
+ for (; i < argc; ++i) {
+ const(char) *arg = argv[i]; // Current argument
- if (arg[1] == '-') { // Long options
+ immutable(option_t) *option = void;
+ if (arg[1] == '-') { // Long option
const(char) *argLong = arg + 2;
// test for "--" (extra args)
- /*if (argLong[0] == 0) {
- if (cli_args_stop(++argi, argc, argv))
- return -1;
- break CLI;
- }*/
+ if (argLong[0] == 0)
+ goto Lskip;
- // Check options
- L_LONG: foreach (ref opt; options) {
- //TODO: test for '='
- // --example=value
-
- if (strncmp(argLong, opt.longname.ptr, opt.longname.length))
- continue L_LONG;
-
- // no argument expected
- if (opt.argtype == ARG_NONE) {
- if (opt.f())
- return -1;
- continue CLI;
- }
-
- // with argument
- if (++argi >= argc) {
- getoptEmissingLong(opt.longname.ptr);
- return -1;
- }
- val = argv[argi];
- if (opt.fa(val)) {
- getoptEinvValLong(opt.longname.ptr, val);
- return -1;
- }
- continue CLI;
- }
-
- getoptEunknown(arg);
- return -1;
- } else if (arg[0] == '-') { // Short options
- // test for "-" (stdin)
+ option = getoptlong(argLong, options);
+ } else if (arg[0] == '-') { // Short option
char argShort = arg[1];
- if (argShort == 0) { // "-"
- getopterrbuf = cast(char*)"main: standard input not supported";
- return -1;
+
+ // Test for null (often for "-")
+ if (argShort == 0) {
+ getoptaddextra(argc, arg);
+ continue;
}
- L_SHORT: foreach (ref opt; options) {
- if (argShort != opt.shortname)
- continue L_SHORT;
-
- // no argument
- if (opt.argtype == ARG_NONE) {
- if (opt.f())
- return -1;
- continue CLI;
- }
-
- // with argument
- if (++argi >= argc) {
- getoptEmissingShort(argShort);
- return -1;
- }
- val = argv[argi];
- if (opt.fa(val)) {
- getoptEinvValShort(opt.shortname, val);
- return -1;
- }
- continue CLI;
- }
-
- getoptEunknown(arg);
- return -1;
- } else {
+ option = getoptshort(argShort, options);
+ } else { // Not a switch
getoptaddextra(argc, arg);
- continue CLI;
+ continue;
}
+
+ // Option was not found
+ if (option == null)
+ return getoptEunknown(arg);
+
+ // Execute option callback
+ int e = getoptexec(option, argc, argv, i);
+ if (e < 0) return e;
+ i += e;
}
- return 0;
+ return getoptleftcount();
+
+Lskip: // When '--' is given
+ for (++i; i < argc; ++i) {
+ const(char) *arg = argv[i]; // Current argument
+ getoptaddextra(argc, arg);
+ }
+ return getoptleftcount();
}
unittest {
+ __gshared int hit;
+ static int opttest() {
+ ++hit;
+ return 0;
+ }
+ static immutable(option_t)[] options = [
+ option_t('t', "test", "testing switch", &opttest),
+ ];
+ static const(char) **argv = [
+ "program", "argument", "--test", "--", "--test"
+ ];
+ static int argc = 5;
+
+ int e = getopt(argc, argv, options);
+ assert(e == 2); // Two leftover argument
+ assert(hit == 1); // --test switch hit once
+
+ const(char) **leftovers = getoptleftovers();
+ assert(leftovers);
+ assert(strcmp(*leftovers, "argument") == 0);
+ assert(strcmp(*(leftovers + 1), "--test") == 0);
+}
+unittest {
+ __gshared int hit;
+ static int opttest() {
+ ++hit;
+ return 0;
+ }
+ static immutable(option_t)[] options = [
+ option_t('t', "test", "testing switch", &opttest),
+ ];
+ static const(char) **argv = [
+ "alicedbg", "--", "alicedbg.exe", "--version"
+ ];
+ static int argc = 4;
+
+ int e = getopt(argc, argv, options);
+ assert(e == 2); // Two leftover argument
+ assert(hit == 0); // --test switch never hit
+
+ const(char) **leftovers = getoptleftovers();
+ assert(leftovers);
+ assert(strcmp(*leftovers, "alicedbg.exe") == 0);
+ assert(strcmp(*(leftovers + 1), "--version") == 0);
}
/// Print options
-void getoptprinter(immutable(option_t)[] options, int skip = 0) {
+void getoptprinter(immutable(option_t)[] options) {
static immutable int padding = -17;
- foreach (ref option; options[skip..$]) { with (option)
+ foreach (ref option; options) { with (option)
if (shortname)
printf(" -%c, --%*s %s\n", shortname, padding, longname.ptr, description.ptr);
else
@@ -235,10 +266,24 @@
}
}
+// Reset getopt internals
+private void getoptreset() {
+ if (getoptextras) {
+ free(getoptextras);
+ getoptextras = null;
+ }
+ getoptextrascnt = 0;
+ if (getopterrbuf) {
+ free(getopterrbuf);
+ getopterrbuf = null;
+ }
+}
+
// CLI "extra" argument handling
private __gshared const(char)** getoptextras;
private __gshared int getoptextrascnt;
+//TODO: This should error out
private void getoptaddextra(int argc, const(char)* extra) {
if (getoptextrascnt >= argc)
return;
@@ -248,13 +293,14 @@
return;
}
getoptextras[getoptextrascnt++] = extra;
+ getoptextras[getoptextrascnt] = null;
}
/// Get remaining arguments
-const(char)** getoptrem() {
+const(char)** getoptleftovers() {
return getoptextras;
}
/// Get remaining argument count
-int getoptremcnt() {
+int getoptleftcount() {
return getoptextrascnt;
}
@@ -264,7 +310,7 @@
private __gshared char* getopterrbuf;
/// Get getopt error message
-const(char)* getopterrstring() {
+const(char)* getopterror() {
return getopterrbuf ? getopterrbuf : "No errors occured";
}
@@ -278,30 +324,35 @@
}
return 0;
}
-private void getoptEunknown(const(char)* opt) {
- if (getopt_prepbuf()) return;
+private int getoptEunknown(const(char)* opt) {
+ if (getopt_prepbuf()) return -100;
snprintf(getopterrbuf, GETOPTBFSZ,
"main: unknown option '%s'\n", opt);
+ return -1;
}
-private void getoptEinvValLong(const(char)* opt, const(char)* val) {
- if (getopt_prepbuf()) return;
+private int getoptEinvValLong(const(char)* opt, const(char)* val) {
+ if (getopt_prepbuf()) return -100;
snprintf(getopterrbuf, GETOPTBFSZ,
"main: '%s' is an invalid value for --%s\n", val, opt);
+ return -1;
}
-private void getoptEinvValShort(char opt, const(char)* val) {
- if (getopt_prepbuf()) return;
+private int getoptEinvValShort(char opt, const(char)* val) {
+ if (getopt_prepbuf()) return -100;
snprintf(getopterrbuf, GETOPTBFSZ,
"main: '%s' is an invalid value for -%c\n", val, opt);
+ return -1;
}
-private void getoptEmissingLong(const(char)* opt) {
- if (getopt_prepbuf()) return;
+private int getoptEmissingLong(const(char)* opt) {
+ if (getopt_prepbuf()) return -100;
snprintf(getopterrbuf, GETOPTBFSZ,
"main: missing argument for --%s\n", opt);
+ return -1;
}
-private void getoptEmissingShort(char opt) {
- if (getopt_prepbuf()) return;
+private int getoptEmissingShort(char opt) {
+ if (getopt_prepbuf()) return -100;
snprintf(getopterrbuf, GETOPTBFSZ,
"main: missing argument for -%c\n", opt);
+ return -1;
}
/// Is user asking for help with this option?
diff --git a/common/error.d b/common/error.d
index 8f81be6..b36ffc3 100644
--- a/common/error.d
+++ b/common/error.d
@@ -5,16 +5,25 @@
/// License: BSD-3-Clause-Clear
module common.error;
-import core.stdc.stdlib : exit;
-import core.stdc.string : strerror;
-import core.stdc.errno : errno;
+
+import adbg.platform;
+import adbg.include.c.stdlib : exit;
+import adbg.debugger.exception : adbg_exception_t, adbg_exception_name;
+import adbg.self;
+import adbg.machines : adbg_machine_default;
+import adbg.disassembler;
+import adbg.error;
+import adbg.debugger.process;
import adbg.error;
import adbg.disassembler;
import adbg.debugger.exception;
-import adbg.machines : AdbgMachine;
+import core.stdc.string : strerror;
+import core.stdc.errno : errno;
import core.stdc.stdio;
import core.stdc.stdlib : malloc;
+extern (C):
+
void print_adbg_error(
const(char)* mod = cast(char*)__MODULE__,
int line = __LINE__) {
@@ -34,11 +43,53 @@
const(char)* mod = cast(char*)__MODULE__,
int line = __LINE__) {
printf("%s@%u: %s\n", mod, line, message);
- exit(0);
+ exit(code);
}
-void panic_crt() {
- panic(errno, strerror(errno));
+void panic_crt() { panic(errno, strerror(errno)); }
+void panic_adbg() { panic(adbg_errno(), adbg_error_msg()); }
+
+void oopsie(adbg_process_t *proc, adbg_exception_t *ex) {
+ puts(
+`
+ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ _|_|_|_| |_|_|_|_ _|_|_|_ _|_|_|_| |_| |_| |_|
+|_| |_|_ _|_| |_|_ _|_| |_|_ _ |_|_ _|_| |_|
+|_| |_|_|_|_ |_|_|_|_| |_|_|_ |_|_|_|_| |_|
+|_|_ _ _ |_| |_| |_| |_| _ _ _|_| |_| |_| _
+ |_|_|_| |_| |_| |_| |_| |_|_|_| |_| |_| |_|
+`
+ );
+
+ printf(
+ "Exception : %s\n"~
+ "PID : %d\n",
+ adbg_exception_name(ex), adbg_process_get_pid(proc)); // casting is temp
+
+ //TODO: Get thread context
+
+ // Fault address & disasm if available
+ if (ex.faultz) {
+ printf("Address : %#zx\n", ex.faultz);
+
+ adbg_opcode_t op = void;
+ adbg_disassembler_t *dis = adbg_dis_open(adbg_machine_default());
+ printf("Instruction:");
+ if (dis && adbg_dis_process_once(dis, &op, proc, ex.fault_address) == 0) {
+ // Print address
+ // Print machine bytes
+ for (size_t bi; bi < op.size; ++bi)
+ printf(" %02x", op.machine[bi]);
+ //
+ printf(" (%s", op.mnemonic);
+ if (op.operands)
+ printf(" %s", op.operands);
+ //
+ puts(")");
+ } else {
+ printf(" Disassembly unavailable (%s)\n", adbg_error_msg());
+ }
+ }
+
+ //TODO: Option to attach debugger to this process
+ exit(ex.oscode);
}
-void panic_adbg() {
- panic(adbg_errno(), adbg_error_msg());
-}
\ No newline at end of file
diff --git a/debugger/main.d b/debugger/main.d
index 46cde2b..e07f90b 100644
--- a/debugger/main.d
+++ b/debugger/main.d
@@ -16,6 +16,7 @@
import core.stdc.stdlib : strtol, EXIT_SUCCESS, EXIT_FAILURE;
import core.stdc.stdio;
import debugger, shell;
+import common.error;
import common.cli;
import common.utils : unformat64;
@@ -23,12 +24,11 @@
immutable option_t[] options = [
// secrets
- option_t(0, "meow", "Meow and exit", &cli_meow),
+ option_t(0, "meow", null, &cli_meow),
// common options
option_arch,
option_syntax,
// debugger options
- option_t(0, "args", "Debugger: Supply arguments to executable", &cli_args),
// option_t('E', "env", "Debugger: Supply environment variables to executable", &cli_env),
option_t('p', "attach", "Debugger: Attach to Process ID", &cli_pid),
// pages
@@ -41,44 +41,6 @@
enum NUMBER_OF_SECRETS = 1;
//
-// ANCHOR --args/--
-//
-
-int cli_args_stop(int argi, int argc, const(char) **argv) { // --
- import adbg.utils.strings : adbg_util_move;
-
- //TODO: Allocate pointer buffer instead using calloc
-
- enum MAX = 16;
- __gshared const(char) *[MAX] args;
-
- opt_file_argv = cast(const(char)**)args;
-
- int left = argc - argi; /// to move
- void **s = cast(void**)(argv+argi);
-
- int m = adbg_util_move(
- cast(void**)&opt_file_argv, MAX,
- cast(void**)&s, left);
-
- debug assert(m == left, "cli_argsdd: 'adbg_util_move' Failed due to small buffer");
-
- return EXIT_SUCCESS;
-}
-int cli_args(const(char) *val) { // --args
- import adbg.utils.strings : adbg_util_expand;
-
- int argc = void;
- char **argv = adbg_util_expand(val, &argc);
-
- if (argc == 0)
- return EXIT_FAILURE;
-
- opt_file_argv = cast(const(char)**)argv;
- return EXIT_SUCCESS;
-}
-
-//
// ANCHOR -E, --env
//
@@ -122,7 +84,7 @@
"\n"~
"OPTIONS"
);
- getoptprinter(options, NUMBER_OF_SECRETS);
+ getoptprinter(options[NUMBER_OF_SECRETS..$]);
puts("\nFor a list of values, for example a list of platforms, type '-a help'");
exit(0);
return 0;
@@ -147,68 +109,16 @@
}
extern (C)
-void crash_handler(adbg_exception_t *ex) {
- scope(exit) exit(ex.oscode);
-
- adbg_process_t *self = adbg_self_process();
-
- puts(
-r"
- _ _ _ _ _ _ _ _ _ _ _ _ _ _
- _|_|_|_| |_|_|_|_ _|_|_|_ _|_|_|_| |_| |_| |_|
-|_| |_|_ _|_| |_|_ _|_| |_|_ _ |_|_ _|_| |_|
-|_| |_|_|_|_ |_|_|_|_| |_|_|_ |_|_|_|_| |_|
-|_|_ _ _ |_| |_| |_| |_| _ _ _|_| |_| |_| _
- |_|_|_| |_| |_| |_| |_| |_|_|_| |_| |_| |_|
-"
- );
-
- printf(
- "Exception : %s\n"~
- "PID : %d\n",
- adbg_exception_name(ex), cast(int)self.pid); // casting is temp
-
- // Fault address & disasm if available
- if (ex.faultz) {
- printf("Address : %#zx\n", ex.faultz);
-
- adbg_opcode_t op = void;
- adbg_disassembler_t *dis = adbg_dis_open(adbg_machine_default());
- printf("Instruction:");
- if (dis && adbg_dis_process_once(dis, &op, self, ex.fault_address) == 0) {
- // Print address
- // Print machine bytes
- for (size_t bi; bi < op.size; ++bi)
- printf(" %02x", op.machine[bi]);
- //
- printf(" (%s", op.mnemonic);
- if (op.operands)
- printf(" %s", op.operands);
- //
- puts(")");
- } else {
- printf(" Disassembly unavailable (%s)\n", adbg_error_msg());
- }
- }
-}
-
-extern (C)
int main(int argc, const(char)** argv) {
// Set crash handle, and ignore on error
// Could do a warning, but it might be a little confusing
- adbg_self_set_crashhandler(&crash_handler);
+ adbg_self_set_crashhandler(&oopsie);
- if (getopt(argc, argv, options) < 0) {
- puts(getopterrstring());
+ int cnt = getopt(argc, argv, options);
+ if (cnt < 0) {
+ puts(getopterror());
return EXIT_FAILURE;
}
- if (getoptremcnt() < 1) {
- puts("error: No file specified");
- return EXIT_FAILURE;
- }
-
- const(char)** args = getoptrem();
-
- return shell_loop(*args);
+ return shellinit(cnt, getoptleftovers());
}
diff --git a/debugger/shell.d b/debugger/shell.d
index 033e4e2..b859c02 100644
--- a/debugger/shell.d
+++ b/debugger/shell.d
@@ -31,9 +31,10 @@
pauseRequired = -5,
alreadyLoaded = -6,
missingOption = -7,
- unformat = -8,
- invalidCount = -9,
- unattached = -10,
+ missingArgument = -8,
+ unformat = -9,
+ invalidCount = -10,
+ unattached = -11,
scanMissingType = -20,
scanMissingValue = -21,
@@ -63,6 +64,8 @@
return "File already loaded.";
case missingOption:
return "Missing option for command.";
+ case missingArgument:
+ return "Missing argument.";
case unformat:
return "Input is not a number.";
case invalidCount:
@@ -88,27 +91,23 @@
}
}
-/*void registerError(void function(ref command2_help_t help)) {
-
-}
-void registerHelp(void function(ref command2_help_t help)) {
-
-}*/
-
-int shell_loop(const(char)* entry) {
+//TODO: Turn into character array (like gdb --args)
+int shellinit(int argc, const(char)** argv) {
int ecode = void;
if (loginit(null))
return 1337;
- // Load or attach process if CLI specified it
- if (entry) {
- ecode = shell_proc_spawn(entry, opt_file_argv);
+ // Start process if specified
+ if (argc > 0 && argv) {
+ ecode = argc > 1 ?
+ shell_proc_spawn(*argv, argc - 1, argv + 1) :
+ shell_proc_spawn(*argv, 0, null);
if (ecode) {
printf("Error: %s\n", adbg_error_msg());
return ecode;
}
- } else if (opt_pid) {
+ } else if (opt_pid) { // Or attach to process if specified
ecode = shell_proc_attach(opt_pid);
if (ecode) {
printf("Error: %s\n", adbg_error_msg());
@@ -118,7 +117,7 @@
coninit();
-LINPUT:
+Lcommand:
printf("(adbg) ");
// .ptr is temporary because a slice with a length of 0
@@ -132,7 +131,7 @@
ecode = shell_exec(line);
if (ecode)
logerror(shell_error_string(ecode));
- goto LINPUT;
+ goto Lcommand;
}
int shell_exec(const(char) *command) {
@@ -158,11 +157,14 @@
private:
__gshared:
-const(char)* last_file;
adbg_process_t *process;
adbg_disassembler_t *dis;
adbg_registers_t *registers;
+const(char)* last_spawn_exec;
+int last_spawn_argc;
+const(char)** last_spawn_argv;
+
// NOTE: BetterC stderr bindings on Windows are broken
// And don't allow re-opening the streams, so screw it
@@ -533,26 +535,31 @@
return null;
}
-int shell_proc_spawn(const(char) *exec, const(char) **argv) {
+int shell_proc_spawn(const(char) *exec, int argc, const(char) **argv) {
// Save for restart
- last_file = exec;
- opt_file_argv = argv;
+ last_spawn_exec = exec;
+ last_spawn_argc = argc;
+ last_spawn_argv = argv;
// Spawn process
process = adbg_debugger_spawn(exec,
- AdbgSpawnOpt.argv, argv,
+ AdbgSpawnOpt.argv, argc, argv,
0);
- if (process == null) {
+ if (process == null)
return ShellError.alicedbg;
- }
- puts("Process created.");
+ printf("Process '%s' created", exec);
+ if (argc && argv) {
+ printf(" with %d arguments:", argc);
+ for (int i; i < argc; ++i)
+ printf(" '%s'", argv[i]);
+ }
+ putchar('\n');
// Open disassembler for process machine type
dis = adbg_dis_open(adbg_process_get_machine(process));
- if (dis == null) {
- logwarn("Disassembler not available (%s).", adbg_error_msg());
- }
+ if (dis == null)
+ logwarn("Disassembler not available (%s)", adbg_error_msg());
return 0;
}
@@ -769,17 +776,18 @@
}
int command_spawn(int argc, const(char) **argv) {
- if (argc < 2) {
- return ShellError.invalidParameter;
- }
+ if (argc < 2)
+ return ShellError.missingArgument;
- return shell_proc_spawn(argv[1], argc > 2 ? argv + 2: null);
+ if (argc < 3)
+ return shell_proc_spawn(argv[1], 0, null);
+
+ return shell_proc_spawn(argv[1], argc - 2, argv + 2);
}
int command_attach(int argc, const(char) **argv) {
- if (argc < 2) {
+ if (argc < 2)
return ShellError.invalidParameter;
- }
return shell_proc_attach(atoi(argv[1]));
}
@@ -803,7 +811,7 @@
adbg_debugger_terminate(process);
// Spawn, shell still messages status
- e = shell_proc_spawn(last_file, opt_file_argv);
+ e = shell_proc_spawn(last_spawn_exec, last_spawn_argc, last_spawn_argv);
break;
case attached:
// Detach first, ignore on error (e.g., already detached)
diff --git a/dumper/dumper.d b/dumper/dumper.d
index 260ded6..7d589f7 100644
--- a/dumper/dumper.d
+++ b/dumper/dumper.d
@@ -128,8 +128,8 @@
if (setting_extract_any() == 0) {
print_string("filename", path);
print_u64("filesize", o.file_size);
- print_string("format", adbg_object_name(o));
- print_string("short_name", adbg_object_short_name(o));
+ print_string("format", adbg_object_format_name(o));
+ print_string("short_name", adbg_object_format_shortname(o));
}
final switch (o.format) with (AdbgObject) {
case mz: return dump_mz(o);
@@ -150,7 +150,8 @@
}
// Otherwise, make a basic summary
- printf("%s: %s\n", path, adbg_object_name(o));
+ printf("%s: %s (%s)\n", path,
+ adbg_object_format_name(o), adbg_object_format_shortname(o));
return 0;
}
diff --git a/dumper/main.d b/dumper/main.d
index 1f1e674..e057cd0 100644
--- a/dumper/main.d
+++ b/dumper/main.d
@@ -16,6 +16,7 @@
import core.stdc.stdlib : EXIT_FAILURE;
import core.stdc.stdio;
import dumper;
+import common.error;
import common.cli;
import common.utils : unformat64;
@@ -29,6 +30,8 @@
//TODO: --type-only: Returns short-name only for identification purposes
//TODO: --name: Extract by section, import, export name (will replace --section?)
immutable option_t[] options = [
+ // secrets
+ option_t(0, "woof", null, &cliopt_woof),
// common options
option_arch,
option_syntax,
@@ -53,12 +56,13 @@
option_t(0, "extract-to", "Setting: Output selected portion to file", &cliopt_extract_to),
option_t(0, "hexdump", "Setting: Output selected portion to stdout as hexdump", &cliopt_hexdump),
// pages
- option_t('h', "help", "Show this help screen and exit", &cli_help),
+ option_t('h', "help", "Show this help screen and exit", &cliopt_help),
option_version,
option_build_info,
option_ver,
option_license,
];
+enum NUMBER_OF_SECRETS = 1;
//
// Selections
@@ -145,7 +149,7 @@
// ANCHOR --help
//
-int cli_help() {
+int cliopt_help() {
puts(
"alicedump: Binary object dumper.\n"~
"\n"~
@@ -159,72 +163,43 @@
"\n"~
"OPTIONS"
);
- getoptprinter(options);
+ getoptprinter(options[NUMBER_OF_SECRETS..$]);
exit(0);
return 0;
}
-extern (C)
-void crash_handler(adbg_exception_t *ex) {
- adbg_process_t *self = adbg_self_process();
-
+int cliopt_woof() {
puts(
r"
- _ _ _ _ _ _ _ _ _ _ _ _ _ _
- _|_|_|_| |_|_|_|_ _|_|_|_ _|_|_|_| |_| |_| |_|
-|_| |_|_ _|_| |_|_ _|_| |_|_ _ |_|_ _|_| |_|
-|_| |_|_|_|_ |_|_|_|_| |_|_|_ |_|_|_|_| |_|
-|_|_ _ _ |_| |_| |_| |_| _ _ _|_| |_| |_| _
- |_|_|_| |_| |_| |_| |_| |_|_|_| |_| |_| |_|
++---------------------+ ,
+| Are you SystemReady | .__,-/|
+| compliant yet? Woof | \_ ` \
++---------------------+ `====
+ { \
+ \ / \
+ /// `\ /
+ //_\ /`
"
);
-
- printf(
- "Exception : %s\n"~
- "PID : %d\n",
- adbg_exception_name(ex), cast(int)self.pid); // casting is temp
-
- // Fault address & disasm if available
- if (ex.faultz) {
- printf("Address : %#zx\n", ex.faultz);
-
- adbg_opcode_t op = void;
- adbg_disassembler_t *dis = adbg_dis_open(adbg_machine_default());
- if (dis && adbg_dis_process_once(dis, &op, self, ex.fault_address) == 0) {
- // Print address
- printf("Instruction:");
- // Print machine bytes
- for (size_t bi; bi < op.size; ++bi)
- printf(" %02x", op.machine[bi]);
- //
- printf(" (%s", op.mnemonic);
- if (op.operands)
- printf(" %s", op.operands);
- //
- puts(")");
- } else {
- printf(" Unavailable (%s)\n", adbg_error_msg());
- }
- }
-
- exit(ex.oscode);
+ exit(0);
+ return 0;
}
extern (C)
int main(int argc, const(char)** argv) {
// Set crash handle, and ignore on error
// Could do a warning, but it might be a little confusing
- adbg_self_set_crashhandler(&crash_handler);
+ adbg_self_set_crashhandler(&oopsie);
- if (getopt(argc, argv, options) < 0) {
- puts(getopterrstring());
+ int e = getopt(argc, argv, options);
+ if (e < 0) {
+ puts(getopterror());
return EXIT_FAILURE;
}
-
- if (getoptremcnt() < 1) {
+ if (e == 0) {
puts("error: No file specified");
return EXIT_FAILURE;
}
- return dump(*getoptrem()); // First argument as file
+ return dump(*getoptleftovers()); // First argument as file
}
diff --git a/src/adbg/self.d b/src/adbg/self.d
index 1bbf6dd..a2c7625 100644
--- a/src/adbg/self.d
+++ b/src/adbg/self.d
@@ -132,7 +132,7 @@
/// Note: Not respected by some exceptions, like buffer overruns.
/// Params: func = User handler function.
/// Returns: Zero on success; Non-zero on error.
-int adbg_self_set_crashhandler(void function(adbg_exception_t*) func) {
+int adbg_self_set_crashhandler(void function(adbg_process_t*, adbg_exception_t*) func) {
if (func == null)
return adbg_oops(AdbgError.invalidArgument);
@@ -161,7 +161,7 @@
private:
-__gshared void function(adbg_exception_t*) __ufunction;
+__gshared void function(adbg_process_t*, adbg_exception_t*) __ufunction;
version (Windows)
extern (Windows)
@@ -182,7 +182,7 @@
}
// Call user function
- __ufunction(&ex);
+ __ufunction(adbg_self_process(), &ex);
return EXCEPTION_EXECUTE_HANDLER;
}
@@ -210,7 +210,7 @@
//adbg_registers_t regs = void;
//adbg_registers_config(®s, adbg_machine_default());
- __ufunction(&ex);
+ __ufunction(adbg_self_process(), &ex);
/+adbg_ctx_init(&mexception.registers);
version (X86) {