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;

-- 

Reply via email to