xdebug

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 72a26a5bc1b2c47dc5cf2bc111c7cbcd1fbaa9f7
parent 1b4559aa03e8793a3901fd4a21dfb673f6e8b8e1
Author: Brian Swetland <swetland@frotz.net>
Date:   Wed,  8 Mar 2023 20:47:46 -0800

added upload and download commands

Diffstat:
MMakefile | 3++-
Asrc/commands-agent.c | 0
Asrc/commands-file.c | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/commands.c | 7++++++-
4 files changed, 135 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile @@ -69,7 +69,8 @@ COMMON := src/transport-arm-debug.c src/transport-dap.c src/usb.c XTEST_SRCS := src/xtest.c $(COMMON) XTEST_OBJS := $(addprefix out/,$(patsubst %.c,%.o,$(filter %.c,$(XTEST_SRCS)))) -XDEBUG_SRCS := src/xdebug.c src/commands.c $(COMMON) +XDEBUG_SRCS := src/xdebug.c $(COMMON) +XDEBUG_SRCS += src/commands.c src/commands-file.c src/commands-agent.c XDEBUG_SRCS += tui/tui.c termbox/termbox.c termbox/utf8.c gen/builtins.c XDEBUG_OBJS := $(addprefix out/,$(patsubst %.c,%.o,$(filter %.c,$(XDEBUG_SRCS)))) diff --git a/src/commands-agent.c b/src/commands-agent.c diff --git a/src/commands-file.c b/src/commands-file.c @@ -0,0 +1,127 @@ +// Copyright 2023, Brian Swetland <swetland@frotz.net> +// Licensed under the Apache License, Version 2.0. + +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/time.h> + +#include "xdebug.h" +#include "transport.h" +#include "arm-v7-debug.h" +#include "arm-v7-system-control.h" + +void *load_file(const char *fn, size_t *_sz) { + int fd; + off_t sz; + void *data = NULL; + fd = open(fn, O_RDONLY); + if (fd < 0) goto fail; + sz = lseek(fd, 0, SEEK_END); + if (sz < 0) goto fail; + if (lseek(fd, 0, SEEK_SET)) goto fail; + if ((data = malloc(sz + 4)) == NULL) goto fail; + if (read(fd, data, sz) != sz) goto fail; + *_sz = sz; + return data; +fail: + if (data) free(data); + if (fd >= 0) close(fd); + return NULL; +} + +static long long now() { + struct timeval tv; + gettimeofday(&tv, 0); + return ((long long) tv.tv_usec) + ((long long) tv.tv_sec) * 1000000LL; +} + +int do_upload(DC* dc, CC* cc) { + int status = DBG_ERR; + const char* fn; + uint32_t addr; + uint32_t len; + uint32_t sz; + long long t0, t1; + int fd, r; + void *data; + + if (cmd_arg_str(cc, 1, &fn)) return DBG_ERR; + if (cmd_arg_u32(cc, 2, &addr)) return DBG_ERR; + if (cmd_arg_u32(cc, 3, &len)) return DBG_ERR; + if (addr & 3) { + ERROR("address not word aligned\n"); + return DBG_ERR; + } + if ((fd = open(fn, O_CREAT | O_TRUNC | O_WRONLY, 0644)) < 0) { + ERROR("cannot open '%s'\n", fn); + return DBG_ERR; + } + sz = (len + 3) & ~3; + + if ((data = malloc(sz)) == NULL) { + ERROR("out of memory\n"); + goto done; + } + + INFO("upload: reading %d bytes...\n", sz); + t0 = now(); + if (dc_mem_rd_words(dc, addr, sz / 4, data) < 0) { + ERROR("failed to read data\n"); + goto done; + } + t1 = now(); + INFO("upload: %lld uS -> %lld B/s\n", (t1 - t0), + (((long long)sz) * 1000000LL) / (t1 - t0)); + + char *x = data; + while (len > 0) { + r = write(fd, x, sz); + if (r < 0) { + if (errno == EINTR) continue; + ERROR("write error\n"); + goto done; + } + x += r; + len -= r; + } + status = 0; +done: + close(fd); + if (data) free(data); + return status; +} + +int do_download(DC* dc, CC* cc) { + const char* fn; + uint32_t addr; + void *data; + size_t sz; + long long t0, t1; + + if (cmd_arg_str(cc, 1, &fn)) return DBG_ERR; + if (cmd_arg_u32(cc, 2, &addr)) return DBG_ERR; + + if ((data = load_file(fn, &sz)) == NULL) { + ERROR("cannot read '%s'\n", fn); + return DBG_ERR; + } + sz = (sz + 3) & ~3; + + INFO("download: sending %ld bytes...\n", sz); + t0 = now(); + if (dc_mem_wr_words(dc, addr, sz / 4, data) < 0) { + ERROR("failed to write data\n"); + free(data); + return DBG_ERR; + } + t1 = now(); + INFO("download: %lld uS -> %lld B/s\n", (t1 - t0), + (((long long)sz) * 1000000LL) / (t1 - t0)); + free(data); + return 0; +} + + diff --git a/src/commands.c b/src/commands.c @@ -11,7 +11,7 @@ int do_attach(DC* dc, CC* cc) { uint32_t n; - dc_set_clock(dc, 4000000); + dc_set_clock(dc, 1000000); return dc_attach(dc, 0, 0, &n); } @@ -255,6 +255,9 @@ int do_exit(DC* dc, CC* cc) { int do_help(DC* dc, CC* cc); +int do_upload(DC* dc, CC* cc); +int do_download(DC* dc, CC* cc); + struct { const char* name; int (*func)(DC* dc, CC* cc); @@ -274,6 +277,8 @@ struct { { "dr", do_rd, NULL }, { "wr", do_wr, "write word wr <addr> <val>" }, { "regs", do_regs, "dump registers" }, +{ "download", do_download, "write file to memory download <file> <addr>" }, +{ "upload", do_upload, "read memory to file upload <file> <addr> <len>" }, { "help", do_help, "list commands" }, { "exit", do_exit, "exit debugger" }, { "quit", do_exit, NULL },