<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Jun 20, 2018, 3:35 PM Alistair Popple <<a href="mailto:alistair@popple.id.au">alistair@popple.id.au</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This switches all commands except the htm command to use the new command/option<br>
parsing code. For the moment we leave the usage help and generic targeting flag<br>
processing alone, but future changes should allow this to also use the common<br>
parsing code.<br>
<br>
Signed-off-by: Alistair Popple <<a href="mailto:alistair@popple.id.au" target="_blank" rel="noreferrer">alistair@popple.id.au</a>><br>
---<br>
 Makefile.am  |   1 +<br>
 src/cfam.c   |  55 ++++++--------------<br>
 src/cfam.h   |  18 -------<br>
 src/main.c   | 125 ++++++++++++++++++++++++++++-----------------<br>
 src/mem.c    | 124 ++++++++------------------------------------<br>
 src/mem.h    |  20 --------<br>
 src/reg.c    | 164 +++++++++++++++--------------------------------------------<br>
 src/reg.h    |  20 --------<br>
 src/ring.c   |  32 ++----------<br>
 src/ring.h   |  17 -------<br>
 src/scom.c   |  54 +++++---------------<br>
 src/scom.h   |  18 -------<br>
 src/thread.c |  87 ++++++++++++++++++++++---------<br>
 src/thread.h |  23 ---------<br>
 14 files changed, 237 insertions(+), 521 deletions(-)<br>
 delete mode 100644 src/cfam.h<br>
 delete mode 100644 src/mem.h<br>
 delete mode 100644 src/reg.h<br>
 delete mode 100644 src/ring.h<br>
 delete mode 100644 src/scom.h<br>
 delete mode 100644 src/thread.h<br>
<br>
diff --git a/Makefile.am b/Makefile.am<br>
index 23f2080..4e0dce2 100644<br>
--- a/Makefile.am<br>
+++ b/Makefile.am<br>
@@ -39,6 +39,7 @@ pdbg_SOURCES = \<br>
        src/ring.c \<br>
        src/htm.c \<br>
        src/progress.c \<br>
+       src/parsers.c \<br>
        src/optcmd.c \<br>
        src/options_@ARCH@.c<br>
<br>
diff --git a/src/cfam.c b/src/cfam.c<br>
index 269123e..6dab388 100644<br>
--- a/src/cfam.c<br>
+++ b/src/cfam.c<br>
@@ -20,8 +20,9 @@<br>
 #include <inttypes.h><br>
<br>
 #include "main.h"<br>
