/* Handle all of the extended 'q' packets. */ void handle_query (char *own_buf, int packet_len, int *new_packet_len_p) { static struct inferior_list_entry *thread_ptr; /* Reply the current thread id. */ if (strcmp ("qC", own_buf) == 0) { thread_ptr = all_threads.head; if (thread_ptr == NULL) strcpy (own_buf, "unset"); else sprintf (own_buf, "QC%x", thread_to_gdb_id ((struct thread_info *)thread_ptr)); return; } if (strcmp ("qSymbol::", own_buf) == 0) { if (the_target->look_up_symbols != NULL) (*the_target->look_up_symbols) (); strcpy (own_buf, "OK"); return; } if (strcmp ("qfThreadInfo", own_buf) == 0) { thread_ptr = all_threads.head; sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr)); thread_ptr = thread_ptr->next; return; } if (strcmp ("qsThreadInfo", own_buf) == 0) { if (thread_ptr != NULL) { sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr)); thread_ptr = thread_ptr->next; return; } else { sprintf (own_buf, "l"); return; } } if (the_target->read_offsets != NULL && strcmp ("qOffsets", own_buf) == 0) { CORE_ADDR text, data; if (the_target->read_offsets (&text, &data)) sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX", (long)text, (long)data, (long)data); else write_enn (own_buf); return; } if (the_target->qxfer_spu != NULL && strncmp ("qXfer:spu:read:", own_buf, 15) == 0) { char *annex; int n; unsigned int len; CORE_ADDR ofs; unsigned char *spu_buf; strcpy (own_buf, "E00"); if (decode_xfer_read (own_buf + 15, &annex, &ofs, &len) < 0) return; if (len > PBUFSIZ - 2) len = PBUFSIZ - 2; spu_buf = malloc (len + 1); if (!spu_buf) return; n = (*the_target->qxfer_spu) (annex, spu_buf, NULL, ofs, len + 1); if (n < 0) write_enn (own_buf); else if (n > len) *new_packet_len_p = write_qxfer_response (own_buf, spu_buf, len, 1); else *new_packet_len_p = write_qxfer_response (own_buf, spu_buf, n, 0); free (spu_buf); return; } if (the_target->qxfer_spu != NULL && strncmp ("qXfer:spu:write:", own_buf, 16) == 0) { char *annex; int n; unsigned int len; CORE_ADDR ofs; unsigned char *spu_buf; strcpy (own_buf, "E00"); spu_buf = malloc (packet_len - 15); if (!spu_buf) return; if (decode_xfer_write (own_buf + 16, packet_len - 16, &annex, &ofs, &len, spu_buf) < 0) { free (spu_buf); return; } n = (*the_target->qxfer_spu) (annex, NULL, (unsigned const char *)spu_buf, ofs, len); if (n < 0) write_enn (own_buf); else sprintf (own_buf, "%x", n); free (spu_buf); return; } if (the_target->read_auxv != NULL && strncmp ("qXfer:auxv:read:", own_buf, 16) == 0) { unsigned char *data; int n; CORE_ADDR ofs; unsigned int len; char *annex; /* Reject any annex; grab the offset and length. */ if (decode_xfer_read (own_buf + 16, &annex, &ofs, &len) < 0 || annex[0] != '\0') { strcpy (own_buf, "E00"); return; } /* Read one extra byte, as an indicator of whether there is more. */ if (len > PBUFSIZ - 2) len = PBUFSIZ - 2; data = malloc (len + 1); n = (*the_target->read_auxv) (ofs, data, len + 1); if (n < 0) write_enn (own_buf); else if (n > len) *new_packet_len_p = write_qxfer_response (own_buf, data, len, 1); else *new_packet_len_p = write_qxfer_response (own_buf, data, n, 0); free (data); return; } if (strncmp ("qXfer:features:read:", own_buf, 20) == 0) { CORE_ADDR ofs; unsigned int len, total_len; const char *document; char *annex; /* Check for support. */ document = get_features_xml ("target.xml"); if (document == NULL) { own_buf[0] = '\0'; return; } /* Grab the annex, offset, and length. */ if (decode_xfer_read (own_buf + 20, &annex, &ofs, &len) < 0) { strcpy (own_buf, "E00"); return; } /* Now grab the correct annex. */ document = get_features_xml (annex); if (document == NULL) { strcpy (own_buf, "E00"); return; } total_len = strlen (document); if (len > PBUFSIZ - 2) len = PBUFSIZ - 2; if (ofs > total_len) write_enn (own_buf); else if (len < total_len - ofs) *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, len, 1); else *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, total_len - ofs, 0); return; } if (strncmp ("qXfer:libraries:read:", own_buf, 21) == 0) { CORE_ADDR ofs; unsigned int len, total_len; char *document, *p; struct inferior_list_entry *dll_ptr; char *annex; /* Reject any annex; grab the offset and length. */ if (decode_xfer_read (own_buf + 21, &annex, &ofs, &len) < 0 || annex[0] != '\0') { strcpy (own_buf, "E00"); return; } /* Over-estimate the necessary memory. Assume that every character in the library name must be escaped. */ total_len = 64; for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next) total_len += 128 + 6 * strlen (((struct dll_info *) dll_ptr)->name); document = malloc (total_len); strcpy (document, "<library-list>\n"); p = document + strlen (document); for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next) { struct dll_info *dll = (struct dll_info *) dll_ptr; char *name; strcpy (p, " <library name=\""); p = p + strlen (p); name = xml_escape_text (dll->name); strcpy (p, name); free (name); p = p + strlen (p); strcpy (p, "\"><segment address=\""); p = p + strlen (p); sprintf (p, "0x%lx", (long) dll->base_addr); p = p + strlen (p); strcpy (p, "\"/></library>\n"); p = p + strlen (p); } strcpy (p, "</library-list>\n"); total_len = strlen (document); if (len > PBUFSIZ - 2) len = PBUFSIZ - 2; if (ofs > total_len) write_enn (own_buf); else if (len < total_len - ofs) *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, len, 1); else *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, total_len - ofs, 0); free (document); return; } /* Protocol features query. */ if (strncmp ("qSupported", own_buf, 10) == 0 && (own_buf[10] == ':' || own_buf[10] == '\0')) { sprintf (own_buf, "PacketSize=%x", PBUFSIZ - 1); #if !defined (NO_PASS_SIGNALS) strcat (own_buf, ";QPassSignals+", PBUFSIZ - 1); #endif #if !defined (NO_LIBRARIES) /* We do not have any hook to indicate whether the target backend supports qXfer:libraries:read, so always report it. */ strcat (own_buf, ";qXfer:libraries:read+"); #endif strcat (own_buf, ";qXfer:memory map:read+"); if (the_target->read_auxv != NULL) strcat (own_buf, ";qXfer:auxv:read+"); if (the_target->qxfer_spu != NULL) strcat (own_buf, ";qXfer:spu:read+;qXfer:spu:write+"); if (get_features_xml ("target.xml") != NULL) strcat (own_buf, ";qXfer:features:read+"); return; } /* Thread-local storage support. */ if (the_target->get_tls_address != NULL && strncmp ("qGetTLSAddr:", own_buf, 12) == 0) { char *p = own_buf + 12; CORE_ADDR parts[3], address = 0; int i, err; for (i = 0; i < 3; i++) { char *p2; int len; if (p == NULL) break; p2 = strchr (p, ','); if (p2) { len = p2 - p; p2++; } else { len = strlen (p); p2 = NULL; } decode_address (&parts[i], p, len); p = p2; } if (p != NULL || i < 3) err = 1; else { struct thread_info *thread = gdb_id_to_thread (parts[0]); if (thread == NULL) err = 2; else err = the_target->get_tls_address (thread, parts[1], parts[2], &address); } if (err == 0) { sprintf (own_buf, "%llx", address); return; } else if (err > 0) { write_enn (own_buf); return; } /* Otherwise, pretend we do not understand this packet. */ } /* Handle "monitor" commands. */ if (strncmp ("qRcmd,", own_buf, 6) == 0) { char *mon = malloc (PBUFSIZ); int len = strlen (own_buf + 6); if ((len % 1) != 0 || unhexify (mon, own_buf + 6, len / 2) != len / 2) { write_enn (own_buf); free (mon); return; } mon[len / 2] = '\0'; write_ok (own_buf); if (strcmp (mon, "set debug 1") == 0) { debug_threads = 1; monitor_output ("Debug output enabled.\n"); } else if (strcmp (mon, "set debug 0") == 0) { debug_threads = 0; monitor_output ("Debug output disabled.\n"); } else if (strcmp (mon, "set remote-debug 1") == 0) { remote_debug = 1; monitor_output ("Protocol debug output enabled.\n"); } else if (strcmp (mon, "set remote-debug 0") == 0) { remote_debug = 0; monitor_output ("Protocol debug output disabled.\n"); } else if (strcmp (mon, "help") == 0) monitor_show_help (); else { int ok = 0; if (the_target->commands) ok = (*the_target->commands) (mon, len); else monitor_output ("Unknown monitor command.\n\n"); if (!ok) { monitor_show_help (); write_enn (own_buf); } } free (mon); return; } /* Otherwise we didn't know what packet it was. Say we didn't understand it. */ own_buf[0] = 0; }
static bool monitor_process_input(struct monitor * mon, int c) { struct dmon_comm * comm = mon->comm; switch (c) { #if (BOOT_ENABLE_GDB) case '+': dbgmon_exec(gdb_bootstrap); break; #endif #if (BOOT_ENABLE_THIRD) case '~': dbgmon_exec(third_bootstrap); break; #endif #if (MONITOR_APPTERM_ENABLE) case CTRL_C: dmprintf(comm, "^C\r\n"); dbgmon_soft_reset(); break; #endif #if (MONITOR_SELFTEST_ENABLE) case CTRL_E: dmprintf(comm, "^E\r\n"); dbgmon_soft_reset(); dbgmon_exec(selftest_bootstrap); break; #endif #if (MONITOR_CONFIGURE_ENABLE) case CTRL_K: dmprintf(comm, "^K\r\n"); dbgmon_soft_reset(); this_board.configure(comm); break; #endif #if (MONITOR_UPGRADE_ENABLE) case CTRL_FS: dbgmon_soft_reset(); dmprintf(comm, "^\\\r\nConfirm [y]? "); if (dmgetc(comm) == 'y') { this_board.upgrade(comm); dmprintf(comm, "Failed !!!\r\n"); } else { dmprintf(comm, "\r\n"); } break; #endif #if (MONITOR_THREADINFO_ENABLE) case CTRL_N: mon->thread_id = __thinkos_thread_getnext(mon->thread_id); if (mon->thread_id == - 1) mon->thread_id = __thinkos_thread_getnext(mon->thread_id); dmprintf(comm, "Thread = %d\r\n", mon->thread_id); dmon_print_thread(comm, mon->thread_id); break; case CTRL_O: dmprintf(comm, "^O\r\n"); dmprintf(comm, s_hr); dmon_print_osinfo(comm); break; case CTRL_P: dmprintf(comm, "^P\r\n"); monitor_pause_all(comm); break; case CTRL_Q: dmprintf(comm, "^Q\r\n"); dbgmon_exec(monitor_task); break; case CTRL_R: dmprintf(comm, "^R\r\n"); monitor_resume_all(comm); break; #endif #if (MONITOR_DUMPMEM_ENABLE) case CTRL_S: dmprintf(comm, "^S\r\n"); monitor_show_mem(mon); break; #endif #if (MONITOR_THREADINFO_ENABLE) case CTRL_T: dmon_print_thread(comm, mon->thread_id); break; #endif #if (MONITOR_STACKUSAGE_ENABLE) case CTRL_U: dmon_print_stack_usage(comm); break; #endif case CTRL_V: monitor_show_help(comm); break; #if (MONITOR_FAULT_ENABLE) case CTRL_X: monitor_print_fault(comm); break; #endif case CTRL_Y: dmprintf(comm, "^\\\r\nConfirm [y]? "); if (dmgetc(comm) == 'y') { monitor_ymodem_recv(comm, this_board.application.start_addr, this_board.application.block_size); } else { dmprintf(comm, "\r\n"); } break; #if (MONITOR_APPWIPE_ENABLE) case CTRL_W: dmprintf(comm, "^W\r\n"); monitor_app_erase(comm, this_board.application.start_addr, this_board.application.block_size); break; #endif #if (MONITOR_APPRESTART_ENABLE) case CTRL_Z: dmprintf(comm, "^Z\r\n"); dbgmon_soft_reset(); monitor_exec(comm, this_board.application.start_addr); break; #endif #if (MONITOR_WATCHPOINT_ENABLE) case CTRL_GS: dmprintf(comm, "^]\r\n"); monitor_watchpoint(mon); break; #endif default: return false; } return true; }