remote_gdb.cc revision 10600
14159Sgblack@eecs.umich.edu/*
210600Sgabeblack@google.com * Copyright 2014 Google, Inc.
34159Sgblack@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company
44159Sgblack@eecs.umich.edu * All rights reserved.
54159Sgblack@eecs.umich.edu *
67087Snate@binkert.org * The license below extends only to copyright in the software and shall
77087Snate@binkert.org * not be construed as granting a license to any other intellectual
87087Snate@binkert.org * property including but not limited to intellectual property relating
97087Snate@binkert.org * to a hardware implementation of the functionality of the software
107087Snate@binkert.org * licensed hereunder.  You may use the software subject to the license
117087Snate@binkert.org * terms below provided that you ensure that this notice is replicated
127087Snate@binkert.org * unmodified and in its entirety in all distributions of the software,
137087Snate@binkert.org * modified or unmodified, in source code or in binary form.
144159Sgblack@eecs.umich.edu *
157087Snate@binkert.org * Redistribution and use in source and binary forms, with or without
167087Snate@binkert.org * modification, are permitted provided that the following conditions are
177087Snate@binkert.org * met: redistributions of source code must retain the above copyright
187087Snate@binkert.org * notice, this list of conditions and the following disclaimer;
197087Snate@binkert.org * redistributions in binary form must reproduce the above copyright
207087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
217087Snate@binkert.org * documentation and/or other materials provided with the distribution;
227087Snate@binkert.org * neither the name of the copyright holders nor the names of its
234159Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
247087Snate@binkert.org * this software without specific prior written permission.
254159Sgblack@eecs.umich.edu *
264159Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
274159Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
284159Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
294159Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
304159Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
314159Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
324159Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
334159Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
344159Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
354159Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
364159Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
374159Sgblack@eecs.umich.edu *
384159Sgblack@eecs.umich.edu * Authors: Gabe Black
394159Sgblack@eecs.umich.edu */
404159Sgblack@eecs.umich.edu
414159Sgblack@eecs.umich.edu#include <sys/signal.h>
428229Snate@binkert.org#include <unistd.h>
434159Sgblack@eecs.umich.edu
444159Sgblack@eecs.umich.edu#include <string>
454159Sgblack@eecs.umich.edu
4610600Sgabeblack@google.com#include "arch/x86/regs/int.hh"
4710600Sgabeblack@google.com#include "arch/x86/regs/misc.hh"
4810600Sgabeblack@google.com#include "arch/x86/pagetable_walker.hh"
4910600Sgabeblack@google.com#include "arch/x86/process.hh"
508229Snate@binkert.org#include "arch/x86/remote_gdb.hh"
514159Sgblack@eecs.umich.edu#include "arch/vtophys.hh"
524159Sgblack@eecs.umich.edu#include "base/remote_gdb.hh"
534159Sgblack@eecs.umich.edu#include "base/socket.hh"
544159Sgblack@eecs.umich.edu#include "base/trace.hh"
5510600Sgabeblack@google.com#include "cpu/base.hh"
564159Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
5710600Sgabeblack@google.com#include "mem/page_table.hh"
5810600Sgabeblack@google.com#include "sim/full_system.hh"
594159Sgblack@eecs.umich.edu
604159Sgblack@eecs.umich.eduusing namespace std;
615567Snate@binkert.orgusing namespace X86ISA;
624159Sgblack@eecs.umich.edu
6310600Sgabeblack@google.comRemoteGDB::RemoteGDB(System *_system, ThreadContext *c) :
6410600Sgabeblack@google.com    BaseRemoteGDB(_system, c, GDB_REG_BYTES), singleStepEvent(this)
654159Sgblack@eecs.umich.edu{}
664159Sgblack@eecs.umich.edu
6710600Sgabeblack@google.combool
6810600Sgabeblack@google.comRemoteGDB::acc(Addr va, size_t len)
694159Sgblack@eecs.umich.edu{
7010600Sgabeblack@google.com    if (FullSystem) {
7110600Sgabeblack@google.com        Walker *walker = context->getDTBPtr()->getWalker();
7210600Sgabeblack@google.com        unsigned logBytes;
7310600Sgabeblack@google.com        Fault fault = walker->startFunctional(context, va, logBytes,
7410600Sgabeblack@google.com                                              BaseTLB::Read);
7510600Sgabeblack@google.com        if (fault != NoFault)
7610600Sgabeblack@google.com            return false;
7710600Sgabeblack@google.com
7810600Sgabeblack@google.com        Addr endVa = va + len - 1;
7910600Sgabeblack@google.com        if ((va & ~mask(logBytes)) == (endVa & ~mask(logBytes)))
8010600Sgabeblack@google.com            return true;
8110600Sgabeblack@google.com
8210600Sgabeblack@google.com        fault = walker->startFunctional(context, endVa, logBytes,
8310600Sgabeblack@google.com                                        BaseTLB::Read);
8410600Sgabeblack@google.com        return fault == NoFault;
8510600Sgabeblack@google.com    } else {
8610600Sgabeblack@google.com        TlbEntry entry;
8710600Sgabeblack@google.com        return context->getProcessPtr()->pTable->lookup(va, entry);
8810600Sgabeblack@google.com    }
894159Sgblack@eecs.umich.edu}
904159Sgblack@eecs.umich.edu
9110600Sgabeblack@google.comvoid
9210600Sgabeblack@google.comRemoteGDB::SingleStepEvent::process()
934159Sgblack@eecs.umich.edu{
9410600Sgabeblack@google.com    if (!gdb->singleStepEvent.scheduled())
9510600Sgabeblack@google.com        gdb->scheduleInstCommitEvent(&gdb->singleStepEvent, 1);
9610600Sgabeblack@google.com    gdb->trap(SIGTRAP);
974159Sgblack@eecs.umich.edu}
984159Sgblack@eecs.umich.edu
9910600Sgabeblack@google.comvoid
10010600Sgabeblack@google.comRemoteGDB::getregs()
1014159Sgblack@eecs.umich.edu{
10210600Sgabeblack@google.com    HandyM5Reg m5reg = context->readMiscRegNoEffect(MISCREG_M5_REG);
10310600Sgabeblack@google.com    if (m5reg.submode == SixtyFourBitMode) {
10410600Sgabeblack@google.com        gdbregs.regs64[GDB64_RAX] = context->readIntReg(INTREG_RAX);
10510600Sgabeblack@google.com        gdbregs.regs64[GDB64_RBX] = context->readIntReg(INTREG_RBX);
10610600Sgabeblack@google.com        gdbregs.regs64[GDB64_RCX] = context->readIntReg(INTREG_RCX);
10710600Sgabeblack@google.com        gdbregs.regs64[GDB64_RDX] = context->readIntReg(INTREG_RDX);
10810600Sgabeblack@google.com        gdbregs.regs64[GDB64_RSI] = context->readIntReg(INTREG_RSI);
10910600Sgabeblack@google.com        gdbregs.regs64[GDB64_RDI] = context->readIntReg(INTREG_RDI);
11010600Sgabeblack@google.com        gdbregs.regs64[GDB64_RBP] = context->readIntReg(INTREG_RBP);
11110600Sgabeblack@google.com        gdbregs.regs64[GDB64_RSP] = context->readIntReg(INTREG_RSP);
11210600Sgabeblack@google.com        gdbregs.regs64[GDB64_R8] = context->readIntReg(INTREG_R8);
11310600Sgabeblack@google.com        gdbregs.regs64[GDB64_R9] = context->readIntReg(INTREG_R9);
11410600Sgabeblack@google.com        gdbregs.regs64[GDB64_R10] = context->readIntReg(INTREG_R10);
11510600Sgabeblack@google.com        gdbregs.regs64[GDB64_R11] = context->readIntReg(INTREG_R11);
11610600Sgabeblack@google.com        gdbregs.regs64[GDB64_R12] = context->readIntReg(INTREG_R12);
11710600Sgabeblack@google.com        gdbregs.regs64[GDB64_R13] = context->readIntReg(INTREG_R13);
11810600Sgabeblack@google.com        gdbregs.regs64[GDB64_R14] = context->readIntReg(INTREG_R14);
11910600Sgabeblack@google.com        gdbregs.regs64[GDB64_R15] = context->readIntReg(INTREG_R15);
12010600Sgabeblack@google.com        gdbregs.regs64[GDB64_RIP] = context->pcState().pc();
12110600Sgabeblack@google.com        gdbregs.regs32[GDB64_RFLAGS_32] =
12210600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_RFLAGS);
12310600Sgabeblack@google.com        gdbregs.regs32[GDB64_CS_32] = context->readMiscRegNoEffect(MISCREG_CS);
12410600Sgabeblack@google.com        gdbregs.regs32[GDB64_SS_32] = context->readMiscRegNoEffect(MISCREG_SS);
12510600Sgabeblack@google.com        gdbregs.regs32[GDB64_DS_32] = context->readMiscRegNoEffect(MISCREG_DS);
12610600Sgabeblack@google.com        gdbregs.regs32[GDB64_ES_32] = context->readMiscRegNoEffect(MISCREG_ES);
12710600Sgabeblack@google.com        gdbregs.regs32[GDB64_FS_32] = context->readMiscRegNoEffect(MISCREG_FS);
12810600Sgabeblack@google.com        gdbregs.regs32[GDB64_GS_32] = context->readMiscRegNoEffect(MISCREG_GS);
12910600Sgabeblack@google.com    } else {
13010600Sgabeblack@google.com        gdbregs.regs32[GDB32_EAX] = context->readIntReg(INTREG_RAX);
13110600Sgabeblack@google.com        gdbregs.regs32[GDB32_ECX] = context->readIntReg(INTREG_RCX);
13210600Sgabeblack@google.com        gdbregs.regs32[GDB32_EDX] = context->readIntReg(INTREG_RDX);
13310600Sgabeblack@google.com        gdbregs.regs32[GDB32_EBX] = context->readIntReg(INTREG_RBX);
13410600Sgabeblack@google.com        gdbregs.regs32[GDB32_ESP] = context->readIntReg(INTREG_RSP);
13510600Sgabeblack@google.com        gdbregs.regs32[GDB32_EBP] = context->readIntReg(INTREG_RBP);
13610600Sgabeblack@google.com        gdbregs.regs32[GDB32_ESI] = context->readIntReg(INTREG_RSI);
13710600Sgabeblack@google.com        gdbregs.regs32[GDB32_EDI] = context->readIntReg(INTREG_RDI);
13810600Sgabeblack@google.com        gdbregs.regs32[GDB32_EIP] = context->pcState().pc();
13910600Sgabeblack@google.com        gdbregs.regs32[GDB32_EFLAGS] =
14010600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_RFLAGS);
14110600Sgabeblack@google.com        gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_CS);
14210600Sgabeblack@google.com        gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_SS);
14310600Sgabeblack@google.com        gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_DS);
14410600Sgabeblack@google.com        gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_ES);
14510600Sgabeblack@google.com        gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_FS);
14610600Sgabeblack@google.com        gdbregs.regs32[GDB32_CS] = context->readMiscRegNoEffect(MISCREG_GS);
14710600Sgabeblack@google.com    }
1484159Sgblack@eecs.umich.edu}
1494159Sgblack@eecs.umich.edu
15010600Sgabeblack@google.comvoid
15110600Sgabeblack@google.comRemoteGDB::setregs()
1524159Sgblack@eecs.umich.edu{
15310600Sgabeblack@google.com    HandyM5Reg m5reg = context->readMiscRegNoEffect(MISCREG_M5_REG);
15410600Sgabeblack@google.com    if (m5reg.submode == SixtyFourBitMode) {
15510600Sgabeblack@google.com        context->setIntReg(INTREG_RAX, gdbregs.regs64[GDB64_RAX]);
15610600Sgabeblack@google.com        context->setIntReg(INTREG_RBX, gdbregs.regs64[GDB64_RBX]);
15710600Sgabeblack@google.com        context->setIntReg(INTREG_RCX, gdbregs.regs64[GDB64_RCX]);
15810600Sgabeblack@google.com        context->setIntReg(INTREG_RDX, gdbregs.regs64[GDB64_RDX]);
15910600Sgabeblack@google.com        context->setIntReg(INTREG_RSI, gdbregs.regs64[GDB64_RSI]);
16010600Sgabeblack@google.com        context->setIntReg(INTREG_RDI, gdbregs.regs64[GDB64_RDI]);
16110600Sgabeblack@google.com        context->setIntReg(INTREG_RBP, gdbregs.regs64[GDB64_RBP]);
16210600Sgabeblack@google.com        context->setIntReg(INTREG_RSP, gdbregs.regs64[GDB64_RSP]);
16310600Sgabeblack@google.com        context->setIntReg(INTREG_R8, gdbregs.regs64[GDB64_R8]);
16410600Sgabeblack@google.com        context->setIntReg(INTREG_R9, gdbregs.regs64[GDB64_R9]);
16510600Sgabeblack@google.com        context->setIntReg(INTREG_R10, gdbregs.regs64[GDB64_R10]);
16610600Sgabeblack@google.com        context->setIntReg(INTREG_R11, gdbregs.regs64[GDB64_R11]);
16710600Sgabeblack@google.com        context->setIntReg(INTREG_R12, gdbregs.regs64[GDB64_R12]);
16810600Sgabeblack@google.com        context->setIntReg(INTREG_R13, gdbregs.regs64[GDB64_R13]);
16910600Sgabeblack@google.com        context->setIntReg(INTREG_R14, gdbregs.regs64[GDB64_R14]);
17010600Sgabeblack@google.com        context->setIntReg(INTREG_R15, gdbregs.regs64[GDB64_R15]);
17110600Sgabeblack@google.com        context->pcState(gdbregs.regs64[GDB64_RIP]);
17210600Sgabeblack@google.com        context->setMiscReg(MISCREG_RFLAGS, gdbregs.regs32[GDB64_RFLAGS_32]);
17310600Sgabeblack@google.com        if (gdbregs.regs32[GDB64_CS_32] !=
17410600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_CS)) {
17510600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to CS.\n");
17610600Sgabeblack@google.com        }
17710600Sgabeblack@google.com        if (gdbregs.regs32[GDB64_SS_32] !=
17810600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_SS)) {
17910600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to SS.\n");
18010600Sgabeblack@google.com        }
18110600Sgabeblack@google.com        if (gdbregs.regs32[GDB64_DS_32] !=
18210600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_DS)) {
18310600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to DS.\n");
18410600Sgabeblack@google.com        }
18510600Sgabeblack@google.com        if (gdbregs.regs32[GDB64_ES_32] !=
18610600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_ES)) {
18710600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to ES.\n");
18810600Sgabeblack@google.com        }
18910600Sgabeblack@google.com        if (gdbregs.regs32[GDB64_FS_32] !=
19010600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_FS)) {
19110600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to FS.\n");
19210600Sgabeblack@google.com        }
19310600Sgabeblack@google.com        if (gdbregs.regs32[GDB64_GS_32] !=
19410600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_GS)) {
19510600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to GS.\n");
19610600Sgabeblack@google.com        }
19710600Sgabeblack@google.com    } else {
19810600Sgabeblack@google.com        context->setIntReg(INTREG_RAX, gdbregs.regs32[GDB32_EAX]);
19910600Sgabeblack@google.com        context->setIntReg(INTREG_RCX, gdbregs.regs32[GDB32_ECX]);
20010600Sgabeblack@google.com        context->setIntReg(INTREG_RDX, gdbregs.regs32[GDB32_EDX]);
20110600Sgabeblack@google.com        context->setIntReg(INTREG_RBX, gdbregs.regs32[GDB32_EBX]);
20210600Sgabeblack@google.com        context->setIntReg(INTREG_RSP, gdbregs.regs32[GDB32_ESP]);
20310600Sgabeblack@google.com        context->setIntReg(INTREG_RBP, gdbregs.regs32[GDB32_EBP]);
20410600Sgabeblack@google.com        context->setIntReg(INTREG_RSI, gdbregs.regs32[GDB32_ESI]);
20510600Sgabeblack@google.com        context->setIntReg(INTREG_RDI, gdbregs.regs32[GDB32_EDI]);
20610600Sgabeblack@google.com        context->pcState(gdbregs.regs32[GDB32_EIP]);
20710600Sgabeblack@google.com        context->setMiscReg(MISCREG_RFLAGS, gdbregs.regs32[GDB32_EFLAGS]);
20810600Sgabeblack@google.com        if (gdbregs.regs32[GDB64_CS_32] !=
20910600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_CS)) {
21010600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to CS.\n");
21110600Sgabeblack@google.com        }
21210600Sgabeblack@google.com        if (gdbregs.regs32[GDB32_SS] !=
21310600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_SS)) {
21410600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to SS.\n");
21510600Sgabeblack@google.com        }
21610600Sgabeblack@google.com        if (gdbregs.regs32[GDB32_DS] !=
21710600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_DS)) {
21810600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to DS.\n");
21910600Sgabeblack@google.com        }
22010600Sgabeblack@google.com        if (gdbregs.regs32[GDB32_ES] !=
22110600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_ES)) {
22210600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to ES.\n");
22310600Sgabeblack@google.com        }
22410600Sgabeblack@google.com        if (gdbregs.regs32[GDB32_FS] !=
22510600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_FS)) {
22610600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to FS.\n");
22710600Sgabeblack@google.com        }
22810600Sgabeblack@google.com        if (gdbregs.regs32[GDB32_GS] !=
22910600Sgabeblack@google.com            context->readMiscRegNoEffect(MISCREG_GS)) {
23010600Sgabeblack@google.com            warn("Remote gdb: Ignoring update to GS.\n");
23110600Sgabeblack@google.com        }
23210600Sgabeblack@google.com    }
2334159Sgblack@eecs.umich.edu}
2344159Sgblack@eecs.umich.edu
23510600Sgabeblack@google.comvoid
23610600Sgabeblack@google.comRemoteGDB::clearSingleStep()
2374159Sgblack@eecs.umich.edu{
23810600Sgabeblack@google.com    descheduleInstCommitEvent(&singleStepEvent);
2394159Sgblack@eecs.umich.edu}
24010600Sgabeblack@google.com
24110600Sgabeblack@google.comvoid
24210600Sgabeblack@google.comRemoteGDB::setSingleStep()
24310600Sgabeblack@google.com{
24410600Sgabeblack@google.com    if (!singleStepEvent.scheduled())
24510600Sgabeblack@google.com        scheduleInstCommitEvent(&singleStepEvent, 1);
24610600Sgabeblack@google.com}
247