⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdbstub.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * gdb server stub *  * Copyright (c) 2003-2005 Fabrice Bellard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * 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 */#ifdef CONFIG_USER_ONLY#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <string.h>#include <errno.h>#include <unistd.h>#include "qemu.h"#else#include "vl.h"#endif#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <signal.h>//#define DEBUG_GDBenum RSState {    RS_IDLE,    RS_GETLINE,    RS_CHKSUM1,    RS_CHKSUM2,};/* XXX: This is not thread safe.  Do we care?  */static int gdbserver_fd = -1;typedef struct GDBState {    CPUState *env; /* current CPU */    enum RSState state; /* parsing state */    int fd;    char line_buf[4096];    int line_buf_index;    int line_csum;#ifdef CONFIG_USER_ONLY    int running_state;#endif} GDBState;#ifdef CONFIG_USER_ONLY/* XXX: remove this hack.  */static GDBState gdbserver_state;#endifstatic int get_char(GDBState *s){    uint8_t ch;    int ret;    for(;;) {        ret = read(s->fd, &ch, 1);        if (ret < 0) {            if (errno != EINTR && errno != EAGAIN)                return -1;        } else if (ret == 0) {            return -1;        } else {            break;        }    }    return ch;}static void put_buffer(GDBState *s, const uint8_t *buf, int len){    int ret;    while (len > 0) {        ret = write(s->fd, buf, len);        if (ret < 0) {            if (errno != EINTR && errno != EAGAIN)                return;        } else {            buf += ret;            len -= ret;        }    }}static inline int fromhex(int v){    if (v >= '0' && v <= '9')        return v - '0';    else if (v >= 'A' && v <= 'F')        return v - 'A' + 10;    else if (v >= 'a' && v <= 'f')        return v - 'a' + 10;    else        return 0;}static inline int tohex(int v){    if (v < 10)        return v + '0';    else        return v - 10 + 'a';}static void memtohex(char *buf, const uint8_t *mem, int len){    int i, c;    char *q;    q = buf;    for(i = 0; i < len; i++) {        c = mem[i];        *q++ = tohex(c >> 4);        *q++ = tohex(c & 0xf);    }    *q = '\0';}static void hextomem(uint8_t *mem, const char *buf, int len){    int i;    for(i = 0; i < len; i++) {        mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);        buf += 2;    }}/* return -1 if error, 0 if OK */static int put_packet(GDBState *s, char *buf){    char buf1[3];    int len, csum, ch, i;#ifdef DEBUG_GDB    printf("reply='%s'\n", buf);#endif    for(;;) {        buf1[0] = '$';        put_buffer(s, buf1, 1);        len = strlen(buf);        put_buffer(s, buf, len);        csum = 0;        for(i = 0; i < len; i++) {            csum += buf[i];        }        buf1[0] = '#';        buf1[1] = tohex((csum >> 4) & 0xf);        buf1[2] = tohex((csum) & 0xf);        put_buffer(s, buf1, 3);        ch = get_char(s);        if (ch < 0)            return -1;        if (ch == '+')            break;    }    return 0;}#if defined(TARGET_I386)static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf){    uint32_t *registers = (uint32_t *)mem_buf;    int i, fpus;    for(i = 0; i < 8; i++) {        registers[i] = env->regs[i];    }    registers[8] = env->eip;    registers[9] = env->eflags;    registers[10] = env->segs[R_CS].selector;    registers[11] = env->segs[R_SS].selector;    registers[12] = env->segs[R_DS].selector;    registers[13] = env->segs[R_ES].selector;    registers[14] = env->segs[R_FS].selector;    registers[15] = env->segs[R_GS].selector;    /* XXX: convert floats */    for(i = 0; i < 8; i++) {        memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10);    }    registers[36] = env->fpuc;    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;    registers[37] = fpus;    registers[38] = 0; /* XXX: convert tags */    registers[39] = 0; /* fiseg */    registers[40] = 0; /* fioff */    registers[41] = 0; /* foseg */    registers[42] = 0; /* fooff */    registers[43] = 0; /* fop */        for(i = 0; i < 16; i++)        tswapls(&registers[i]);    for(i = 36; i < 44; i++)        tswapls(&registers[i]);    return 44 * 4;}static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size){    uint32_t *registers = (uint32_t *)mem_buf;    int i;    for(i = 0; i < 8; i++) {        env->regs[i] = tswapl(registers[i]);    }    env->eip = tswapl(registers[8]);    env->eflags = tswapl(registers[9]);#if defined(CONFIG_USER_ONLY)#define LOAD_SEG(index, sreg)\            if (tswapl(registers[index]) != env->segs[sreg].selector)\                cpu_x86_load_seg(env, sreg, tswapl(registers[index]));            LOAD_SEG(10, R_CS);            LOAD_SEG(11, R_SS);            LOAD_SEG(12, R_DS);            LOAD_SEG(13, R_ES);            LOAD_SEG(14, R_FS);            LOAD_SEG(15, R_GS);#endif}#elif defined (TARGET_PPC)static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf){    uint32_t *registers = (uint32_t *)mem_buf, tmp;    int i;    /* fill in gprs */    for(i = 0; i < 32; i++) {        registers[i] = tswapl(env->gpr[i]);    }    /* fill in fprs */    for (i = 0; i < 32; i++) {        registers[(i * 2) + 32] = tswapl(*((uint32_t *)&env->fpr[i]));	registers[(i * 2) + 33] = tswapl(*((uint32_t *)&env->fpr[i] + 1));    }    /* nip, msr, ccr, lnk, ctr, xer, mq */    registers[96] = tswapl(env->nip);    registers[97] = tswapl(do_load_msr(env));    tmp = 0;    for (i = 0; i < 8; i++)        tmp |= env->crf[i] << (32 - ((i + 1) * 4));    registers[98] = tswapl(tmp);    registers[99] = tswapl(env->lr);    registers[100] = tswapl(env->ctr);    registers[101] = tswapl(do_load_xer(env));    registers[102] = 0;    return 103 * 4;}static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size){    uint32_t *registers = (uint32_t *)mem_buf;    int i;    /* fill in gprs */    for (i = 0; i < 32; i++) {        env->gpr[i] = tswapl(registers[i]);    }    /* fill in fprs */    for (i = 0; i < 32; i++) {        *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);	*((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);    }    /* nip, msr, ccr, lnk, ctr, xer, mq */    env->nip = tswapl(registers[96]);    do_store_msr(env, tswapl(registers[97]));    registers[98] = tswapl(registers[98]);    for (i = 0; i < 8; i++)        env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;    env->lr = tswapl(registers[99]);    env->ctr = tswapl(registers[100]);    do_store_xer(env, tswapl(registers[101]));}#elif defined (TARGET_SPARC)static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf){    target_ulong *registers = (target_ulong *)mem_buf;    int i;    /* fill in g0..g7 */    for(i = 0; i < 8; i++) {        registers[i] = tswapl(env->gregs[i]);    }    /* fill in register window */    for(i = 0; i < 24; i++) {        registers[i + 8] = tswapl(env->regwptr[i]);    }    /* fill in fprs */    for (i = 0; i < 32; i++) {        registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i]));    }#ifndef TARGET_SPARC64    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */    registers[64] = tswapl(env->y);    {	target_ulong tmp;	tmp = GET_PSR(env);	registers[65] = tswapl(tmp);    }    registers[66] = tswapl(env->wim);    registers[67] = tswapl(env->tbr);    registers[68] = tswapl(env->pc);    registers[69] = tswapl(env->npc);    registers[70] = tswapl(env->fsr);    registers[71] = 0; /* csr */    registers[72] = 0;    return 73 * sizeof(target_ulong);#else    for (i = 0; i < 32; i += 2) {        registers[i/2 + 64] = tswapl(*((uint64_t *)&env->fpr[i]));    }    registers[81] = tswapl(env->pc);    registers[82] = tswapl(env->npc);    registers[83] = tswapl(env->tstate[env->tl]);    registers[84] = tswapl(env->fsr);    registers[85] = tswapl(env->fprs);    registers[86] = tswapl(env->y);    return 87 * sizeof(target_ulong);#endif}static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size){    target_ulong *registers = (target_ulong *)mem_buf;    int i;    /* fill in g0..g7 */    for(i = 0; i < 7; i++) {        env->gregs[i] = tswapl(registers[i]);    }    /* fill in register window */    for(i = 0; i < 24; i++) {        env->regwptr[i] = tswapl(registers[i + 8]);    }    /* fill in fprs */    for (i = 0; i < 32; i++) {        *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]);    }#ifndef TARGET_SPARC64    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */    env->y = tswapl(registers[64]);    PUT_PSR(env, tswapl(registers[65]));    env->wim = tswapl(registers[66]);    env->tbr = tswapl(registers[67]);    env->pc = tswapl(registers[68]);    env->npc = tswapl(registers[69]);    env->fsr = tswapl(registers[70]);#else    for (i = 0; i < 32; i += 2) {	uint64_t tmp;	tmp = tswapl(registers[i/2 + 64]) << 32;	tmp |= tswapl(registers[i/2 + 64 + 1]);        *((uint64_t *)&env->fpr[i]) = tmp;    }    env->pc = tswapl(registers[81]);    env->npc = tswapl(registers[82]);    env->tstate[env->tl] = tswapl(registers[83]);    env->fsr = tswapl(registers[84]);    env->fprs = tswapl(registers[85]);    env->y = tswapl(registers[86]);#endif}#elif defined (TARGET_ARM)static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf){    int i;    uint8_t *ptr;    ptr = mem_buf;    /* 16 core integer registers (4 bytes each).  */    for (i = 0; i < 16; i++)      {        *(uint32_t *)ptr = tswapl(env->regs[i]);        ptr += 4;      }    /* 8 FPA registers (12 bytes each), FPS (4 bytes).       Not yet implemented.  */    memset (ptr, 0, 8 * 12 + 4);    ptr += 8 * 12 + 4;    /* CPSR (4 bytes).  */    *(uint32_t *)ptr = tswapl (cpsr_read(env));    ptr += 4;    return ptr - mem_buf;}static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size){    int i;    uint8_t *ptr;    ptr = mem_buf;    /* Core integer registers.  */    for (i = 0; i < 16; i++)      {        env->regs[i] = tswapl(*(uint32_t *)ptr);        ptr += 4;      }    /* Ignore FPA regs and scr.  */    ptr += 8 * 12 + 4;    cpsr_write (env, tswapl(*(uint32_t *)ptr), 0xffffffff);}#elif defined (TARGET_MIPS)static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf){    int i;    uint8_t *ptr;    ptr = mem_buf;    for (i = 0; i < 32; i++)      {        *(uint32_t *)ptr = tswapl(env->gpr[i]);        ptr += 4;      }    *(uint32_t *)ptr = tswapl(env->CP0_Status);    ptr += 4;    *(uint32_t *)ptr = tswapl(env->LO);    ptr += 4;    *(uint32_t *)ptr = tswapl(env->HI);    ptr += 4;    *(uint32_t *)ptr = tswapl(env->CP0_BadVAddr);    ptr += 4;    *(uint32_t *)ptr = tswapl(env->CP0_Cause);    ptr += 4;    *(uint32_t *)ptr = tswapl(env->PC);    ptr += 4;    /* 32 FP registers, fsr, fir, fp.  Not yet implemented.  */    return ptr - mem_buf;}static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size){    int i;    uint8_t *ptr;    ptr = mem_buf;    for (i = 0; i < 32; i++)      {        env->gpr[i] = tswapl(*(uint32_t *)ptr);        ptr += 4;      }    env->CP0_Status = tswapl(*(uint32_t *)ptr);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -