diff --git a/common/cli.d b/common/cli.d
index 59dcd90..13955c3 100644
--- a/common/cli.d
+++ b/common/cli.d
@@ -17,8 +17,10 @@
import core.stdc.string;
import core.stdc.errno;
+/// Copyright string
enum COPYRIGHT = "Copyright (c) 2019-2024 dd86k
";
+/// License string
immutable(char) *page_license =
COPYRIGHT~`
All rights reserved.
@@ -48,8 +50,8 @@
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.`;
-debug enum FULL_VERSION = ADBG_VERSION~"+"~__BUILDTYPE__;
-else enum FULL_VERSION = ADBG_VERSION;
+debug enum FULL_VERSION = ADBG_VERSION~"+"~__BUILDTYPE__; /// Full version string
+else enum FULL_VERSION = ADBG_VERSION; /// Ditto
/// Turns a __VERSION__ number into a string constant
template DSTRVER(uint ver) {
@@ -76,7 +78,9 @@
//ARG_LARGENUMBER, // %lli
}
+/// Represents one command-line option switch
struct option_t { align(1):
+ /// Make an option without arguments
this (char oshort, string olong, string desc, int function() ufunc) {
shortname = oshort;
longname = olong;
@@ -84,6 +88,7 @@
argtype = ARG_NONE;
f = ufunc;
}
+ /// Make an option with string argument
this (char oshort, string olong, string desc, int function(const(char)*) ufunc) {
shortname = oshort;
longname = olong;
@@ -96,18 +101,22 @@
char shortname; /// Short switch name
ubyte argtype; /// Argument type
union {
- int function() f;
- int function(const(char)*) fa;
+ int function() f; /// User callback
+ int function(const(char)*) fa; /// Ditto
}
}
-//NOTE: Can't make a template and pass a function pointer
-
+/// Default option for --machine
enum option_arch = option_t('m', "machine", "Select machine for disassembler (default=platform)", &cli_march);
+/// Default option for --syntax
enum option_syntax = option_t('s', "syntax", "Select syntax for disassembler (default=platform)", &cli_syntax);
+/// Default option for --version
enum option_version = option_t(0, "version", "Show the version screen and exit", &cli_version);
+/// Default option for --build-info
enum option_build_info = option_t(0, "build-info", "Show the build and debug information and exit", &cli_build_info);
+/// Default option for --ver
enum option_ver = option_t(0, "ver", "Show only the version string and exit", &cli_ver);
+/// Default option for --license
enum option_license = option_t(0, "license", "Show the license page and exit", &cli_license);
//TODO: Return error
@@ -115,6 +124,7 @@
// 0 -> no args left
// >0 -> args left
//TODO: Make option functions return <0=error >0=ok, consumed arg(s)
+/// Interpret options
int getopt(int argc, const(char) **argv, immutable(option_t)[] options) {
const(char) *arg = void;
const(char) *val = void;
@@ -208,6 +218,7 @@
unittest {
}
+/// Print options
void getoptprinter(immutable(option_t)[] options, int skip = 0) {
static immutable int padding = -17;
foreach (ref option; options[skip..$]) { with (option)
@@ -232,9 +243,11 @@
}
getoptextras[getoptextrascnt++] = extra;
}
+/// Get remaining arguments
const(char)** getoptrem() {
return getoptextras;
}
+/// Get remaining argument count
int getoptremcnt() {
return getoptextrascnt;
}
@@ -244,6 +257,7 @@
private enum GETOPTBFSZ = 2048;
private __gshared char* getopterrbuf;
+/// Get getopt error message
const(char)* getopterrstring() {
return getopterrbuf ? getopterrbuf : "No errors occured";
}
@@ -284,12 +298,13 @@
"main: missing argument for -%c\n", opt);
}
-
+/// Is user asking for help with this option?
bool wantsHelp(const(char) *query) {
- return (query[0] == 'h' && query[1] == 0) ||
- strcmp(query, "help") == 0;
+ return strcmp(query, "help") == 0;
}
+private:
+
//
// --march
//
diff --git a/debugger/shell.d b/debugger/shell.d
index 3a11393..033e4e2 100644
--- a/debugger/shell.d
+++ b/debugger/shell.d
@@ -624,7 +624,12 @@
}
}
-void shell_event_exception(adbg_exception_t *ex) {
+void shell_event_exception(adbg_process_t *proc, int event, void* evdata) {
+ if (event != AdbgEvent.exception)
+ return;
+
+ adbg_exception_t *ex = cast(adbg_exception_t*)evdata;
+
printf("* Process %d (thread %d) stopped\n"~
" Reason : %s ("~ADBG_OS_ERROR_FORMAT~")\n",
ex.pid, ex.tid,
diff --git a/dumper/format/elf.d b/dumper/format/elf.d
index 11ef97d..ad6d776 100644
--- a/dumper/format/elf.d
+++ b/dumper/format/elf.d
@@ -5,7 +5,7 @@
/// License: BSD-3-Clause-Clear
module format.elf;
-import adbg.utils.bit : adbg_align4up;
+import adbg.utils.bit : adbg_alignup;
import adbg.disassembler;
import adbg.object.server;
import adbg.machines;
@@ -241,7 +241,7 @@
print_u32("n_descsz", nhdr.n_descsz);
print_u32("n_type", nhdr.n_type, adbg_object_elf_nt_type_string(nhdr.n_type));
- size_t nnamesz = adbg_align4up(nhdr.n_namesz);
+ size_t nnamesz = adbg_alignup(nhdr.n_namesz, ulong.sizeof);
void *data = note + Elf64_Nhdr.sizeof + nnamesz;
// NOTE: Only for x86-64, for now
@@ -388,7 +388,7 @@
ulong nsize =
Elf64_Nhdr.sizeof +
nnamesz +
- adbg_align4up(nhdr.n_descsz);
+ adbg_alignup(nhdr.n_descsz, uint.sizeof);
noffset += nsize;
nleft -= nsize;
diff --git a/examples/simple.d b/examples/simple.d
index 0f997ca..1c2d53e 100644
--- a/examples/simple.d
+++ b/examples/simple.d
@@ -11,12 +11,58 @@
import adbg;
extern (C):
+__gshared:
+private: // Shuts up dscanner
+
+adbg_disassembler_t *dis;
+
+void die(int code = 0, const(char) *reason = null) {
+ printf("error: %s\n", reason ? reason : adbg_error_msg);
+ if (code == 0) code = adbg_errno;
+ exit(code);
+}
+
+int choice(const(char) *msg) {
+ printf("\n%s: ", msg);
+LINPUT: int c = getchar;
+ if (isprint(c)) return c;
+ goto LINPUT;
+}
+
+void loop_handler(adbg_process_t *proc, int event, void *evdata) {
+ if (event != AdbgEvent.exception)
+ return;
+
+ adbg_exception_t *ex = cast(adbg_exception_t*)evdata;
+ printf(
+ "\n----------------------------------------\n"~
+ "* EXCEPTION ("~ADBG_OS_ERROR_FORMAT~"): %s\n"~
+ "* PID=%u TID=%u\n"~
+ "* FAULT=%8llx",
+ ex.oscode, adbg_exception_name(ex),
+ ex.pid, ex.tid,
+ ex.fault_address
+ );
+
+ // Print disassembly if available
+ if (dis && ex.faultz) {
+ adbg_opcode_t op = void;
+ if (adbg_dis_process_once(dis, &op, proc, ex.fault_address)) {
+ printf(" (error:%s)\n", adbg_error_msg);
+ return;
+ }
+ if (op.operands)
+ printf(" (%s %s)\n", op.mnemonic, op.operands);
+ else
+ printf(" (%s)\n", op.mnemonic);
+ }
+}
int main(int argc, const(char) **argv) {
if (argc < 2)
die(1, "Missing path to executable");
- process = adbg_debugger_spawn(argv[1], 0);
+ adbg_process_t *process = adbg_debugger_spawn(argv[1], 0);
if (process == null)
die;
@@ -50,47 +96,4 @@
adbg_debugger_wait(process, &loop_handler);
goto LOOP;
-}
-
-private: // Shuts up dscanner
-
-void die(int code = 0, const(char) *reason = null) {
- printf("error: %s\n", reason ? reason : adbg_error_msg);
- if (code == 0) code = adbg_errno;
- exit(code);
-}
-
-int choice(const(char) *msg) {
- printf("\n%s: ", msg);
-LINPUT: int c = getchar;
- if (isprint(c)) return c;
- goto LINPUT;
-}
-
-__gshared adbg_process_t *process;
-__gshared adbg_disassembler_t *dis;
-
-void loop_handler(adbg_exception_t *ex) {
- printf(
- "\n----------------------------------------\n"~
- "* EXCEPTION ("~ADBG_OS_ERROR_FORMAT~"): %s\n"~
- "* PID=%u TID=%u\n"~
- "* FAULT=%8llx",
- ex.oscode, adbg_exception_name(ex),
- ex.pid, ex.tid,
- ex.fault_address
- );
-
- // Print disassembly if available
- if (dis && ex.faultz) {
- adbg_opcode_t op = void;
- if (adbg_dis_process_once(dis, &op, process, ex.fault_address)) {
- printf(" (error:%s)\n", adbg_error_msg);
- return;
- }
- if (op.operands)
- printf(" (%s %s)\n", op.mnemonic, op.operands);
- else
- printf(" (%s)\n", op.mnemonic);
- }
}
\ No newline at end of file
diff --git a/src/adbg/debugger/process.d b/src/adbg/debugger/process.d
index e20982c..bcb08ec 100644
--- a/src/adbg/debugger/process.d
+++ b/src/adbg/debugger/process.d
@@ -51,6 +51,11 @@
extern (C):
+/// Debugging events
+enum AdbgEvent {
+ exception,
+}
+
/// Process status
enum AdbgProcStatus : ubyte {
unknown, /// Process status is not known.
@@ -58,29 +63,8 @@
standby, /// Process is loaded and waiting to run.
running, /// Process is running.
paused, /// Process is paused due to an exception or by the debugger.
- idle = unloaded, /// Old v1 alias for unloaded.
- ready = standby, /// Old v1 alias for standby.
}
-/// Debugger event
-/+public
-enum AdbgEvent {
- exception,
- processCreated,
- processExit,
- threadCreated,
- threadExit,
-}
-
-/// Debugger event structure
-public
-struct adbg_debugger_event_t {
- AdbgEvent event;
- public union {
- exception_t exception;
- }
-}+/
-
//TODO: Rename to AdbgDebuggerRelation
/// Process creation source.
enum AdbgCreation : ubyte {
@@ -603,7 +587,8 @@
/// tracee = Tracee instance.
/// userfunc = User function callback.
/// Returns: Error code.
-int adbg_debugger_wait(adbg_process_t *tracee, void function(adbg_exception_t*) userfunc) {
+int adbg_debugger_wait(adbg_process_t *tracee,
+ void function(adbg_process_t*, int, void*) userfunc) {
if (tracee == null || userfunc == null)
return adbg_oops(AdbgError.invalidArgument);
if (tracee.creation == AdbgCreation.unloaded)
@@ -730,7 +715,7 @@
adbg_exception_translate(&exception, &tracee.pid, &stopsig);
}
- userfunc(&exception);
+ userfunc(tracee, AdbgEvent.exception, &exception);
return 0;
L_UNLOADED:
@@ -785,12 +770,12 @@
version (Windows) {
if (ContinueDebugEvent(tracee.pid, tracee.tid, DBG_CONTINUE) == FALSE) {
- tracee.status = AdbgProcStatus.idle;
+ tracee.status = AdbgProcStatus.unknown;
return adbg_oops(AdbgError.os);
}
} else {
if (ptrace(PT_CONT, tracee.pid, null, null) < 0) {
- tracee.status = AdbgProcStatus.idle;
+ tracee.status = AdbgProcStatus.unknown;
return adbg_oops(AdbgError.os);
}
}