24 #include <sys/types.h>
27 #include <sys/socket.h>
29 #include <netinet/in.h>
32 #include <libvirt/libvirt.h>
33 #include <libvirt/libvirt-qemu.h>
71 virConnectPtr qemu_libvirt_conn;
72 virDomainPtr qemu_libvirt_dom;
82 qstate = calloc(1,
sizeof(*qstate));
86 verror(
"memcache already in use!\n");
94 verror(
"could not stat QEMU mem-path file %s: %s (%d)!\n",
99 qstate->ram_mmap_size = sbuf.st_size;
101 if (qstate->ram_mmap_fd < 0) {
102 verror(
"could not open QEMU mem-path file %s: %s (%d)!\n",
108 MAP_SHARED,qstate->ram_mmap_fd,0);
109 if (qstate->ram_mmap == (
void *) -1) {
110 verror(
"could not mmap QEMU mem-path file %s: %s (%d)!\n",
117 qstate->qemu_qmp_fd = -1;
118 gstate->hops_priv = qstate;
124 g_hash_table_insert(target->
config,
125 strdup(
"OS_EMULATE_USERSPACE_EXCEPTIONS"),
128 #ifdef ENABLE_LIBVIRT
129 qstate->qemu_libvirt_conn = 0;
130 qstate->qemu_libvirt_dom = 0;
159 rc = recv(fd,bufp + count,rlen - count,
160 (i == 0 && blockfirst) ? 0 : MSG_DONTWAIT);
163 if (errno == EAGAIN || errno == EWOULDBLOCK) {
167 verror(
"recv: %s (%d)\n",strerror(errno),errno);
172 verror(
"qmp server disconnected unexpectedly!\n");
176 count += (
unsigned int)rc;
202 struct sockaddr_in sin;
203 struct sockaddr_in6 sin6;
204 char *cmd =
"{ \"execute\": \"qmp_capabilities\" }";
209 if (gspec->qemu_qmp_hostname || gspec->qemu_qmp_port > 0) {
210 if (!gspec->qemu_qmp_hostname)
211 gspec->qemu_qmp_hostname = strdup(
"localhost");
212 if (gspec->qemu_qmp_port < 0)
213 gspec->qemu_qmp_port = 1235;
215 he = gethostbyname(gspec->qemu_qmp_hostname);
217 verror(
"gethostbyname(%s): %s (%d)!",gspec->qemu_qmp_hostname,
222 addrtype = he->h_addrtype;
223 if (addrtype == AF_INET) {
224 memcpy(&sin.sin_addr,he->h_addr,he->h_length);
228 sin.sin_port = htons(gspec->qemu_qmp_port);
229 sin.sin_family = addrtype;
231 else if (addrtype == AF_INET6) {
232 memcpy(&sin6.sin6_addr,he->h_addr,he->h_length);
235 sin6.sin6_port = htons(gspec->qemu_qmp_port);
236 sin6.sin6_family = addrtype;
239 verror(
"unknown addrtype %d for hostname %s!\n",
240 addrtype,gspec->qemu_qmp_hostname);
251 qstate->
qemu_qmp_fd = socket(addrtype,SOCK_STREAM,0);
253 verror(
"socket(): %s\n",strerror(errno));
257 if (connect(qstate->
qemu_qmp_fd,(
struct sockaddr *)dst,dlen) < 0) {
258 verror(
"connect(%s): %s\n",he->h_name,strerror(errno));
263 "connected to tcp socket %s:%d (fd %d)\n",
264 he->h_name,gspec->qemu_qmp_port,qstate->
qemu_qmp_fd);
282 #ifdef ENABLE_LIBVIRT
283 else if (gspec->qemu_libvirt_domain) {
284 qstate->qemu_libvirt_conn = virConnectOpen(NULL);
285 if (!qstate->qemu_libvirt_conn)
287 qstate->qemu_libvirt_dom =
288 virDomainLookupByName(qstate->qemu_libvirt_conn,
289 gspec->qemu_libvirt_domain);
290 if (!qstate->qemu_libvirt_dom) {
291 verror(
"could not find libvirt domain '%s'!\n",
292 gspec->qemu_libvirt_domain);
294 errno = ECONNREFUSED;
295 virConnectClose(qstate->qemu_libvirt_conn);
296 qstate->qemu_libvirt_conn = NULL;
352 char *cmd =
"{ \"execute\": \"human-monitor-command\","
353 " \"arguments\": { \"command-line\": \"info registers\" } }\n";
359 if (qstate->qemu_qmp_fd > 0) {
361 buf = malloc(bufsiz);
367 write(qstate->qemu_qmp_fd,cmd,strlen(cmd));
374 #ifdef ENABLE_LIBVIRT
375 else if (qstate->qemu_libvirt_conn) {
377 virDomainQemuMonitorCommand(qstate->qemu_libvirt_dom,cmd,&buf,0);
383 bufsiz = strlen(buf);
391 for (i = 0; i < bufsiz; ++i) {
392 if (buf[i] ==
'\r' || buf[i] ==
'\n')
397 idx = strstr(buf,
"GS =0000 ");
399 regval = (
REGVAL)strtoull(idx + strlen(
"GS =0000"),NULL,16);
409 idx = strstr(buf,
"CR0=");
411 regval = (
REGVAL)strtoull(idx + strlen(
"CR0="),NULL,16);
423 idx = strstr(buf,
"CR3=");
425 regval = (
REGVAL)strtoull(idx + strlen(
"CR3="),NULL,16);
437 idx = strstr(buf,
"CR4=");
439 regval = (
REGVAL)strtoull(idx + strlen(
"CR4="),NULL,16);
451 idx = strstr(buf,
"DR6=");
453 regval = (
REGVAL)strtoull(idx + strlen(
"DR6="),NULL,16);
465 idx = strstr(buf,
"EFER=");
467 regval = (
REGVAL)strtoull(idx + strlen(
"EFER="),NULL,16);
479 if (qstate->qemu_qmp_fd > 0)
489 unsigned long length,
490 unsigned char *buf) {
493 char *ram_mmap_start,*ram_mmap_end;
501 unsigned long plength = 0;
503 unsigned long alen = 0;
517 lbuf = malloc(length + 1);
522 ram_mmap_start = (
char *)mstate->
ram_mmap;
532 for (i = 0; length == 0 || plength < length; ++i) {
538 if (lbuf != (
char *)buf)
548 if (length > 0 && (plength + mlen) > length)
549 mlen = (length - plength);
551 mmap = ram_mmap_start + paddr;
555 if (mmap < ram_mmap_start || mmap >= ram_mmap_end) {
558 if (lbuf != (
char *)buf)
564 if (!buf && !length) {
566 lbuf = realloc(lbuf,alen);
570 memcpy(lbuf + plength,mmap,mlen);
573 if (!buf && !length) {
574 for (j = plength; j < (plength + mlen); ++j) {
578 if (j < (plength + mlen)) {
579 lbuf = realloc(lbuf,plength + j + 1);
590 return (
unsigned char *)lbuf;
595 unsigned long length,
596 unsigned char *buf) {
599 char *ram_mmap_start,*ram_mmap_end;
607 unsigned long plength = 0;
618 ram_mmap_start = (
char *)mstate->
ram_mmap;
628 for (i = 0; plength < length; ++i) {
642 if ((plength + mlen) > length)
643 mlen = (length - plength);
645 mmap = ram_mmap_start + paddr;
649 if (mmap < ram_mmap_start || mmap >= ram_mmap_end) {
656 memcpy(mmap,buf + plength,mlen);
668 unsigned char *lbuf = NULL;
683 lbuf = realloc(lbuf,lbuf_alen);
688 lbuf_alen - lbuf_len,lbuf + lbuf_len)) {
699 for (j = lbuf_len; j < lbuf_alen; ++j) {
706 lbuf = realloc(lbuf,j + 1);
710 lbuf_len = lbuf_alen;
713 lbuf = realloc(lbuf,lbuf_alen);
717 return (
unsigned char *)lbuf;
725 #define GDB_MAX_IO 1024
739 unsigned long length,
740 unsigned char *buf) {
744 unsigned long bread,left;
769 vwarn(
"could not load current thread; assuming tid %d is current!\n",
773 if (tthread->
tid != tid) {
774 verror(
"tid %d is not current nor global; cannot read!\n",tid);
785 buf = malloc(length);
789 while (bread < length) {
790 left = length - bread;
807 addr,length,strerror(errno),rc);
822 unsigned long length,
823 unsigned char *buf) {
826 unsigned long bwrote,left;
851 vwarn(
"could not load current thread; assuming tid %d is current!\n",
855 if (tthread->
tid != tid) {
856 verror(
"tid %d is not current nor global; cannot read!\n",tid);
864 while (bwrote < length) {
865 left = length - bwrote;
875 if (bwrote >= length)
882 addr,length,strerror(errno),rc);
916 vwarn(
"error while looking up vaddr 0x%"PRIxADDR" (for vaddr"
917 " 0x%"PRIxADDR") in memcache: %s (%d); trying full lookup!\n",
918 tvaddr,vaddr,strerror(errno),rc);
945 char *ram_mmap_start,*ram_mmap_end;
961 ram_mmap_start = (
char *)mstate->
ram_mmap + addr;
963 end = ram_mmap_start;
965 while (end >= (
char *)mstate->
ram_mmap && end < ram_mmap_end) {
971 mlen = end - ram_mmap_start;
972 retval = malloc(mlen + 1);
974 memcpy(retval,ram_mmap_start,mlen);
977 return (
unsigned char *)retval;
981 unsigned long length,
982 unsigned char *buf) {
985 char *ram_mmap_start,*ram_mmap_end;
996 ram_mmap_start = (
char *)mstate->
ram_mmap + paddr;
999 if (ram_mmap_start >= (
char *)mstate->
ram_mmap
1000 && (ram_mmap_start + length) < ram_mmap_end) {
1003 buf = malloc(length + 1);
1006 memcpy(buf,ram_mmap_start,length);
1009 verror(
"bad read paddr/length 0x%"PRIxADDR" %lu\n",paddr,length);
1014 return (
unsigned char *)buf;
1018 unsigned long length,
1019 unsigned char *buf) {
1022 char *ram_mmap_start,*ram_mmap_end;
1033 ram_mmap_start = (
char *)mstate->
ram_mmap + paddr;
1036 if (ram_mmap_start >= (
char *)mstate->
ram_mmap
1037 && (ram_mmap_start + length) < ram_mmap_end) {
1038 memcpy(ram_mmap_start,buf,length);
1042 verror(
"bad write paddr/length 0x%"PRIxADDR" %lu\n",paddr,length);
1052 if (qstate->qemu_qmp_fd > -1) {
1053 close(qstate->qemu_qmp_fd);
1054 qstate->qemu_qmp_fd = -1;
1056 #ifdef ENABLE_LIBVIRT
1057 else if (qstate->qemu_libvirt_conn) {
1058 qstate->qemu_libvirt_dom = 0;
1059 virConnectClose(qstate->qemu_libvirt_conn);
1060 qstate->qemu_libvirt_conn = 0;
1064 if (qstate->ram_mmap) {
1065 munmap(qstate->ram_mmap,qstate->ram_mmap_size);
1066 qstate->ram_mmap = NULL;
1067 qstate->ram_mmap_size = 0;
1068 close(qstate->ram_mmap_fd);
int target_arch_x86_v2p(struct target *target, ADDR pgd, ADDR virt, arch_x86_v2p_flags_t flags, ADDR *phys)
#define vwarnopt(level, area, flags, format,...)
target_personality_t personality
int gdb_helper_qemu_handle_exception_any(struct target *target)
int __recv_til_block(int fd, char *buf, unsigned int len, int blockfirst)
int regcache_init_reg(struct regcache *regcache, REG reg, REGVAL regval)
int gdb_rsp_write_mem(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
unsigned char * gdb_helper_qemu_read_tid(struct target *target, tid_t tid, ADDR pgd, ADDR addr, unsigned long length, unsigned char *buf)
#define verror(format,...)
unsigned char * gdb_helper_qemu_read_tid_mem_path(struct target *target, tid_t tid, ADDR pgd, ADDR addr, unsigned long length, unsigned char *buf)
unsigned long gdb_helper_qemu_write_phys(struct target *target, ADDR paddr, unsigned long length, unsigned char *buf)
int gdb_helper_qemu_attach(struct target *target)
unsigned char * gdb_helper_qemu_read_phys(struct target *target, ADDR paddr, unsigned long length, unsigned char *buf)
#define vwarn(format,...)
struct target_thread * target_load_current_thread(struct target *target, int force)
int memcache_get_v2p(struct memcache *memcache, ADDR tag, ADDR va, ADDR *pa, void **tag_priv)
int gdb_helper_qemu_handle_exception_ours(struct target *target)
int gdb_helper_qemu_addr_v2p(struct target *target, tid_t tid, ADDR pgd, ADDR vaddr, ADDR *paddr)
unsigned int clear_mem_caches_each_exception
int memcache_set_v2p(struct memcache *memcache, ADDR tag, ADDR va, ADDR pa)
void * mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
struct memcache * memcache
unsigned long gdb_helper_qemu_write_tid_mem_path(struct target *target, tid_t tid, ADDR pgd, ADDR addr, unsigned long length, unsigned char *buf)
unsigned char * gdb_helper_qemu_read_v_str(struct target *target, tid_t tid, ADDR pgd, ADDR addr)
#define REG_X86_64_MSR_EFER
#define vdebug(devel, areas, flags, format,...)
int memcache_invalidate_all(struct memcache *memcache)
struct gdb_helper_ops gdb_helper_ops_qemu
unsigned long gdb_helper_qemu_write_tid(struct target *target, tid_t tid, ADDR pgd, ADDR addr, unsigned long length, unsigned char *buf)
int gdb_rsp_read_mem(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
int gdb_helper_qemu_fini(struct target *target)
int gdb_helper_qemu_load_machine(struct target *target, struct regcache *regcache)
int gdb_helper_qemu_init(struct target *target)
#define REG_X86_64_GS_BASE
struct memcache * memcache_create(unsigned long int max_v2p, unsigned long int max_mmap_size, memcache_tag_priv_dtor pdtor)
void memcache_inc_ticks(struct memcache *memcache, unsigned int new_ticks)
struct target_spec * spec
unsigned long ram_mmap_size
unsigned char * gdb_helper_qemu_read_phys_str(struct target *target, ADDR addr)
int gdb_helper_qemu_handle_pause(struct target *target)
int(* init)(struct target *target)