commit ac695472be018e1a1fbca3b5e3ca078dcbd8cfe3
parent 4a34d8ea3153622a953355813c0c79593ffd2331
Author: Brian Swetland <swetland@frotz.net>
Date: Sun, 21 Jun 2015 04:49:42 -0700
debugger: fold gdb-bridge into debugger binary (run on loopback:5555)
Diffstat:
4 files changed, 109 insertions(+), 58 deletions(-)
diff --git a/tools/debugger-core.c b/tools/debugger-core.c
@@ -23,16 +23,13 @@
#include <ctype.h>
#include <stdarg.h>
-#include <fw/types.h>
-#include "debugger.h"
-
#include <pthread.h>
+#include <sys/socket.h>
-#include "rswdp.h"
-
-// for core debug regs
+#include <fw/types.h>
#include <protocol/rswdp.h>
-
+#include "debugger.h"
+#include "rswdp.h"
#include "linenoise.h"
#define DHCSR_C_DEBUGEN (1 << 0)
@@ -55,10 +52,6 @@
#define DFSR_EXTERNAL (1 << 4)
#define DFSR_MASK 0x1F
-#define DEBUG_MONITOR 1
-
-#if DEBUG_MONITOR
-
static void m_event(const char *evt) {
linenoisePause();
fprintf(stdout, "DEBUG EVENT: %s\n", evt);
@@ -107,22 +100,39 @@ void *debugger_monitor(void *arg) {
}
}
-void debugger_init() {
- pthread_create(&_dbg_thread, NULL, debugger_monitor, NULL);
+void gdb_server(int fd);
+int socket_listen_tcp(unsigned port);
+
+static pthread_t _listen_master;
+void *gdb_listener(void *arg) {
+ int fd;
+ if ((fd = socket_listen_tcp(5555)) < 0) {
+ linenoisePause();
+ xprintf("gdb_listener() cannot bind to 5555\n");
+ linenoiseResume();
+ return NULL;
+ }
+ for (;;) {
+ int s = accept(fd, NULL, NULL);
+ if (s >= 0) {
+ linenoisePause();
+ xprintf("[ gdb connected ]\n");
+ linenoiseResume();
+ gdb_server(s);
+ close(s);
+ linenoisePause();
+ xprintf("[ gdb disconnected ]\n");
+ linenoiseResume();
+ }
+ }
+ return NULL;
}
-#else
-
-void debugger_lock() {
- swdp_clear_error();
-}
-void debugger_unlock() {
-}
void debugger_init() {
+ pthread_create(&_dbg_thread, NULL, debugger_monitor, NULL);
+ pthread_create(&_listen_master, NULL, gdb_listener, NULL);
}
-#endif
-
static struct varinfo *all_variables = 0;
static struct funcinfo *allfuncs = 0;
diff --git a/tools/gdb-bridge.c b/tools/gdb-bridge.c
@@ -26,6 +26,17 @@
#include <fw/types.h>
#include "rswdp.h"
#include <protocol/rswdp.h>
+#include "debugger.h"
+#include "linenoise.h"
+
+void zprintf(const char *fmt, ...) {
+ linenoisePause();
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ linenoiseResume();
+}
struct gdbcnxn {
int tx, rx;
@@ -120,7 +131,7 @@ again:
return 0;
}
if (c < 0x20)
- fprintf(stderr,"! %02x !\n",c);
+ zprintf("PKT: ?? %02x\n",c);
} while (c != '$');
chk = 0;
@@ -137,7 +148,7 @@ again:
c = strtoul(tmp, 0, 16);
if (c != (chk & 0xff)) {
gdb_putc(gc,'-');
- fprintf(stderr,"PKT: BAD CHECKSUM\n");
+ zprintf("PKT: BAD CHECKSUM\n");
goto again;
} else {
gdb_putc(gc,'+');
@@ -149,7 +160,7 @@ again:
}
}
gdb_putc(gc,'-');
- fprintf(stderr,"PKT: OVERFLOW\n");
+ zprintf("PKT: OVERFLOW\n");
goto again;
fail:
@@ -168,6 +179,7 @@ unsigned unhex(char *x) {
static struct gdbcnxn *GC;
+#if 0
void xprintf(const char *fmt, ...) {
char buf[256];
va_list ap;
@@ -177,11 +189,9 @@ void xprintf(const char *fmt, ...) {
va_end(ap);
gdb_puthex(GC, buf, strlen(buf));
}
+#endif
-void debugger_command(char *line);
-
-void handle_ext_command(struct gdbcnxn *gc, char *cmd, char *args)
-{
+void handle_ext_command(struct gdbcnxn *gc, char *cmd, char *args) {
if (!strcmp(cmd,"Rcmd")) {
char *p = args;
cmd = p;
@@ -195,8 +205,7 @@ void handle_ext_command(struct gdbcnxn *gc, char *cmd, char *args)
}
}
-void handle_command(struct gdbcnxn *gc, char *cmd)
-{
+void handle_command(struct gdbcnxn *gc, char *cmd) {
union {
u32 w[256+2];
u16 h[512+4];
@@ -253,6 +262,8 @@ void handle_command(struct gdbcnxn *gc, char *cmd)
break;
}
+ default:
+ zprintf("CMD: %c unknown\n", cmd[0]);
}
gdb_epilogue(gc);
}
@@ -260,27 +271,17 @@ void handle_command(struct gdbcnxn *gc, char *cmd)
void handler(int n) {
}
-int main(int argc, char **argv) {
+void gdb_server(int fd) {
struct gdbcnxn gc;
char cmd[32768];
- gc.tx = 1;
- gc.rx = 0;
+ gc.tx = fd;
+ gc.rx = fd;
gc.chk = 0;
- signal(SIGINT, handler);
-
- fprintf(stderr,"[ debugport v1.0 ]\n");
-
- if (swdp_open())
- fprintf(stderr,"error: cannot find swdp board\n");
-
- for (;;) {
- if (gdb_recv(&gc, cmd, sizeof(cmd))) {
- fprintf(stderr,"[ disconnect ]\n");
- return 0;
- }
- //fprintf(stderr,"PKT: %s\n", cmd);
+ while (gdb_recv(&gc, cmd, sizeof(cmd)) == 0) {
+ zprintf("PKT: %s\n", cmd);
+ debugger_lock();
handle_command(&gc, cmd);
+ debugger_unlock();
}
- return 0;
}
diff --git a/tools/module.mk b/tools/module.mk
@@ -7,6 +7,8 @@ M_OBJS += tools/debugger-commands.o
M_OBJS += tools/rswdp.o
M_OBJS += tools/linenoise.o
M_OBJS += tools/usb.o
+M_OBJS += tools/socket.o
+M_OBJS += tools/gdb-bridge.o
M_OBJS += out/debugger-builtins.o
$(call build-host-executable)
@@ -15,16 +17,6 @@ out/debugger-builtins.c: $(AGENTS) bin/mkbuiltins
@mkdir -p out
./bin/mkbuiltins $(AGENTS) > $@
-M_NAME := gdb-bridge
-M_OBJS := tools/gdb-bridge.o
-M_OBJS += tools/debugger-core.o
-M_OBJS += tools/debugger-commands.o
-M_OBJS += tools/rswdp.o
-M_OBJS += tools/linenoise.o
-M_OBJS += tools/usb.o
-M_OBJS += out/debugger-builtins.o
-$(call build-host-executable)
-
M_NAME := stm32boot
M_OBJS := tools/stm32boot.o
$(call build-host-executable)
diff --git a/tools/socket.c b/tools/socket.c
@@ -0,0 +1,48 @@
+/* socket.c
+ *
+ * Copyright 2015 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+int socket_listen_tcp(unsigned port) {
+ int fd, n = 1;
+ struct sockaddr_in addr;
+
+ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ return -1;
+ }
+
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ addr.sin_port = htons(port);
+ if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ goto fail;
+ }
+ if (listen(fd, 10) < 0) {
+ goto fail;
+ }
+ return fd;
+fail:
+ close(fd);
+ return -1;
+}