+#include "optcmd.h"<br>
<br>
-static int getcfam(struct pdbg_target *target, uint32_t index, uint64_t *addr, uint64_t *unused)<br>
+static int _getcfam(struct pdbg_target *target, uint32_t index, uint64_t *addr, uint64_t *unused)<br>
 {<br>
        uint32_t value;<br>
<br>
@@ -33,7 +34,15 @@ static int getcfam(struct pdbg_target *target, uint32_t index, uint64_t *addr, u<br>
        return 1;<br>
 }<br>
<br>
-static int putcfam(struct pdbg_target *target, uint32_t index, uint64_t *addr, uint64_t *data)<br>
+static int getcfam(uint32_t addr)<br>
+{<br>
+       uint64_t addr64 = addr;<br>
+<br>
+       return for_each_target("fsi", _getcfam, &addr64, NULL);<br>
+}<br>
+OPTCMD_DEFINE_CMD_WITH_ARGS(getcfam, getcfam, (ADDRESS32));<br>
+<br>
+static int _putcfam(struct pdbg_target *target, uint32_t index, uint64_t *addr, uint64_t *data)<br>
 {<br>
        if (fsi_write(target, *addr, *data))<br>
                return 0;<br>
@@ -41,44 +50,10 @@ static int putcfam(struct pdbg_target *target, uint32_t index, uint64_t *addr, u<br>
        return 1;<br>
 }<br>
<br>
-int handle_cfams(int optind, int argc, char *argv[])<br>
+static int putcfam(uint32_t addr, uint32_t data)<br>
 {<br>
-       uint64_t addr;<br>
-       char *endptr;<br>
-<br>
-       if (optind + 1 >= argc) {<br>
-               printf("%s: command '%s' requires an address\n", argv[0], argv[optind]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       errno = 0;<br>
-       addr = strtoull(argv[optind + 1], &endptr, 0);<br>
-       if (errno || *endptr != '\0') {<br>
-               printf("%s: command '%s' couldn't parse address '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1]);<br>
-               return -1;<br>
-       }<br>
+       uint64_t addr64 = addr, data64 = data;<br>
<br>
-       if (strcmp(argv[optind], "putcfam") == 0) {<br>
-               uint64_t data;<br>
-<br>
-               if (optind + 2 >= argc) {<br>
-                       printf("%s: command '%s' requires data\n", argv[0], argv[optind]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               errno = 0;<br>
-               data = strtoull(argv[optind + 2], &endptr, 0);<br>
-               if (errno || *endptr != '\0') {<br>
-                       printf("%s: command '%s' couldn't parse data '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               return for_each_target("fsi", putcfam, &addr, &data);<br>
-       }<br>
-<br>
-       return for_each_target("fsi", getcfam, &addr, NULL);<br>
+       return for_each_target("fsi", _putcfam, &addr64, &data64);<br>
 }<br>
-<br>
-<br>
+OPTCMD_DEFINE_CMD_WITH_ARGS(putcfam, putcfam, (ADDRESS32, DATA32));<br>
diff --git a/src/cfam.h b/src/cfam.h<br>
deleted file mode 100644<br>
index 997ed3d..0000000<br>
--- a/src/cfam.h<br>
+++ /dev/null<br>
@@ -1,18 +0,0 @@<br>
-/* Copyright 2017 IBM Corp.<br>
- *<br>
- * Licensed under the Apache License, Version 2.0 (the "License");<br>
- * you may not use this file except in compliance with the License.<br>
- * You may obtain a copy of the License at<br>
- *<br>
- *     <a href="http://www.apache.org/licenses/LICENSE-2.0" rel="noreferrer noreferrer" target="_blank">http://www.apache.org/licenses/LICENSE-2.0</a><br>
- *<br>
- * Unless required by applicable law or agreed to in writing, software<br>
- * distributed under the License is distributed on an "AS IS" BASIS,<br>
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or<br>
- * implied.<br>
- * See the License for the specific language governing permissions and<br>
- * limitations under the License.<br>
- */<br>
-#include <inttypes.h><br>
-<br>
-int handle_cfams(int optind, int argc, char *argv[]);<br>
diff --git a/src/main.c b/src/main.c<br>
index cf9a3b2..1cfaca7 100644<br>
--- a/src/main.c<br>
+++ b/src/main.c<br>
@@ -34,14 +34,9 @@<br>
 #include <target.h><br>
<br>
 #include "main.h"<br>
-#include "cfam.h"<br>
-#include "scom.h"<br>
-#include "reg.h"<br>
-#include "ring.h"<br>
-#include "mem.h"<br>
-#include "thread.h"<br>
 #include "htm.h"<br>
 #include "options.h"<br>
+#include "optcmd.h"<br>
<br>
 #define PR_ERROR(x, args...) \<br>
        pdbg_log(PDBG_ERROR, x, ##args)<br>
@@ -77,44 +72,64 @@ static int **processorsel[MAX_PROCESSORS];<br>
 static int *chipsel[MAX_PROCESSORS][MAX_CHIPS];<br>
 static int threadsel[MAX_PROCESSORS][MAX_CHIPS][MAX_THREADS];<br>
<br>
-static int handle_probe(int optind, int argc, char *argv[]);<br>
-static int handle_release(int optind, int argc, char *argv[]);<br>
+static int probe(void);<br>
+static int release(void);<br>
+<br>
+/* TODO: We are repeating ourselves here. A little bit more macro magic could<br>
+ * easily fix this but I was hesitant to introduce too much magic all at<br>
+ * once. */<br>
+extern struct optcmd_cmd<br>
+       optcmd_getscom, optcmd_putscom, optcmd_getcfam, optcmd_putcfam,<br>
+       optcmd_getgpr, optcmd_putgpr, optcmd_getspr, optcmd_putspr,<br>
+       optcmd_getnia, optcmd_putnia, optcmd_getmsr, optcmd_putmsr,<br>
+       optcmd_getring, optcmd_start, optcmd_stop, optcmd_step,<br>
+       optcmd_threadstatus, optcmd_sreset, optcmd_regs, optcmd_probe,<br>
+       optcmd_getmem, optcmd_putmem;<br>
+<br>
+static struct optcmd_cmd *cmds[] = {<br>
+       &optcmd_getscom, &optcmd_putscom, &optcmd_getcfam, &optcmd_putcfam,<br>
+       &optcmd_getgpr, &optcmd_putgpr, &optcmd_getspr, &optcmd_putspr,<br>
+       &optcmd_getnia, &optcmd_putnia, &optcmd_getmsr, &optcmd_putmsr,<br>
+       &optcmd_getring, &optcmd_start, &optcmd_stop, &optcmd_step,<br>
+       &optcmd_threadstatus, &optcmd_sreset, &optcmd_regs, &optcmd_probe,<br>
+       &optcmd_getmem, &optcmd_putmem,<br>
+};<br>
<br>
+/* Purely for printing usage text. We could integrate printing argument and flag<br>
+ * help into optcmd if desired. */<br>
 struct action {<br>
        const char *name;<br>
        const char *args;<br>
        const char *desc;<br>
-       int (*fn)(int, int, char **);<br>
 };<br>
<br>
 static struct action actions[] = {<br>
-       { "getgpr",  "<gpr>", "Read General Purpose Register (GPR)", &handle_gpr },<br>
-       { "putgpr",  "<gpr> <value>", "Write General Purpose Register (GPR)", &handle_gpr },<br>
-       { "getnia",  "", "Get Next Instruction Address (NIA)", &handle_nia },<br>
-       { "putnia",  "<value>", "Write Next Instrution Address (NIA)", &handle_nia },<br>
-       { "getspr",  "<spr>", "Get Special Purpose Register (SPR)", &handle_spr },<br>
-       { "putspr",  "<spr> <value>", "Write Special Purpose Register (SPR)", &handle_spr },<br>
-       { "getmsr",  "", "Get Machine State Register (MSR)", &handle_msr },<br>
-       { "putmsr",  "<value>", "Write Machine State Register (MSR)", &handle_msr },<br>
-       { "getring", "<addr> <len>", "Read a ring. Length must be correct", &handle_getring },<br>
-       { "start",   "", "Start thread", &thread_start },<br>
-       { "step",    "<count>", "Set a thread <count> instructions", &thread_step },<br>
-       { "stop",    "", "Stop thread", &thread_stop },<br>
-       { "htm", "core|nest start|stop|status|reset|dump|trace|analyse", "Hardware Trace Macro", &run_htm },<br>
-       { "release", "", "Should be called after pdbg work is finished, to release special wakeups and other resources.", &handle_release},<br>
-       { "probe", "", "", &handle_probe },<br>
-       { "getcfam", "<address>", "Read system cfam", &handle_cfams },<br>
-       { "putcfam", "<address> <value> [<mask>]", "Write system cfam", &handle_cfams },<br>
-       { "getscom", "<address>", "Read system scom", &handle_scoms },<br>
-       { "putscom", "<address> <value> [<mask>]", "Write system scom", &handle_scoms },<br>
-       { "getmem",  "<address> <count>", "Read system memory", &handle_mem },<br>
-       { "putmem",  "<address>", "Write to system memory", &handle_mem },<br>
-       { "threadstatus", "", "Print the status of a thread", &thread_status_print },<br>
-       { "sreset",  "", "Reset", &thread_sreset },<br>
-       { "regs",  "", "State", &thread_state },<br>
+       { "getgpr",  "<gpr>", "Read General Purpose Register (GPR)" },<br>
+       { "putgpr",  "<gpr> <value>", "Write General Purpose Register (GPR)" },<br>
+       { "getnia",  "", "Get Next Instruction Address (NIA)" },<br>
+       { "putnia",  "<value>", "Write Next Instrution Address (NIA)" },<br>
+       { "getspr",  "<spr>", "Get Special Purpose Register (SPR)" },<br>
+       { "putspr",  "<spr> <value>", "Write Special Purpose Register (SPR)" },<br>
+       { "getmsr",  "", "Get Machine State Register (MSR)" },<br>
+       { "putmsr",  "<value>", "Write Machine State Register (MSR)" },<br>
+       { "getring", "<addr> <len>", "Read a ring. Length must be correct" },<br>
+       { "start",   "", "Start thread" },<br>
+       { "step",    "<count>", "Set a thread <count> instructions" },<br>
+       { "stop",    "", "Stop thread" },<br>
+       { "htm", "core|nest start|stop|status|reset|dump|trace|analyse", "Hardware Trace Macro" },<br>
+       { "release", "", "Should be called after pdbg work is finished" },<br>
+       { "probe", "", "" },<br>
+       { "getcfam", "<address>", "Read system cfam" },<br>
+       { "putcfam", "<address> <value> [<mask>]", "Write system cfam" },<br>
+       { "getscom", "<address>", "Read system scom" },<br>
+       { "putscom", "<address> <value> [<mask>]", "Write system scom" },<br>
+       { "getmem",  "<address> <count>", "Read system memory" },<br>
+       { "putmem",  "<address>", "Write to system memory" },<br>
+       { "threadstatus", "", "Print the status of a thread" },<br>
+       { "sreset",  "", "Reset" },<br>
+       { "regs",  "", "State" },<br>
 };<br>
<br>
-<br>
 static void print_usage(char *pname)<br>
 {<br>
        int i;<br>
@@ -600,7 +615,7 @@ static void release_target(struct pdbg_target *target)<br>
        pdbg_target_release(target);<br>
 }<br>
<br>
-static void do_release(void)<br>
+static int release(void)<br>
 {<br>
        struct pdbg_target_class *target_class;<br>
<br>
@@ -610,7 +625,10 @@ static void do_release(void)<br>
                pdbg_for_each_class_target(target_class->name, target)<br>
                        release_target(target);<br>
        }<br>
+<br>
+       return 0;<br>
 }<br>
+OPTCMD_DEFINE_CMD(release, release);<br>
<br>
 void print_target(struct pdbg_target *target, int level)<br>
 {<br>
@@ -652,7 +670,7 @@ void print_target(struct pdbg_target *target, int level)<br>
        }<br>
 }<br>
<br>
-static int handle_probe(int optind, int argc, char *argv[])<br>
+static int probe(void)<br>
 {<br>
        struct pdbg_target *target;<br>
<br>
@@ -664,25 +682,21 @@ static int handle_probe(int optind, int argc, char *argv[])<br>
<br>
        return 1;<br>
 }<br>
+OPTCMD_DEFINE_CMD(probe, probe);<br>
<br>
 /*<br>
  * Release handler.<br>
  */<br>
 static void atexit_release(void)<br>
 {<br>
-       do_release();<br>
-}<br>
-<br>
-static int handle_release(int optind, int argc, char *argv[])<br>
-{<br>
-       do_release();<br>
-<br>
-       return 1;<br>
+       release();<br>
 }<br>
<br>
 int main(int argc, char *argv[])<br>
 {<br>
        int i, rc = 0;<br>
+       void **args, **flags;<br>
+       optcmd_cmd_t *cmd;<br>
<br>
        backend = default_backend();<br>
        device_node = default_target(backend);<br>
@@ -714,13 +728,28 @@ int main(int argc, char *argv[])<br>
<br>
        atexit(atexit_release);<br>
<br>
-       for (i = 0; i < ARRAY_SIZE(actions); i++) {<br>
-               if (strcmp(argv[optind], actions[i].name) == 0) {<br>
-                       rc = actions[i].fn(optind, argc, argv);<br>
-                       goto found_action;<br>
+       for (i = 0; i < ARRAY_SIZE(cmds); i++) {<br>
+               if (!strcmp(argv[optind], cmds[i]->cmd)) {<br>
+                       /* Found our command */<br>
+                       cmd = optcmd_parse(cmds[i], (const char **) &argv[optind + 1],<br>
+                                          argc - (optind + 1), &args, &flags);<br>
+                       if (cmd) {<br>
+                               rc = cmd(args, flags);<br>
+                               goto found_action;<br>
+                       } else {<br>
+                               /* Error parsing arguments so exit return directly */<br>
+                               return 1;<br>
+                       }<br>
                }<br>
        }<br>
<br>
+       /* Process subcommands. Currently only 'htm'.<br>
+        * TODO: Move htm command parsing to optcmd once htm clean-up is complete */<br>
+       if (!strcmp(argv[optind], "htm")) {<br>
+               run_htm(optind, argc, argv);<br>
+               goto found_action;<br>
+       }<br>
+<br>
        PR_ERROR("Unsupported command: %s\n", argv[optind]);<br>
        return 1;<br>
<br>
diff --git a/src/mem.c b/src/mem.c<br>
index e0327d1..29fd21e 100644<br>
--- a/src/mem.c<br>
+++ b/src/mem.c<br>
@@ -20,21 +20,34 @@<br>
 #include <string.h><br>
 #include <unistd.h><br>
 #include <assert.h><br>
+#include <stdbool.h><br>
<br>
 #include <libpdbg.h><br>
<br>
 #include "main.h"<br>
 #include "progress.h"<br>
+#include "optcmd.h"<br>
+#include "parsers.h"<br>
<br>
 #define PR_ERROR(x, args...) \<br>
        pdbg_log(PDBG_ERROR, x, ##args)<br>
<br>
 #define PUTMEM_BUF_SIZE 1024<br>
-static int getmem(uint64_t addr, uint64_t size, bool ci)<br>
+<br>
+struct mem_flags {<br>
+       bool ci;<br>
+};<br>
+<br>
+#define MEM_CI_FLAG ("--ci", ci, parse_flag_noarg, false)<br>
+<br>
+static int getmem(uint64_t addr, uint64_t size, struct mem_flags flags)<br>
 {<br>
        struct pdbg_target *target;<br>
        uint8_t *buf;<br>
        int rc = 0;<br>
+<br>
+       printf("getmem ci %d\n", <a href="http://flags.ci" rel="noreferrer noreferrer" target="_blank">flags.ci</a>);<br>
+<br>
        buf = malloc(size);<br>
        assert(buf);<br>
        pdbg_for_each_class_target("adu", target) {<br>
@@ -43,7 +56,7 @@ static int getmem(uint64_t addr, uint64_t size, bool ci)<br>
<br>
                pdbg_set_progress_tick(progress_tick);<br>
                progress_init();<br>
-               if (!__adu_getmem(target, addr, buf, size, ci)) {<br>
+               if (!__adu_getmem(target, addr, buf, size, <a href="http://flags.ci" rel="noreferrer noreferrer" target="_blank">flags.ci</a>)) {<br>
                        if (write(STDOUT_FILENO, buf, size) < 0)<br>
                                PR_ERROR("Unable to write stdout.\n");<br>
                        else<br>
@@ -58,7 +71,10 @@ static int getmem(uint64_t addr, uint64_t size, bool ci)<br>
        return rc;<br>
<br>
 }<br>
-static int putmem(uint64_t addr, bool ci)<br>
+OPTCMD_DEFINE_CMD_WITH_FLAGS(getmem, getmem, (ADDRESS, DATA),<br>
+                            mem_flags, (MEM_CI_FLAG));<br>
+<br>
+static int putmem(uint64_t addr, struct mem_flags flags)<br>
 {<br>
        uint8_t *buf;<br>
        int read_size, rc = 0;<br>
@@ -76,7 +92,7 @@ static int putmem(uint64_t addr, bool ci)<br>
        progress_init();<br>
        do {<br>
                read_size = read(STDIN_FILENO, buf, PUTMEM_BUF_SIZE);<br>
-               if (__adu_putmem(adu_target, addr, buf, read_size, ci)) {<br>
+               if (__adu_putmem(adu_target, addr, buf, read_size, <a href="http://flags.ci" rel="noreferrer noreferrer" target="_blank">flags.ci</a>)) {<br>
                        rc = 0;<br>
                        printf("Unable to write memory.\n");<br>
                        break;<br>
@@ -89,101 +105,5 @@ static int putmem(uint64_t addr, bool ci)<br>
        free(buf);<br>
        return rc;<br>
 }<br>
-<br>
-static bool is_real_address(struct thread_regs *regs, uint64_t addr)<br>
-{<br>
-       return true;<br>
-       if ((addr & 0xf000000000000000ULL) == 0xc000000000000000ULL)<br>
-               return true;<br>
-       return false;<br>
-}<br>
-<br>
-static int load8(struct pdbg_target *target, uint64_t addr, uint64_t *value)<br>
-{<br>
-       if (adu_getmem(target, addr, (uint8_t *)value, 8)) {<br>
-               PR_ERROR("Unable to read memory address=%016" PRIx64 ".\n", addr);<br>
-               return 0;<br>
-       }<br>
-<br>
-       return 1;<br>
-}<br>
-<br>
-int dump_stack(struct thread_regs *regs)<br>
-{<br>
-       struct pdbg_target *target;<br>
-       uint64_t sp = regs->gprs[1];<br>
-       uint64_t pc;<br>
-<br>
-       pdbg_for_each_class_target("adu", target) {<br>
-               if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED)<br>
-                       continue;<br>
-               break;<br>
-       }<br>
-<br>
-       printf("STACK:\n");<br>
-       if (!target)<br>
-               PR_ERROR("Unable to read memory (no ADU found)\n");<br>
-<br>
-       if (sp && is_real_address(regs, sp)) {<br>
-               if (!load8(target, sp, &sp))<br>
-                       return 1;<br>
-               while (sp && is_real_address(regs, sp)) {<br>
-                       if (!load8(target, sp + 16, &pc))<br>
-                               return 1;<br>
-<br>
-                       printf(" 0x%016" PRIx64 " 0x%16" PRIx64 "\n", sp, pc);<br>
-<br>
-                       if (!load8(target, sp, &sp))<br>
-                               return 1;<br>
-               }<br>
-       }<br>
-<br>
-       return 0;<br>
-}<br>
-<br>
-int handle_mem(int optind, int argc, char *argv[])<br>
-{<br>
-       uint64_t addr;<br>
-       char *endptr;<br>
-       bool ci = false;<br>
-<br>
-       if (optind + 1 >= argc) {<br>
-               printf("%s: command '%s' requires an address\n", argv[0], argv[optind]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       errno = 0;<br>
-<br>
-       if (strcmp(argv[optind +1], "-ci") == 0) {<br>
-               /* Set cache-inhibited flag */<br>
-               ci = true;<br>
-       }<br>
-<br>
-       addr = strtoull(argv[optind + 1 + ci], &endptr, 0);<br>
-       if (errno || *endptr != '\0') {<br>
-               printf("%s: command '%s' couldn't parse address '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1 + ci]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       if (strcmp(argv[optind], "getmem") == 0) {<br>
-               uint64_t size;<br>
-<br>
-               if (optind + 2 + ci >= argc) {<br>
-                       printf("%s: command '%s' requires data\n", argv[0], argv[optind]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               errno = 0;<br>
-               size = strtoull(argv[optind + 2 + ci], &endptr, 0);<br>
-               if (errno || *endptr != '\0') {<br>
-                       printf("%s: command '%s' couldn't parse data '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1 + ci]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               return getmem(addr, size, ci);<br>
-       }<br>
-<br>
-       return putmem(addr, ci);<br>
-}<br>
+OPTCMD_DEFINE_CMD_WITH_FLAGS(putmem, putmem, (ADDRESS),<br>
+                            mem_flags, (MEM_CI_FLAG));<br>
diff --git a/src/mem.h b/src/mem.h<br>
deleted file mode 100644<br>
index 42bdc04..0000000<br>
--- a/src/mem.h<br>
+++ /dev/null<br>
@@ -1,20 +0,0 @@<br>
-/* Copyright 2017 IBM Corp.<br>
- *<br>
- * Licensed under the Apache License, Version 2.0 (the "License");<br>
- * you may not use this file except in compliance with the License.<br>
- * You may obtain a copy of the License at<br>
- *<br>
- *     <a href="http://www.apache.org/licenses/LICENSE-2.0" rel="noreferrer noreferrer" target="_blank">http://www.apache.org/licenses/LICENSE-2.0</a><br>
- *<br>
- * Unless required by applicable law or agreed to in writing, software<br>
- * distributed under the License is distributed on an "AS IS" BASIS,<br>
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or<br>
- * implied.<br>
- * See the License for the specific language governing permissions and<br>
- * limitations under the License.<br>
- */<br>
-#include <inttypes.h><br>
-#include <libpdbg.h><br>
-<br>
-int dump_stack(struct thread_regs *regs);<br>
-int handle_mem(int optind, int argc, char *argv[]);<br>
diff --git a/src/reg.c b/src/reg.c<br>
index 21bec13..aa77a8a 100644<br>
--- a/src/reg.c<br>
+++ b/src/reg.c<br>
@@ -22,6 +22,7 @@<br>
 #include <libpdbg.h><br>
<br>
 #include "main.h"<br>
+#include "optcmd.h"<br>
<br>
 #define REG_MEM -3<br>
 #define REG_MSR -2<br>
@@ -91,143 +92,58 @@ static int getprocreg(struct pdbg_target *target, uint32_t index, uint64_t *reg,<br>
        return !rc;<br>
 }<br>
<br>
-int handle_gpr(int optind, int argc, char *argv[])<br>
+static int getgpr(int gpr)<br>
 {<br>
-       char *endptr;<br>
-       uint64_t gpr;<br>
-<br>
-       if (optind + 1 >= argc) {<br>
-               printf("%s: command '%s' requires a GPR\n", argv[0], argv[optind]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       errno = 0;<br>
-       gpr = strtoull(argv[optind + 1], &endptr, 0);<br>
-       if (errno || *endptr != '\0') {<br>
-               printf("%s: command '%s' couldn't parse GPR '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       if (gpr > 31) {<br>
-               printf("A GPR must be between zero and 31 inclusive\n");<br>
-               return -1;<br>
-       }<br>
-<br>
-       if (strcmp(argv[optind], "putgpr") == 0) {<br>
-               uint64_t data;<br>
-<br>
-               if (optind + 2 >= argc) {<br>
-                       printf("%s: command '%s' requires data\n", argv[0], argv[optind]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               errno = 0;<br>
-               data = strtoull(argv[optind + 2], &endptr, 0);<br>
-               if (errno || *endptr != '\0') {<br>
-                       printf("%s: command '%s' couldn't parse data '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               return for_each_target("thread", putprocreg, &gpr, &data);<br>
-       }<br>
-<br>
-       return for_each_target("thread", getprocreg, &gpr, NULL);<br>
+       uint64_t reg = gpr;<br>
+       return for_each_target("thread", getprocreg, &reg, NULL);<br>
 }<br>
+OPTCMD_DEFINE_CMD_WITH_ARGS(getgpr, getgpr, (GPR));<br>
<br>
-int handle_nia(int optind, int argc, char *argv[])<br>
+static int putgpr(int gpr, uint64_t data)<br>
 {<br>
-       uint64_t reg = REG_NIA;<br>
-       char *endptr;<br>
-<br>
-       if (strcmp(argv[optind], "putnia") == 0) {<br>
-               uint64_t data;<br>
-<br>
-               if (optind + 1 >= argc) {<br>
-                       printf("%s: command '%s' requires data\n", argv[0], argv[optind]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               errno = 0;<br>
-               data = strtoull(argv[optind + 1], &endptr, 0);<br>
-               if (errno || *endptr != '\0') {<br>
-                       printf("%s: command '%s' couldn't parse data '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               return for_each_target("thread", putprocreg, &reg, &data);<br>
-       }<br>
+       uint64_t reg = gpr;<br>
+       return for_each_target("thread", putprocreg, &reg, &data);<br>
+}<br>
+OPTCMD_DEFINE_CMD_WITH_ARGS(putgpr, putgpr, (GPR, DATA));<br>
<br>
+static int getnia(void)<br>
+{<br>
+       uint64_t reg = REG_NIA;<br>
        return for_each_target("thread", getprocreg, &reg, NULL);<br>
 }<br>
+OPTCMD_DEFINE_CMD(getnia, getnia);<br>
<br>
-int handle_spr(int optind, int argc, char *argv[])<br>
+static int putnia(uint64_t nia)<br>
 {<br>
-       char *endptr;<br>
-       uint64_t spr;<br>
-<br>
-       if (optind + 1 >= argc) {<br>
-               printf("%s: command '%s' requires a GPR\n", argv[0], argv[optind]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       errno = 0;<br>
-       spr = strtoull(argv[optind + 1], &endptr, 0);<br>
-       if (errno || *endptr != '\0') {<br>
-               printf("%s: command '%s' couldn't parse GPR '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       spr += REG_R31;<br>
-<br>
-       if (strcmp(argv[optind], "putspr") == 0) {<br>
-               uint64_t data;<br>
-<br>
-               if (optind + 2 >= argc) {<br>
-                       printf("%s: command '%s' requires data\n", argv[0], argv[optind]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               errno = 0;<br>
-               data = strtoull(argv[optind + 2], &endptr, 0);<br>
-               if (errno || *endptr != '\0') {<br>
-                       printf("%s: command '%s' couldn't parse data '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               return for_each_target("thread", putprocreg, &spr, &data);<br>
-       }<br>
-<br>
-       return for_each_target("thread", getprocreg, &spr, NULL);<br>
+       uint64_t reg = REG_NIA;<br>
+       return for_each_target("thread", getprocreg, &reg, &nia);<br>
 }<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">I think this should be putprocreg. There is at least one more that I found that seems to be using the wrong <put/get>procreg</div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+OPTCMD_DEFINE_CMD_WITH_ARGS(putnia, putnia, (DATA));<br>
<br>
-int handle_msr(int optind, int argc, char *argv[])<br>
+static int getspr(int spr)<br>
 {<br>
-       uint64_t msr = REG_MSR;<br>
-       char *endptr;<br>
-<br>
-       if (strcmp(argv[optind], "putmsr") == 0) {<br>
-               uint64_t data;<br>
-<br>
-               if (optind + 1 >= argc) {<br>
-                       printf("%s: command '%s' requires data\n", argv[0], argv[optind]);<br>
-                       return -1;<br>
-               }<br>
+       uint64_t reg = spr + REG_R31;<br>
+       return for_each_target("thread", getprocreg, &reg, NULL);<br>
+}<br>
+OPTCMD_DEFINE_CMD_WITH_ARGS(getspr, getspr, (SPR));<br>
<br>
-               errno = 0;<br>
-               data = strtoull(argv[optind + 1], &endptr, 0);<br>
-               if (errno || *endptr != '\0') {<br>
-                       printf("%s: command '%s' couldn't parse data '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1]);<br>
-                       return -1;<br>
-               }<br>
+static int putspr(int spr, uint64_t data)<br>
+{<br>
+       uint64_t reg = spr + REG_R31;<br>
+       return for_each_target("thread", putprocreg, &reg, &data);<br>
+}<br>
+OPTCMD_DEFINE_CMD_WITH_ARGS(putspr, putspr, (SPR, DATA));<br>
<br>
-               return for_each_target("thread", putprocreg, &msr, &data);<br>
-       }<br>
+static int getmsr(void)<br>
+{<br>
+       uint64_t reg = REG_MSR;<br>
+       return for_each_target("thread", getprocreg, &reg, NULL);<br>
+}<br>
+OPTCMD_DEFINE_CMD(getmsr, getmsr);<br>
<br>
-       return for_each_target("thread", getprocreg, &msr, NULL);<br>
+static int putmsr(uint64_t data)<br>
+{<br>
+       uint64_t reg = REG_MSR;<br>
+       return for_each_target("thread", putprocreg, &reg, &data);<br>
 }<br>
+OPTCMD_DEFINE_CMD_WITH_ARGS(putmsr, putmsr, (DATA));<br>
diff --git a/src/reg.h b/src/reg.h<br>
deleted file mode 100644<br>
index ad41d9d..0000000<br>
--- a/src/reg.h<br>
+++ /dev/null<br>
@@ -1,20 +0,0 @@<br>
-/* Copyright 2017 IBM Corp.<br>
- *<br>
- * Licensed under the Apache License, Version 2.0 (the "License");<br>
- * you may not use this file except in compliance with the License.<br>
- * You may obtain a copy of the License at<br>
- *<br>
- *     <a href="http://www.apache.org/licenses/LICENSE-2.0" rel="noreferrer noreferrer" target="_blank">http://www.apache.org/licenses/LICENSE-2.0</a><br>
- *<br>
- * Unless required by applicable law or agreed to in writing, software<br>
- * distributed under the License is distributed on an "AS IS" BASIS,<br>
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or<br>
- * implied.<br>
- * See the License for the specific language governing permissions and<br>
- * limitations under the License.<br>
- */<br>
-<br>
-int handle_gpr(int optind, int argc, char *argv[]);<br>
-int handle_nia(int optind, int argc, char *argv[]);<br>
-int handle_spr(int optind, int argc, char *argv[]);<br>
-int handle_msr(int optind, int argc, char *argv[]);<br>
diff --git a/src/ring.c b/src/ring.c<br>
index b0c9376..58df4d1 100644<br>
--- a/src/ring.c<br>
+++ b/src/ring.c<br>
@@ -18,11 +18,12 @@<br>
 #include <stdio.h><br>
 #include <stdlib.h><br>
 #include <string.h><br>
+#include <assert.h><br>
<br>
-#include <target.h><br>
-#include <operations.h><br>
+#include <libpdbg.h><br>
<br>
 #include "main.h"<br>
+#include "optcmd.h"<br>
<br>
 static int pdbg_getring(struct pdbg_target *target, uint32_t index, uint64_t *addr, uint64_t *len)<br>
 {<br>
@@ -51,31 +52,8 @@ static int pdbg_getring(struct pdbg_target *target, uint32_t index, uint64_t *ad<br>
        return 1;<br>
 }<br>
<br>
-int handle_getring(int optind, int argc, char *argv[])<br>
+static int _getring(uint64_t ring_addr, uint64_t ring_len)<br>
 {<br>
-       uint64_t ring_addr, ring_len;<br>
-       char *endptr;<br>
-<br>
-       if (optind + 2 >= argc) {<br>
-               printf("%s: command '%s' requires two arguments (address and length)\n",<br>
-                      argv[0], argv[optind]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       errno = 0;<br>
-       ring_addr = strtoull(argv[optind + 1], &endptr, 0);<br>
-       if (errno || *endptr != '\0') {<br>
-               printf("%s: command '%s' couldn't parse ring address '%s'\n",<br>
-                      argv[0], argv[optind], argv[optind + 1]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       ring_len = strtoull(argv[optind + 2], &endptr, 0);<br>
-       if (errno || *endptr != '\0') {<br>
-               printf("%s: command '%s' couldn't parse ring length '%s'\n",<br>
-                      argv[0], argv[optind], argv[optind + 2]);<br>
-               return -1;<br>
-       }<br>
-<br>
        return for_each_target("chiplet", pdbg_getring, &ring_addr, &ring_len);<br>
 }<br>
+OPTCMD_DEFINE_CMD_WITH_ARGS(getring, _getring, (ADDRESS, DATA));<br>
diff --git a/src/ring.h b/src/ring.h<br>
deleted file mode 100644<br>
index a72c875..0000000<br>
--- a/src/ring.h<br>
+++ /dev/null<br>
@@ -1,17 +0,0 @@<br>
-/* Copyright 2018 IBM Corp.<br>
- *<br>
- * Licensed under the Apache License, Version 2.0 (the "License");<br>
- * you may not use this file except in compliance with the License.<br>
- * You may obtain a copy of the License at<br>
- *<br>
- *      <a href="http://www.apache.org/licenses/LICENSE-2.0" rel="noreferrer noreferrer" target="_blank">http://www.apache.org/licenses/LICENSE-2.0</a><br>
- *<br>
- * Unless required by applicable law or agreed to in writing, software<br>
- * distributed under the License is distributed on an "AS IS" BASIS,<br>
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or<br>
- * implied.<br>
- * See the License for the specific language governing permissions and<br>
- * limitations under the License.<br>
- */<br>
-<br>
-int handle_getring(int optind, int argc, char *argv[]);<br>
diff --git a/src/scom.c b/src/scom.c<br>
index 4c59e2a..2372e91 100644<br>
--- a/src/scom.c<br>
+++ b/src/scom.c<br>
@@ -22,8 +22,9 @@<br>
 #include <libpdbg.h><br>
<br>
 #include "main.h"<br>
+#include "optcmd.h"<br>
<br>
-static int getscom(struct pdbg_target *target, uint32_t index, uint64_t *addr, uint64_t *unused)<br>
+static int _getscom(struct pdbg_target *target, uint32_t index, uint64_t *addr, uint64_t *unused)<br>
 {<br>
        uint64_t value;<br>
<br>
@@ -35,7 +36,13 @@ static int getscom(struct pdbg_target *target, uint32_t index, uint64_t *addr, u<br>
        return 1;<br>
 }<br>
<br>
-static int putscom(struct pdbg_target *target, uint32_t index, uint64_t *addr, uint64_t *data)<br>
+ int getscom(uint64_t addr)<br>
+{<br>
+       return for_each_target("pib", _getscom, &addr, NULL);<br>
+}<br>
+OPTCMD_DEFINE_CMD_WITH_ARGS(getscom, getscom, (ADDRESS));<br>
+<br>
+static int _putscom(struct pdbg_target *target, uint32_t index, uint64_t *addr, uint64_t *data)<br>
 {<br>
        if (pib_write(target, *addr, *data))<br>
                return 0;<br>
@@ -43,44 +50,9 @@ static int putscom(struct pdbg_target *target, uint32_t index, uint64_t *addr, u<br>
        return 1;<br>
 }<br>
<br>
-<br>
-int handle_scoms(int optind, int argc, char *argv[])<br>
+ int putscom(uint64_t addr, uint64_t data, uint64_t mask)<br>
 {<br>
-       uint64_t addr;<br>
-       char *endptr;<br>
-<br>
-       if (optind + 1 >= argc) {<br>
-               printf("%s: command '%s' requires an address\n", argv[0], argv[optind]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       errno = 0;<br>
-       addr = strtoull(argv[optind + 1], &endptr, 0);<br>
-       if (errno || *endptr != '\0') {<br>
-               printf("%s: command '%s' couldn't parse address '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       if (strcmp(argv[optind], "putscom") == 0) {<br>
-               uint64_t data;<br>
-<br>
-               if (optind + 2 >= argc) {<br>
-                       printf("%s: command '%s' requires data\n", argv[0], argv[optind]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               errno = 0;<br>
-               data = strtoull(argv[optind + 2], &endptr, 0);<br>
-               if (errno || *endptr != '\0') {<br>
-                       printf("%s: command '%s' couldn't parse data '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1]);<br>
-                       return -1;<br>
-               }<br>
-<br>
-               return for_each_target("pib", putscom, &addr, &data);<br>
-       }<br>
-<br>
-       return for_each_target("pib", getscom, &addr, NULL);<br>
+       /* TODO: Restore the <mask> functionality */<br>
+       return for_each_target("pib", _putscom, &addr, &data);<br>
 }<br>
-<br>
+OPTCMD_DEFINE_CMD_WITH_ARGS(putscom, putscom, (ADDRESS, DATA, DEFAULT_DATA("0xffffffffffffffff")));<br>
diff --git a/src/scom.h b/src/scom.h<br>
deleted file mode 100644<br>
index d4325b5..0000000<br>
--- a/src/scom.h<br>
+++ /dev/null<br>
@@ -1,18 +0,0 @@<br>
-/* Copyright 2017 IBM Corp.<br>
- *<br>
- * Licensed under the Apache License, Version 2.0 (the "License");<br>
- * you may not use this file except in compliance with the License.<br>
- * You may obtain a copy of the License at<br>
- *<br>
- *     <a href="http://www.apache.org/licenses/LICENSE-2.0" rel="noreferrer noreferrer" target="_blank">http://www.apache.org/licenses/LICENSE-2.0</a><br>
- *<br>
- * Unless required by applicable law or agreed to in writing, software<br>
- * distributed under the License is distributed on an "AS IS" BASIS,<br>
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or<br>
- * implied.<br>
- * See the License for the specific language governing permissions and<br>
- * limitations under the License.<br>
- */<br>
-#include <inttypes.h><br>
-<br>
-int handle_scoms(int optind, int argc, char *argv[]);<br>
diff --git a/src/thread.c b/src/thread.c<br>
index e8b54cb..4b95636 100644<br>
--- a/src/thread.c<br>
+++ b/src/thread.c<br>
@@ -21,7 +21,7 @@<br>
 #include <libpdbg.h><br>
<br>
 #include "main.h"<br>
-#include "mem.h"<br>
+#include "optcmd.h"<br>
<br>
 static int print_thread_status(struct pdbg_target *target, uint32_t index, uint64_t *arg, uint64_t *unused1)<br>
 {<br>
@@ -81,6 +81,57 @@ static int print_core_thread_status(struct pdbg_target *core_target, uint32_t in<br>
        return rc;<br>
 }<br>
<br>
+static bool is_real_address(struct thread_regs *regs, uint64_t addr)<br>
+{<br>
+       return true;<br>
+       if ((addr & 0xf000000000000000ULL) == 0xc000000000000000ULL)<br>
+               return true;<br>
+       return false;<br>
+}<br>
+<br>
+static int load8(struct pdbg_target *target, uint64_t addr, uint64_t *value)<br>
+{<br>
+       if (adu_getmem(target, addr, (uint8_t *)value, 8)) {<br>
+               pdbg_log(PDBG_ERROR, "Unable to read memory address=%016" PRIx64 ".\n", addr);<br>
+               return 0;<br>
+       }<br>
+<br>
+       return 1;<br>
+}<br>
+<br>
+static int dump_stack(struct thread_regs *regs)<br>
+{<br>
+       struct pdbg_target *target;<br>
+       uint64_t sp = regs->gprs[1];<br>
+       uint64_t pc;<br>
+<br>
+       pdbg_for_each_class_target("adu", target) {<br>
+               if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED)<br>
+                       continue;<br>
+               break;<br>
+       }<br>
+<br>
+       printf("STACK:\n");<br>
+       if (!target)<br>
+               pdbg_log(PDBG_ERROR, "Unable to read memory (no ADU found)\n");<br>
+<br>
+       if (sp && is_real_address(regs, sp)) {<br>
+               if (!load8(target, sp, &sp))<br>
+                       return 1;<br>
+               while (sp && is_real_address(regs, sp)) {<br>
+                       if (!load8(target, sp + 16, &pc))<br>
+                               return 1;<br>
+<br>
+                       printf(" 0x%016" PRIx64 " 0x%16" PRIx64 "\n", sp, pc);<br>
+<br>
+                       if (!load8(target, sp, &sp))<br>
+                               return 1;<br>
+               }<br>
+       }<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
 static int get_thread_max_index(struct pdbg_target *target, uint32_t index, uint64_t *maxindex, uint64_t *unused)<br>
 {<br>
        if (index > *maxindex)<br>
@@ -140,48 +191,37 @@ static int state_thread(struct pdbg_target *thread_target, uint32_t index, uint6<br>
        return 1;<br>
 }<br>
<br>
-int thread_start(int optind, int argc, char *argv[])<br>
+static int thread_start(void)<br>
 {<br>
        return for_each_target("thread", start_thread, NULL, NULL);<br>
 }<br>
+OPTCMD_DEFINE_CMD(start, thread_start);<br>
<br>
-int thread_step(int optind, int argc, char *argv[])<br>
+static int thread_step(uint64_t count)<br>
 {<br>
-       uint64_t count;<br>
-       char *endptr;<br>
-<br>
-       if (optind + 1 >= argc) {<br>
-               printf("%s: command '%s' requires a count\n", argv[0], argv[optind]);<br>
-               return -1;<br>
-       }<br>
-<br>
-       errno = 0;<br>
-       count = strtoull(argv[optind + 1], &endptr, 0);<br>
-       if (errno || *endptr != '\0') {<br>
-               printf("%s: command '%s' couldn't parse count '%s'\n",<br>
-                               argv[0], argv[optind], argv[optind + 1]);<br>
-               return -1;<br>
-       }<br>
-<br>
        return for_each_target("thread", step_thread, &count, NULL);<br>
 }<br>
+OPTCMD_DEFINE_CMD_WITH_ARGS(step, thread_step, (DATA));<br>
<br>
-int thread_stop(int optind, int argc, char *argv[])<br>
+static int thread_stop(void)<br>
 {<br>
        return for_each_target("thread", stop_thread, NULL, NULL);<br>
 }<br>
+OPTCMD_DEFINE_CMD(stop, thread_stop);<br>
<br>
-int thread_status_print(int optind, int argc, char *argv[])<br>
+static int thread_status_print(void)<br>
 {<br>
        return for_each_target("pib", print_proc_thread_status, NULL, NULL);<br>
 }<br>
+OPTCMD_DEFINE_CMD(threadstatus, thread_status_print);<br>
<br>
-int thread_sreset(int optind, int argc, char *argv[])<br>
+static int thread_sreset(void)<br>
 {<br>
        return for_each_target("thread", sreset_thread, NULL, NULL);<br>
 }<br>
+OPTCMD_DEFINE_CMD(sreset, thread_sreset);<br>
<br>
-int thread_state(int optind, int argc, char *argv[])<br>
+static int thread_state(void)<br>
 {<br>
        int err;<br>
<br>
@@ -191,3 +231,4 @@ int thread_state(int optind, int argc, char *argv[])<br>
<br>
        return err;<br>
 }<br>
+OPTCMD_DEFINE_CMD(regs, thread_state);<br>
diff --git a/src/thread.h b/src/thread.h<br>
deleted file mode 100644<br>
index 0c1caa2..0000000<br>
--- a/src/thread.h<br>
+++ /dev/null<br>
@@ -1,23 +0,0 @@<br>
-/* Copyright 2017 IBM Corp.<br>
- *<br>
- * Licensed under the Apache License, Version 2.0 (the "License");<br>
- * you may not use this file except in compliance with the License.<br>
- * You may obtain a copy of the License at<br>
- *<br>
- *     <a href="http://www.apache.org/licenses/LICENSE-2.0" rel="noreferrer noreferrer" target="_blank">http://www.apache.org/licenses/LICENSE-2.0</a><br>
- *<br>
- * Unless required by applicable law or agreed to in writing, software<br>
- * distributed under the License is distributed on an "AS IS" BASIS,<br>
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or<br>
- * implied.<br>
- * See the License for the specific language governing permissions and<br>
- * limitations under the License.<br>
- */<br>
-#include <inttypes.h><br>
-<br>
-int thread_start(int optind, int argc, char *argv[]);<br>
-int thread_step(int optind, int argc, char *argv[]);<br>
-int thread_stop(int optind, int argc, char *argv[]);<br>
-int thread_status_print(int optind, int argc, char *argv[]);<br>
-int thread_sreset(int optind, int argc, char *argv[]);<br>
-int thread_state(int optind, int argc, char *argv[]);<br>
-- <br>
2.11.0<br>
<br>
-- <br>
Pdbg mailing list<br>
<a href="mailto:Pdbg@lists.ozlabs.org" target="_blank" rel="noreferrer">Pdbg@lists.ozlabs.org</a><br>
<a href="https://lists.ozlabs.org/listinfo/pdbg" rel="noreferrer noreferrer" target="_blank">https://lists.ozlabs.org/listinfo/pdbg</a><br>
</blockquote></div></div></div>