From ab858febb6ca6e5dada1492e96c00d8b12c575c0 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 21 May 2018 16:14:33 +0200 Subject: [PATCH] gdb_server: add per target option "-gdb-port" The argument passed to global config command "gdb_port" is usually, but not always, a TCP port number. In case of multiple targets, this numeric value is used as the first port of a set of consecutive TCP ports assigned one per target. If the argument is not a numeric value (e.g. "pipe", "disabled", ...) then incrementing it for the next target has no sense. Add the option "-gdb-port number" to the commands "target create" and "$target_name configure" to override, for the specific target, the general global configuration. This permits to use a per target "-gdb-port disabled", when no gdb port is required for that specific target. It also makes possible to choose a custom TCP port number for each target, overriding the usual sequence of consecutive port numbers. Change-Id: I3b9a1910b28ab4bc757e839d0e5d08ffc29f7ab4 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4530 Tested-by: jenkins Reviewed-by: Christopher Head Reviewed-by: Matthias Welwarsky --- doc/openocd.texi | 14 +++++++++++++- src/server/gdb_server.c | 27 +++++++++++++++++++-------- src/target/target.c | 21 +++++++++++++++++++++ src/target/target.h | 2 ++ 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index c0d065d4..3eb63090 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2114,6 +2114,7 @@ In such cases, just specify the relevant port number as "disabled". If you disable all access through TCP/IP, you will need to use the command line @option{-pipe} option. +@anchor{gdb_port} @deffn {Command} gdb_port [number] @cindex GDB server Normally gdb listens to a TCP/IP port, but GDB can also @@ -2139,11 +2140,15 @@ The GDB port for the first target will be the base port, the second target will listen on gdb_port + 1, and so on. When not specified during the configuration stage, the port @var{number} defaults to 3333. +When @var{number} is not a numeric value, incrementing it to compute +the next port number does not work. In this case, specify the proper +@var{number} for each target by using the option @code{-gdb-port} of the +commands @command{target create} or @command{$target_name configure}. +@xref{gdbportoverride,,option -gdb-port}. Note: when using "gdb_port pipe", increasing the default remote timeout in gdb (with 'set remotetimeout') is recommended. An insufficient timeout may cause initialization to fail with "Unknown remote qXfer reply: OK". - @end deffn @deffn {Command} tcl_port [number] @@ -4458,6 +4463,13 @@ to the target. Currently, only the @code{aarch64} target makes use of this optio where it is a mandatory configuration for the target run control. @xref{armcrosstrigger,,ARM Cross-Trigger Interface}, for instruction on how to declare and control a CTI instance. + +@anchor{gdbportoverride} +@item @code{-gdb-port} @var{number} -- see command @command{gdb_port} for the +possible values of the parameter @var{number}, which are not only numeric values. +Use this option to override, for this target only, the global parameter set with +command @command{gdb_port}. +@xref{gdb_port,,command gdb_port}. @end itemize @end deffn diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 69afb2fd..2375e951 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -3373,6 +3373,8 @@ static int gdb_target_start(struct target *target, const char *port) if (NULL == gdb_service) return -ENOMEM; + LOG_DEBUG("starting gdb server for %s on %s", target_name(target), port); + gdb_service->target = target; gdb_service->core[0] = -1; gdb_service->core[1] = -1; @@ -3398,16 +3400,30 @@ static int gdb_target_start(struct target *target, const char *port) static int gdb_target_add_one(struct target *target) { + /* one gdb instance per smp list */ + if ((target->smp) && (target->gdb_service)) + return ERROR_OK; + + if (target->gdb_port_override) { + if (strcmp(target->gdb_port_override, "disabled") == 0) { + LOG_INFO("gdb port disabled"); + return ERROR_OK; + } + return gdb_target_start(target, target->gdb_port_override); + } + if (strcmp(gdb_port, "disabled") == 0) { LOG_INFO("gdb port disabled"); return ERROR_OK; } - /* one gdb instance per smp list */ - if ((target->smp) && (target->gdb_service)) - return ERROR_OK; int retval = gdb_target_start(target, gdb_port_next); if (retval == ERROR_OK) { + /* save the port number so can be queried with + * $target_name cget -gdb-port + */ + target->gdb_port_override = strdup(gdb_port_next); + long portnumber; /* If we can parse the port number * then we increment the port number for the next target. @@ -3432,11 +3448,6 @@ static int gdb_target_add_one(struct target *target) int gdb_target_add_all(struct target *target) { - if (strcmp(gdb_port, "disabled") == 0) { - LOG_INFO("gdb server disabled"); - return ERROR_OK; - } - if (NULL == target) { LOG_WARNING("gdb services need one or more targets defined"); return ERROR_OK; diff --git a/src/target/target.c b/src/target/target.c index 68f93210..253928d7 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1927,6 +1927,7 @@ static void target_destroy(struct target *target) target->smp = 0; } + free(target->gdb_port_override); free(target->type); free(target->trace_info); free(target->fileio_info); @@ -4537,6 +4538,7 @@ enum target_cfg_param { TCFG_DBGBASE, TCFG_RTOS, TCFG_DEFER_EXAMINE, + TCFG_GDB_PORT, }; static Jim_Nvp nvp_config_opts[] = { @@ -4552,6 +4554,7 @@ static Jim_Nvp nvp_config_opts[] = { { .name = "-dbgbase", .value = TCFG_DBGBASE }, { .name = "-rtos", .value = TCFG_RTOS }, { .name = "-defer-examine", .value = TCFG_DEFER_EXAMINE }, + { .name = "-gdb-port", .value = TCFG_GDB_PORT }, { .name = NULL, .value = -1 } }; @@ -4839,6 +4842,20 @@ no_params: /* loop for more */ break; + case TCFG_GDB_PORT: + if (goi->isconfigure) { + const char *s; + e = Jim_GetOpt_String(goi, &s, NULL); + if (e != JIM_OK) + return e; + target->gdb_port_override = strdup(s); + } else { + if (goi->argc != 0) + goto no_params; + } + Jim_SetResultString(goi->interp, target->gdb_port_override ? : "undefined", -1); + /* loop for more */ + break; } } /* while (goi->argc) */ @@ -5613,6 +5630,8 @@ static int target_create(Jim_GetOptInfo *goi) target->rtos = NULL; target->rtos_auto_detect = false; + target->gdb_port_override = NULL; + /* Do the rest as "configure" options */ goi->isconfigure = 1; e = target_configure(goi, target); @@ -5635,6 +5654,7 @@ static int target_create(Jim_GetOptInfo *goi) } if (e != JIM_OK) { + free(target->gdb_port_override); free(target->type); free(target); return e; @@ -5652,6 +5672,7 @@ static int target_create(Jim_GetOptInfo *goi) e = (*(target->type->target_create))(target, goi->interp); if (e != ERROR_OK) { LOG_DEBUG("target_create failed"); + free(target->gdb_port_override); free(target->type); free(target->cmd_name); free(target); diff --git a/src/target/target.h b/src/target/target.h index 51a5b693..c3137a08 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -206,6 +206,8 @@ struct target { /* file-I/O information for host to do syscall */ struct gdb_fileio_info *fileio_info; + char *gdb_port_override; /* target-specific override for gdb_port */ + /* The semihosting information, extracted from the target. */ struct semihosting *semihosting; }; -- 2.39.5