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) {
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')
398 idx = strstr(buf,
"GS =0000 ");
400 regval = (
REGVAL)strtoull(idx + strlen(
"GS =0000"),NULL,16);
409 if (qstate->qemu_qmp_fd > 0) {
416 idx = strstr(buf,
"CR0=");
418 regval = (
REGVAL)strtoull(idx + strlen(
"CR0="),NULL,16);
430 if (qstate->qemu_qmp_fd > 0) {
436 idx = strstr(buf,
"CR3=");
438 regval = (
REGVAL)strtoull(idx + strlen(
"CR3="),NULL,16);
450 idx = strstr(buf,
"CR4=");
452 regval = (
REGVAL)strtoull(idx + strlen(
"CR4="),NULL,16);
464 idx = strstr(buf,
"DR6=");
466 regval = (
REGVAL)strtoull(idx + strlen(
"DR6="),NULL,16);
478 idx = strstr(buf,
"EFER=");
480 regval = (
REGVAL)strtoull(idx + strlen(
"EFER="),NULL,16);
492 if (qstate->qemu_qmp_fd > 0)
502 unsigned long length,
503 unsigned char *buf) {
506 char *ram_mmap_start,*ram_mmap_end;
514 unsigned long plength = 0;
516 unsigned long alen = 0;
530 lbuf =
malloc(length + 1);
535 ram_mmap_start = (
char *)mstate->
ram_mmap;
545 for (i = 0; length == 0 || plength < length; ++
i) {
551 if (lbuf != (
char *)buf)
561 if (length > 0 && (plength + mlen) > length)
562 mlen = (length - plength);
564 mmap = ram_mmap_start + paddr;
568 if (mmap < ram_mmap_start || mmap >= ram_mmap_end) {
571 if (lbuf != (
char *)buf)
577 if (!buf && !length) {
583 memcpy(lbuf + plength,mmap,mlen);
586 if (!buf && !length) {
587 for (j = plength; j < (plength + mlen); ++j) {
591 if (j < (plength + mlen)) {
592 lbuf =
realloc(lbuf,plength + j + 1);
603 return (
unsigned char *)lbuf;
608 unsigned long length,
609 unsigned char *buf) {
612 char *ram_mmap_start,*ram_mmap_end;
620 unsigned long plength = 0;
631 ram_mmap_start = (
char *)mstate->
ram_mmap;
641 for (i = 0; plength < length; ++
i) {
655 if ((plength + mlen) > length)
656 mlen = (length - plength);
658 mmap = ram_mmap_start + paddr;
662 if (mmap < ram_mmap_start || mmap >= ram_mmap_end) {
669 memcpy(mmap,buf + plength,mlen);
681 unsigned char *lbuf = NULL;
696 lbuf =
realloc(lbuf,lbuf_alen);
701 lbuf_alen - lbuf_len,lbuf + lbuf_len)) {
712 for (j = lbuf_len; j < lbuf_alen; ++j) {
723 lbuf_len = lbuf_alen;
726 lbuf =
realloc(lbuf,lbuf_alen);
730 return (
unsigned char *)lbuf;
738 #define GDB_MAX_IO 1024
752 unsigned long length,
753 unsigned char *buf) {
757 unsigned long bread,left;
782 vwarn(
"could not load current thread; assuming tid %d is current!\n",
786 if (tthread->
tid != tid) {
787 verror(
"tid %d is not current nor global; cannot read!\n",tid);
802 while (bread < length) {
803 left = length - bread;
820 addr,length,strerror(errno),rc);
835 unsigned long length,
836 unsigned char *buf) {
839 unsigned long bwrote,left;
864 vwarn(
"could not load current thread; assuming tid %d is current!\n",
868 if (tthread->
tid != tid) {
869 verror(
"tid %d is not current nor global; cannot read!\n",tid);
877 while (bwrote < length) {
878 left = length - bwrote;
888 if (bwrote >= length)
895 addr,length,strerror(errno),rc);
929 vwarn(
"error while looking up vaddr 0x%"PRIxADDR" (for vaddr"
930 " 0x%"PRIxADDR") in memcache: %s (%d); trying full lookup!\n",
931 tvaddr,vaddr,strerror(errno),rc);
958 char *ram_mmap_start,*ram_mmap_end;
974 ram_mmap_start = (
char *)mstate->
ram_mmap + addr;
976 end = ram_mmap_start;
978 while (end >= (
char *)mstate->
ram_mmap && end < ram_mmap_end) {
984 mlen = end - ram_mmap_start;
985 retval =
malloc(mlen + 1);
987 memcpy(retval,ram_mmap_start,mlen);
990 return (
unsigned char *)retval;
994 unsigned long length,
995 unsigned char *buf) {
998 char *ram_mmap_start,*ram_mmap_end;
1009 ram_mmap_start = (
char *)mstate->
ram_mmap + paddr;
1012 if (ram_mmap_start >= (
char *)mstate->
ram_mmap
1013 && (ram_mmap_start + length) < ram_mmap_end) {
1016 buf =
malloc(length + 1);
1019 memcpy(buf,ram_mmap_start,length);
1022 verror(
"bad read paddr/length 0x%"PRIxADDR" %lu\n",paddr,length);
1027 return (
unsigned char *)buf;
1031 unsigned long length,
1032 unsigned char *buf) {
1035 char *ram_mmap_start,*ram_mmap_end;
1046 ram_mmap_start = (
char *)mstate->
ram_mmap + paddr;
1049 if (ram_mmap_start >= (
char *)mstate->
ram_mmap
1050 && (ram_mmap_start + length) < ram_mmap_end) {
1051 memcpy(ram_mmap_start,buf,length);
1055 verror(
"bad write paddr/length 0x%"PRIxADDR" %lu\n",paddr,length);
1065 if (qstate->qemu_qmp_fd > -1) {
1066 close(qstate->qemu_qmp_fd);
1067 qstate->qemu_qmp_fd = -1;
1069 #ifdef ENABLE_LIBVIRT
1070 else if (qstate->qemu_libvirt_conn) {
1071 qstate->qemu_libvirt_dom = 0;
1072 virConnectClose(qstate->qemu_libvirt_conn);
1073 qstate->qemu_libvirt_conn = 0;
1077 if (qstate->ram_mmap) {
1078 munmap(qstate->ram_mmap,qstate->ram_mmap_size);
1079 qstate->ram_mmap = NULL;
1080 qstate->ram_mmap_size = 0;
1081 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
static uint64_t unsigned int i
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)
struct malloc_state * mstate
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)
void * realloc(void *ptr, size_t size)
void * calloc(size_t nmemb, size_t size)
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
void * malloc(size_t size)
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)
struct gdb_helper_ops gdb_helper_ops_qemu