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

📄 remote_gdb.cc

📁 M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作为模拟平台
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2002, 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Nathan L. Binkert *//* * Copyright (c) 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and * contributed to Berkeley. * * All advertising materials mentioning features or use of this software * must display the following acknowledgement: *	This product includes software developed by the University of *	California, Lawrence Berkeley Laboratories. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)kgdb_stub.c	8.4 (Berkeley) 1/12/94 *//*- * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Jason R. Thorpe. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the NetBSD *	Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its *    contributors may be used to endorse or promote products derived *    from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *//* * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $ * * Taken from NetBSD * * "Stub" to allow remote cpu to debug over a serial line using gdb. */#include <sys/signal.h>#include <string>#include <unistd.h>#include "config/full_system.hh"#if FULL_SYSTEM#include "arch/vtophys.hh"#endif#include "base/intmath.hh"#include "base/remote_gdb.hh"#include "base/socket.hh"#include "base/trace.hh"#include "cpu/thread_context.hh"#include "cpu/static_inst.hh"//#include "mem/physical.hh"#include "mem/port.hh"#include "mem/translating_port.hh"#include "sim/system.hh"using namespace std;using namespace TheISA;#ifndef NDEBUGvector<BaseRemoteGDB *> debuggers;voiddebugger(){    static int current_debugger = -1;    if (current_debugger >= 0 && current_debugger < debuggers.size()) {        BaseRemoteGDB *gdb = debuggers[current_debugger];        if (!gdb->isattached())            gdb->listener->accept();        if (gdb->isattached())            gdb->trap(SIGILL);    }}#endif/////////////////////////////////////////////////////////////////GDBListener::Event::Event(GDBListener *l, int fd, int e)    : PollEvent(fd, e), listener(l){}voidGDBListener::Event::process(int revent){    listener->accept();}GDBListener::GDBListener(BaseRemoteGDB *g, int p)    : event(NULL), gdb(g), port(p){    assert(!gdb->listener);    gdb->listener = this;}GDBListener::~GDBListener(){    if (event)        delete event;}stringGDBListener::name(){    return gdb->name() + ".listener";}voidGDBListener::listen(){    while (!listener.listen(port, true)) {        DPRINTF(GDBMisc, "Can't bind port %d\n", port);        port++;    }    event = new Event(this, listener.getfd(), POLLIN);    pollQueue.schedule(event);#ifndef NDEBUG    gdb->number = debuggers.size();    debuggers.push_back(gdb);#endif#ifndef NDEBUG    ccprintf(cerr, "%d: %s: listening for remote gdb #%d on port %d\n",             curTick, name(), gdb->number, port);#else    ccprintf(cerr, "%d: %s: listening for remote gdb on port %d\n",             curTick, name(), port);#endif}voidGDBListener::accept(){    if (!listener.islistening())        panic("GDBListener::accept(): cannot accept if we're not listening!");    int sfd = listener.accept(true);    if (sfd != -1) {        if (gdb->isattached())            close(sfd);        else            gdb->attach(sfd);    }}BaseRemoteGDB::Event::Event(BaseRemoteGDB *g, int fd, int e)    : PollEvent(fd, e), gdb(g){}voidBaseRemoteGDB::Event::process(int revent){    if (revent & POLLIN)        gdb->trap(SIGILL);    else if (revent & POLLNVAL)        gdb->detach();}BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c, size_t cacheSize)    : event(NULL), listener(NULL), number(-1), fd(-1),      active(false), attached(false),      system(_system), pmem(_system->physmem), context(c),      gdbregs(cacheSize){    memset(gdbregs.regs, 0, gdbregs.bytes());}BaseRemoteGDB::~BaseRemoteGDB(){    if (event)        delete event;}stringBaseRemoteGDB::name(){    return system->name() + ".remote_gdb";}boolBaseRemoteGDB::isattached(){ return attached; }voidBaseRemoteGDB::attach(int f){    fd = f;    event = new Event(this, fd, POLLIN);    pollQueue.schedule(event);    attached = true;    DPRINTFN("remote gdb attached\n");}voidBaseRemoteGDB::detach(){    attached = false;    close(fd);    fd = -1;    pollQueue.remove(event);    DPRINTFN("remote gdb detached\n");}const char *BaseRemoteGDB::gdb_command(char cmd){    switch (cmd) {      case GDBSignal: return "KGDB_SIGNAL";      case GDBSetBaud: return "KGDB_SET_BAUD";      case GDBSetBreak: return "KGDB_SET_BREAK";      case GDBCont: return "KGDB_CONT";      case GDBAsyncCont: return "KGDB_ASYNC_CONT";      case GDBDebug: return "KGDB_DEBUG";      case GDBDetach: return "KGDB_DETACH";      case GDBRegR: return "KGDB_REG_R";      case GDBRegW: return "KGDB_REG_W";      case GDBSetThread: return "KGDB_SET_THREAD";      case GDBCycleStep: return "KGDB_CYCLE_STEP";      case GDBSigCycleStep: return "KGDB_SIG_CYCLE_STEP";      case GDBKill: return "KGDB_KILL";      case GDBMemW: return "KGDB_MEM_W";      case GDBMemR: return "KGDB_MEM_R";      case GDBSetReg: return "KGDB_SET_REG";      case GDBReadReg: return "KGDB_READ_REG";      case GDBQueryVar: return "KGDB_QUERY_VAR";      case GDBSetVar: return "KGDB_SET_VAR";      case GDBReset: return "KGDB_RESET";      case GDBStep: return "KGDB_STEP";      case GDBAsyncStep: return "KGDB_ASYNC_STEP";      case GDBThreadAlive: return "KGDB_THREAD_ALIVE";      case GDBTargetExit: return "KGDB_TARGET_EXIT";      case GDBBinaryDload: return "KGDB_BINARY_DLOAD";      case GDBClrHwBkpt: return "KGDB_CLR_HW_BKPT";      case GDBSetHwBkpt: return "KGDB_SET_HW_BKPT";      case GDBStart: return "KGDB_START";      case GDBEnd: return "KGDB_END";      case GDBGoodP: return "KGDB_GOODP";      case GDBBadP: return "KGDB_BADP";      default: return "KGDB_UNKNOWN";    }}/////////////////////////////uint8_tBaseRemoteGDB::getbyte(){    uint8_t b;    ::read(fd, &b, 1);    return b;}voidBaseRemoteGDB::putbyte(uint8_t b){    ::write(fd, &b, 1);}// Send a packet to gdbvoidBaseRemoteGDB::send(const char *bp){    const char *p;    uint8_t csum, c;    DPRINTF(GDBSend, "send:  %s\n", bp);    do {        p = bp;        //Start sending a packet        putbyte(GDBStart);        //Send the contents, and also keep a check sum.        for (csum = 0; (c = *p); p++) {            putbyte(c);            csum += c;        }        //Send the ending character.        putbyte(GDBEnd);        //Sent the checksum.        putbyte(i2digit(csum >> 4));        putbyte(i2digit(csum));        //Try transmitting over and over again until the other end doesn't send an        //error back.    } while ((c = getbyte() & 0x7f) == GDBBadP);}// Receive a packet from gdbintBaseRemoteGDB::recv(char *bp, int maxlen){    char *p;    int c, csum;    int len;    do {        p = bp;        csum = len = 0;        //Find the beginning of a packet        while ((c = getbyte()) != GDBStart)            ;        //Read until you find the end of the data in the packet, and keep        //track of the check sum.        while ((c = getbyte()) != GDBEnd && len < maxlen) {            c &= 0x7f;            csum += c;            *p++ = c;            len++;        }        //Mask the check sum, and terminate the command string.        csum &= 0xff;        *p = '\0';        //If the command was too long, report an error.        if (len >= maxlen) {            putbyte(GDBBadP);            continue;        }        //Bring in the checksum. If the check sum matches, csum will be 0.        csum -= digit2i(getbyte()) * 16;        csum -= digit2i(getbyte());        //If the check sum was correct        if (csum == 0) {            //Report that the packet was received correctly            putbyte(GDBGoodP);            // Sequence present?            if (bp[2] == ':') {                putbyte(bp[0]);                putbyte(bp[1]);                len -= 3;                memcpy(bp, bp+3, len);            }            break;        }        //Otherwise, report that there was a mistake.        putbyte(GDBBadP);    } while (1);    DPRINTF(GDBRecv, "recv:  %s: %s\n", gdb_command(*bp), bp);    return (len);}// Read bytes from kernel address space for debugger.boolBaseRemoteGDB::read(Addr vaddr, size_t size, char *data){    static Addr lastaddr = 0;    static size_t lastsize = 0;    if (vaddr < 10) {      DPRINTF(GDBRead, "read:  reading memory location zero!\n");      vaddr = lastaddr + lastsize;    }    DPRINTF(GDBRead, "read:  addr=%#x, size=%d", vaddr, size);#if FULL_SYSTEM    VirtualPort *port = context->getVirtPort(context);#else    TranslatingPort *port = context->getMemPort();#endif    port->readBlob(vaddr, (uint8_t*)data, size);#if FULL_SYSTEM    context->delVirtPort(port);#endif#if TRACING_ON    if (DTRACE(GDBRead)) {        if (DTRACE(GDBExtra)) {            char buf[1024];            mem2hex(buf, data, size);            DPRINTFNR(": %s\n", buf);        } else            DPRINTFNR("\n");    }#endif    return true;}// Write bytes to kernel address space for debugger.boolBaseRemoteGDB::write(Addr vaddr, size_t size, const char *data){    static Addr lastaddr = 0;    static size_t lastsize = 0;    if (vaddr < 10) {      DPRINTF(GDBWrite, "write: writing memory location zero!\n");      vaddr = lastaddr + lastsize;    }    if (DTRACE(GDBWrite)) {        DPRINTFN("write: addr=%#x, size=%d", vaddr, size);        if (DTRACE(GDBExtra)) {            char buf[1024];            mem2hex(buf, data, size);            DPRINTFNR(": %s\n", buf);        } else            DPRINTFNR("\n");    }#if FULL_SYSTEM    VirtualPort *port = context->getVirtPort(context);#else    TranslatingPort *port = context->getMemPort();#endif    port->writeBlob(vaddr, (uint8_t*)data, size);#if FULL_SYSTEM    context->delVirtPort(port);#else    delete port;#endif

⌨️ 快捷键说明

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