*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
*/
#include "config.h"
#include "qemu-common.h"
-1, /* SIGLOST */
TARGET_SIGUSR1,
TARGET_SIGUSR2,
+#ifdef TARGET_SIGPWR
TARGET_SIGPWR,
+#else
+ -1,
+#endif
-1, /* SIGPOLL */
-1,
-1,
-1,
-1,
-1,
+#ifdef __SIGRTMIN
__SIGRTMIN + 1,
__SIGRTMIN + 2,
__SIGRTMIN + 3,
-1,
-1,
-1
+#endif
};
#else
/* In system mode we only need SIGINT and SIGTRAP; other signals
#elif defined (TARGET_PPC)
+/* Old gdb always expects FP registers. Newer (xml-aware) gdb only
+ expects whatever the target description contains. Due to a
+ historical mishap the FP registers appear in between core integer
+ regs and PC, MSR, CR, and so forth. We hack round this by giving the
+ FP regs zero size when talking to a newer gdb. */
#define NUM_CORE_REGS 71
+#if defined (TARGET_PPC64)
+#define GDB_CORE_XML "power64-core.xml"
+#else
+#define GDB_CORE_XML "power-core.xml"
+#endif
static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
{
GET_REGL(env->gpr[n]);
} else if (n < 64) {
/* fprs */
+ if (gdb_has_xml)
+ return 0;
stfq_p(mem_buf, env->fpr[n-32]);
return 8;
} else {
case 67: GET_REGL(env->lr);
case 68: GET_REGL(env->ctr);
case 69: GET_REGL(env->xer);
- case 70: GET_REG32(0); /* fpscr */
+ case 70:
+ {
+ if (gdb_has_xml)
+ return 0;
+ GET_REG32(0); /* fpscr */
+ }
}
}
return 0;
return sizeof(target_ulong);
} else if (n < 64) {
/* fprs */
+ if (gdb_has_xml)
+ return 0;
env->fpr[n-32] = ldfq_p(mem_buf);
return 8;
} else {
return sizeof(target_ulong);
case 70:
/* fpscr */
+ if (gdb_has_xml)
+ return 0;
return 4;
}
}
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
#define NUM_CORE_REGS 86
#else
-#define NUM_CORE_REGS 73
+#define NUM_CORE_REGS 72
#endif
#ifdef TARGET_ABI32
case 69: GET_REGA(env->npc);
case 70: GET_REGA(env->fsr);
case 71: GET_REGA(0); /* csr */
- case 72: GET_REGA(0);
+ default: GET_REGA(0);
}
#else
if (n < 64) {
}
#ifndef CONFIG_USER_ONLY
-static void gdb_vm_stopped(void *opaque, int reason)
+static void gdb_vm_state_change(void *opaque, int running, int reason)
{
GDBState *s = gdbserver_state;
CPUState *env = s->c_cpu;
const char *type;
int ret;
- if (s->state == RS_SYSCALL)
+ if (running || (reason != EXCP_DEBUG && reason != EXCP_INTERRUPT) ||
+ s->state == RS_SYSCALL)
return;
/* disable single step if it was enable */
}
tb_flush(env);
ret = GDB_SIGNAL_TRAP;
- } else if (reason == EXCP_INTERRUPT) {
- ret = GDB_SIGNAL_INT;
} else {
- ret = 0;
+ ret = GDB_SIGNAL_INT;
}
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, env->cpu_index+1);
put_packet(s, buf);
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
s = qemu_mallocz(sizeof(GDBState));
- if (!s) {
- errno = ENOMEM;
- perror("accept");
- return;
- }
memset (s, 0, sizeof (GDBState));
s->c_cpu = first_cpu;
void gdbserver_fork(CPUState *env)
{
GDBState *s = gdbserver_state;
- if (s->fd < 0)
+ if (gdbserver_fd < 0 || s->fd < 0)
return;
close(s->fd);
s->fd = -1;
port = gdbstub_port_name;
}
- chr = qemu_chr_open("gdb", port);
+ chr = qemu_chr_open("gdb", port, NULL);
if (!chr)
return -1;
s = qemu_mallocz(sizeof(GDBState));
- if (!s) {
- return -1;
- }
s->c_cpu = first_cpu;
s->g_cpu = first_cpu;
s->chr = chr;
gdbserver_state = s;
qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
gdb_chr_event, NULL);
- qemu_add_vm_stop_handler(gdb_vm_stopped, NULL);
+ qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
return 0;
}
#endif