void win32_xfer_shared_library (const char* so_name, CORE_ADDR load_addr, struct obstack *obstack) { char *p; obstack_grow_str (obstack, "<library name=\""); p = xml_escape_text (so_name); obstack_grow_str (obstack, p); xfree (p); obstack_grow_str (obstack, "\"><segment address=\"0x"); /* The symbols in a dll are offset by 0x1000, which is the the offset from 0 of the first byte in an image - because of the file header and the section alignment. */ p = paddr_nz (load_addr + 0x1000); obstack_grow_str (obstack, p); obstack_grow_str (obstack, "\"/></library>"); }
static void rs6000_xfer_shared_library (LdInfo *ldi, struct obstack *obstack) { const int arch64 = ARCH64 (); const char *archive_name = LDI_FILENAME (ldi, arch64); const char *member_name = archive_name + strlen (archive_name) + 1; CORE_ADDR text_addr, data_addr; ULONGEST text_size, data_size; char *p; if (arch64) { text_addr = ldi->l64.ldinfo_textorg; text_size = ldi->l64.ldinfo_textsize; data_addr = ldi->l64.ldinfo_dataorg; data_size = ldi->l64.ldinfo_datasize; } else { /* The text and data addresses are defined as pointers. To avoid sign-extending their value in the assignments below, we cast their value to unsigned long first. */ text_addr = (unsigned long) ldi->l32.ldinfo_textorg; text_size = ldi->l32.ldinfo_textsize; data_addr = (unsigned long) ldi->l32.ldinfo_dataorg; data_size = ldi->l32.ldinfo_datasize; } obstack_grow_str (obstack, "<library name=\""); p = xml_escape_text (archive_name); obstack_grow_str (obstack, p); xfree (p); obstack_grow_str (obstack, "\""); if (member_name[0] != '\0') { obstack_grow_str (obstack, " member=\""); p = xml_escape_text (member_name); obstack_grow_str (obstack, p); xfree (p); obstack_grow_str (obstack, "\""); } obstack_grow_str (obstack, " text_addr=\""); obstack_grow_str (obstack, core_addr_to_string (text_addr)); obstack_grow_str (obstack, "\""); obstack_grow_str (obstack, " text_size=\""); obstack_grow_str (obstack, pulongest (text_size)); obstack_grow_str (obstack, "\""); obstack_grow_str (obstack, " data_addr=\""); obstack_grow_str (obstack, core_addr_to_string (data_addr)); obstack_grow_str (obstack, "\""); obstack_grow_str (obstack, " data_size=\""); obstack_grow_str (obstack, pulongest (data_size)); obstack_grow_str (obstack, "\""); obstack_grow_str (obstack, "></library>"); }
/* 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; }