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

📄 gdbstub.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
            }        }        break;    case 'g':        reg_size = cpu_gdb_read_registers(env, mem_buf);        memtohex(buf, mem_buf, reg_size);        put_packet(s, buf);        break;    case 'G':        registers = (void *)mem_buf;        len = strlen(p) / 2;        hextomem((uint8_t *)registers, p, len);        cpu_gdb_write_registers(env, mem_buf, len);        put_packet(s, "OK");        break;    case 'm':        addr = strtoull(p, (char **)&p, 16);        if (*p == ',')            p++;        len = strtoull(p, NULL, 16);        if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0) {            put_packet (s, "E14");        } else {            memtohex(buf, mem_buf, len);            put_packet(s, buf);        }        break;    case 'M':        addr = strtoull(p, (char **)&p, 16);        if (*p == ',')            p++;        len = strtoull(p, (char **)&p, 16);        if (*p == ':')            p++;        hextomem(mem_buf, p, len);        if (cpu_memory_rw_debug(env, addr, mem_buf, len, 1) != 0)            put_packet(s, "E14");        else            put_packet(s, "OK");        break;    case 'Z':        type = strtoul(p, (char **)&p, 16);        if (*p == ',')            p++;        addr = strtoull(p, (char **)&p, 16);        if (*p == ',')            p++;        len = strtoull(p, (char **)&p, 16);        if (type == 0 || type == 1) {            if (cpu_breakpoint_insert(env, addr) < 0)                goto breakpoint_error;            put_packet(s, "OK");#ifndef CONFIG_USER_ONLY        } else if (type == 2) {            if (cpu_watchpoint_insert(env, addr) < 0)                goto breakpoint_error;            put_packet(s, "OK");#endif        } else {        breakpoint_error:            put_packet(s, "E22");        }        break;    case 'z':        type = strtoul(p, (char **)&p, 16);        if (*p == ',')            p++;        addr = strtoull(p, (char **)&p, 16);        if (*p == ',')            p++;        len = strtoull(p, (char **)&p, 16);        if (type == 0 || type == 1) {            cpu_breakpoint_remove(env, addr);            put_packet(s, "OK");#ifndef CONFIG_USER_ONLY        } else if (type == 2) {            cpu_watchpoint_remove(env, addr);            put_packet(s, "OK");#endif        } else {            goto breakpoint_error;        }        break;#ifdef CONFIG_LINUX_USER    case 'q':        if (strncmp(p, "Offsets", 7) == 0) {            TaskState *ts = env->opaque;            sprintf(buf,                    "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx                    ";Bss=" TARGET_ABI_FMT_lx,                    ts->info->code_offset,                    ts->info->data_offset,                    ts->info->data_offset);            put_packet(s, buf);            break;        }        /* Fall through.  */#endif    default:        //        unknown_command:        /* put empty packet */        buf[0] = '\0';        put_packet(s, buf);        break;    }    return RS_IDLE;}extern void tb_flush(CPUState *env);#ifndef CONFIG_USER_ONLYstatic void gdb_vm_stopped(void *opaque, int reason){    GDBState *s = opaque;    char buf[256];    int ret;    if (s->state == RS_SYSCALL)        return;    /* disable single step if it was enable */    cpu_single_step(s->env, 0);    if (reason == EXCP_DEBUG) {        if (s->env->watchpoint_hit) {            snprintf(buf, sizeof(buf), "T%02xwatch:" TARGET_FMT_lx ";",                     SIGTRAP,                     s->env->watchpoint[s->env->watchpoint_hit - 1].vaddr);            put_packet(s, buf);            s->env->watchpoint_hit = 0;            return;        }	tb_flush(s->env);        ret = SIGTRAP;    } else if (reason == EXCP_INTERRUPT) {        ret = SIGINT;    } else {        ret = 0;    }    snprintf(buf, sizeof(buf), "S%02x", ret);    put_packet(s, buf);}#endif/* Send a gdb syscall request.   This accepts limited printf-style format specifiers, specifically:    %x  - target_ulong argument printed in hex.    %lx - 64-bit argument printed in hex.    %s  - string pointer (target_ulong) and length (int) pair.  */void gdb_do_syscall(gdb_syscall_complete_cb cb, char *fmt, ...){    va_list va;    char buf[256];    char *p;    target_ulong addr;    uint64_t i64;    GDBState *s;    s = gdb_syscall_state;    if (!s)        return;    gdb_current_syscall_cb = cb;    s->state = RS_SYSCALL;#ifndef CONFIG_USER_ONLY    vm_stop(EXCP_DEBUG);#endif    s->state = RS_IDLE;    va_start(va, fmt);    p = buf;    *(p++) = 'F';    while (*fmt) {        if (*fmt == '%') {            fmt++;            switch (*fmt++) {            case 'x':                addr = va_arg(va, target_ulong);                p += sprintf(p, TARGET_FMT_lx, addr);                break;            case 'l':                if (*(fmt++) != 'x')                    goto bad_format;                i64 = va_arg(va, uint64_t);                p += sprintf(p, "%" PRIx64, i64);                break;            case 's':                addr = va_arg(va, target_ulong);                p += sprintf(p, TARGET_FMT_lx "/%x", addr, va_arg(va, int));                break;            default:            bad_format:                fprintf(stderr, "gdbstub: Bad syscall format string '%s'\n",                        fmt - 1);                break;            }        } else {            *(p++) = *(fmt++);        }    }    *p = 0;    va_end(va);    put_packet(s, buf);#ifdef CONFIG_USER_ONLY    gdb_handlesig(s->env, 0);#else    cpu_interrupt(s->env, CPU_INTERRUPT_EXIT);#endif}static void gdb_read_byte(GDBState *s, int ch){    CPUState *env = s->env;    int i, csum;    uint8_t reply;#ifndef CONFIG_USER_ONLY    if (s->last_packet_len) {        /* Waiting for a response to the last packet.  If we see the start           of a new command then abandon the previous response.  */        if (ch == '-') {#ifdef DEBUG_GDB            printf("Got NACK, retransmitting\n");#endif            put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);        }#ifdef DEBUG_GDB        else if (ch == '+')            printf("Got ACK\n");        else            printf("Got '%c' when expecting ACK/NACK\n", ch);#endif        if (ch == '+' || ch == '$')            s->last_packet_len = 0;        if (ch != '$')            return;    }    if (vm_running) {        /* when the CPU is running, we cannot do anything except stop           it when receiving a char */        vm_stop(EXCP_INTERRUPT);    } else#endif    {        switch(s->state) {        case RS_IDLE:            if (ch == '$') {                s->line_buf_index = 0;                s->state = RS_GETLINE;            }            break;        case RS_GETLINE:            if (ch == '#') {            s->state = RS_CHKSUM1;            } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {                s->state = RS_IDLE;            } else {            s->line_buf[s->line_buf_index++] = ch;            }            break;        case RS_CHKSUM1:            s->line_buf[s->line_buf_index] = '\0';            s->line_csum = fromhex(ch) << 4;            s->state = RS_CHKSUM2;            break;        case RS_CHKSUM2:            s->line_csum |= fromhex(ch);            csum = 0;            for(i = 0; i < s->line_buf_index; i++) {                csum += s->line_buf[i];            }            if (s->line_csum != (csum & 0xff)) {                reply = '-';                put_buffer(s, &reply, 1);                s->state = RS_IDLE;            } else {                reply = '+';                put_buffer(s, &reply, 1);                s->state = gdb_handle_packet(s, env, s->line_buf);            }            break;        default:            abort();        }    }}#ifdef CONFIG_USER_ONLYintgdb_handlesig (CPUState *env, int sig){  GDBState *s;  char buf[256];  int n;  if (gdbserver_fd < 0)    return sig;  s = &gdbserver_state;  /* disable single step if it was enabled */  cpu_single_step(env, 0);  tb_flush(env);  if (sig != 0)    {      snprintf(buf, sizeof(buf), "S%02x", sig);      put_packet(s, buf);    }  sig = 0;  s->state = RS_IDLE;  s->running_state = 0;  while (s->running_state == 0) {      n = read (s->fd, buf, 256);      if (n > 0)        {          int i;          for (i = 0; i < n; i++)            gdb_read_byte (s, buf[i]);        }      else if (n == 0 || errno != EAGAIN)        {          /* XXX: Connection closed.  Should probably wait for annother             connection before continuing.  */          return sig;        }  }  return sig;}/* Tell the remote gdb that the process has exited.  */void gdb_exit(CPUState *env, int code){  GDBState *s;  char buf[4];  if (gdbserver_fd < 0)    return;  s = &gdbserver_state;  snprintf(buf, sizeof(buf), "W%02x", code);  put_packet(s, buf);}static void gdb_accept(void *opaque){    GDBState *s;    struct sockaddr_in sockaddr;    socklen_t len;    int val, fd;    for(;;) {        len = sizeof(sockaddr);        fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);        if (fd < 0 && errno != EINTR) {            perror("accept");            return;        } else if (fd >= 0) {            break;        }    }    /* set short latency */    val = 1;    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));    s = &gdbserver_state;    memset (s, 0, sizeof (GDBState));    s->env = first_cpu; /* XXX: allow to change CPU */    s->fd = fd;    gdb_syscall_state = s;    fcntl(fd, F_SETFL, O_NONBLOCK);}static int gdbserver_open(int port){    struct sockaddr_in sockaddr;    int fd, val, ret;    fd = socket(PF_INET, SOCK_STREAM, 0);    if (fd < 0) {        perror("socket");        return -1;    }    /* allow fast reuse */    val = 1;    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));    sockaddr.sin_family = AF_INET;    sockaddr.sin_port = htons(port);    sockaddr.sin_addr.s_addr = 0;    ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));    if (ret < 0) {        perror("bind");        return -1;    }    ret = listen(fd, 0);    if (ret < 0) {        perror("listen");        return -1;    }    return fd;}int gdbserver_start(int port){    gdbserver_fd = gdbserver_open(port);    if (gdbserver_fd < 0)        return -1;    /* accept connections */    gdb_accept (NULL);    return 0;}#elsestatic int gdb_chr_can_receive(void *opaque){  return 1;}static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size){    GDBState *s = opaque;    int i;    for (i = 0; i < size; i++) {        gdb_read_byte(s, buf[i]);    }}static void gdb_chr_event(void *opaque, int event){    switch (event) {    case CHR_EVENT_RESET:        vm_stop(EXCP_INTERRUPT);        gdb_syscall_state = opaque;        break;    default:        break;    }}int gdbserver_start(const char *port){    GDBState *s;    char gdbstub_port_name[128];    int port_num;    char *p;    CharDriverState *chr;    if (!port || !*port)      return -1;    port_num = strtol(port, &p, 10);    if (*p == 0) {        /* A numeric value is interpreted as a port number.  */        snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),                 "tcp::%d,nowait,nodelay,server", port_num);        port = gdbstub_port_name;    }    chr = qemu_chr_open(port);    if (!chr)        return -1;    s = qemu_mallocz(sizeof(GDBState));    if (!s) {        return -1;    }    s->env = first_cpu; /* XXX: allow to change CPU */    s->chr = chr;    qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,                          gdb_chr_event, s);    qemu_add_vm_stop_handler(gdb_vm_stopped, s);    return 0;}#endif

⌨️ 快捷键说明

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