This is an automated email from Gerrit. "Tim Nordell <tnord...@airgain.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7179
-- gerrit commit 2eb3980b66f153b9c395a707901624a5d0d742e3 Author: Tim Nordell <tnord...@airgain.com> Date: Wed Sep 7 11:59:47 2022 -0500 rtos: Support looking up .lto_priv.0 appended to symbol name When FreeRTOS (at least) is compiled with -flto, this leaves certain static symbols with .lto_priv.0 appended to their name. Arguably this could be considered to be a gdb or gcc bug, but one place to resolve it for OpenOCD usage is here at symbol lookup time. Note that the ".0" is for the first such instance of the variable as a static; additional ones would end up as ".1", ".2", etc, and are not considered here. Signed-off-by: Tim Nordell <tnord...@airgain.com> Change-Id: I03580b45e8ea364392ef4e05c96276416b390cb0 diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index 3aa6ab4664..fbf3717459 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -221,13 +221,15 @@ static struct symbol_table_elem *next_symbol(struct rtos *os, char *cur_symbol, */ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size) { + static const char lto_priv_suffix[] = ".lto_priv.0"; int rtos_detected = 0; uint64_t addr = 0; size_t reply_len; char reply[GDB_BUFFER_SIZE + 1], cur_sym[GDB_BUFFER_SIZE / 2 + 1] = ""; /* Extra byte for null-termination */ - struct symbol_table_elem *next_sym; + struct symbol_table_elem *next_sym = NULL; struct target *target = get_target_from_connection(connection); struct rtos *os = target->rtos; + bool retry_with_lto_priv = false; reply_len = sprintf(reply, "OK"); @@ -238,13 +240,25 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s size_t len = unhexify((uint8_t *)cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1)); cur_sym[len] = 0; + /* Detect if the response contains lto_priv_suffix at the end */ + bool is_lto_priv = (len > strlen(lto_priv_suffix) && + !strcmp(cur_sym + len - strlen(lto_priv_suffix), lto_priv_suffix)); + + /* Trim the appended lto_priv_suffix for all of the logic below */ + if (is_lto_priv) + cur_sym[len - sizeof(lto_priv_suffix) + 1] = 0; + if ((strcmp(packet, "qSymbol::") != 0) && /* GDB is not offering symbol lookup for the first time */ (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr))) { /* GDB did not find an address for a symbol */ /* GDB could not find an address for the previous symbol */ struct symbol_table_elem *sym = find_symbol(os, cur_sym); - if (sym && !sym->optional) { /* the symbol is mandatory for this RTOS */ + if (!is_lto_priv) + { + retry_with_lto_priv = true; + next_sym = sym; + } else if (sym && !sym->optional) { /* the symbol is mandatory for this RTOS */ if (!target->rtos_auto_detect) { LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym); goto done; @@ -261,9 +275,12 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s } } - LOG_DEBUG("RTOS: Address of symbol '%s' is 0x%" PRIx64, cur_sym, addr); + LOG_DEBUG("RTOS: Address of symbol '%s%s' is 0x%" PRIx64, + cur_sym, is_lto_priv ? lto_priv_suffix : "", + addr); - next_sym = next_symbol(os, cur_sym, addr); + if (!next_sym) + next_sym = next_symbol(os, cur_sym, addr); /* Should never happen unless the debugger misbehaves */ if (!next_sym) { @@ -289,18 +306,26 @@ int rtos_qsymbol(struct connection *connection, char const *packet, int packet_s } } - if (8 + (strlen(next_sym->symbol_name) * 2) + 1 > sizeof(reply)) { + + if (8 + (strlen(next_sym->symbol_name) * 2 + retry_with_lto_priv * strlen(lto_priv_suffix)) + 1 > sizeof(reply)) { LOG_ERROR("ERROR: RTOS symbol '%s' name is too long for GDB!", next_sym->symbol_name); goto done; } - LOG_DEBUG("RTOS: Requesting symbol lookup of '%s' from the debugger", next_sym->symbol_name); + LOG_DEBUG("RTOS: Requesting symbol lookup of '%s%s' from the debugger", + next_sym->symbol_name, retry_with_lto_priv ? lto_priv_suffix : ""); reply_len = snprintf(reply, sizeof(reply), "qSymbol:"); reply_len += hexify(reply + reply_len, (const uint8_t *)next_sym->symbol_name, strlen(next_sym->symbol_name), sizeof(reply) - reply_len); + if (retry_with_lto_priv) { + reply_len += hexify(reply + reply_len, + (const uint8_t *)lto_priv_suffix, strlen(lto_priv_suffix), + sizeof(reply) - reply_len); + } + done: gdb_put_packet(connection, reply, reply_len); return rtos_detected; --