14159Sgblack@eecs.umich.edu/*
211274Sshingarov@labware.com * Copyright 2015 LabWare
310600Sgabeblack@google.com * Copyright 2014 Google, Inc.
44159Sgblack@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company
54159Sgblack@eecs.umich.edu * All rights reserved.
64159Sgblack@eecs.umich.edu *
77087Snate@binkert.org * The license below extends only to copyright in the software and shall
87087Snate@binkert.org * not be construed as granting a license to any other intellectual
97087Snate@binkert.org * property including but not limited to intellectual property relating
107087Snate@binkert.org * to a hardware implementation of the functionality of the software
117087Snate@binkert.org * licensed hereunder.  You may use the software subject to the license
127087Snate@binkert.org * terms below provided that you ensure that this notice is replicated
137087Snate@binkert.org * unmodified and in its entirety in all distributions of the software,
147087Snate@binkert.org * modified or unmodified, in source code or in binary form.
154159Sgblack@eecs.umich.edu *
167087Snate@binkert.org * Redistribution and use in source and binary forms, with or without
177087Snate@binkert.org * modification, are permitted provided that the following conditions are
187087Snate@binkert.org * met: redistributions of source code must retain the above copyright
197087Snate@binkert.org * notice, this list of conditions and the following disclaimer;
207087Snate@binkert.org * redistributions in binary form must reproduce the above copyright
217087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
227087Snate@binkert.org * documentation and/or other materials provided with the distribution;
237087Snate@binkert.org * neither the name of the copyright holders nor the names of its
244159Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
257087Snate@binkert.org * this software without specific prior written permission.
264159Sgblack@eecs.umich.edu *
274159Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
284159Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
294159Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
304159Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
314159Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
324159Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
334159Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
344159Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
354159Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
364159Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
374159Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
384159Sgblack@eecs.umich.edu *
394159Sgblack@eecs.umich.edu * Authors: Gabe Black
4011274Sshingarov@labware.com *          Boris Shingarov
414159Sgblack@eecs.umich.edu */
424159Sgblack@eecs.umich.edu
4311793Sbrandon.potter@amd.com#include "arch/x86/remote_gdb.hh"
4411793Sbrandon.potter@amd.com
454159Sgblack@eecs.umich.edu#include <sys/signal.h>
468229Snate@binkert.org#include <unistd.h>
474159Sgblack@eecs.umich.edu
484159Sgblack@eecs.umich.edu#include <string>
494159Sgblack@eecs.umich.edu
5011793Sbrandon.potter@amd.com#include "arch/vtophys.hh"
5111793Sbrandon.potter@amd.com#include "arch/x86/pagetable_walker.hh"
5211793Sbrandon.potter@amd.com#include "arch/x86/process.hh"
5310600Sgabeblack@google.com#include "arch/x86/regs/int.hh"
5410600Sgabeblack@google.com#include "arch/x86/regs/misc.hh"
554159Sgblack@eecs.umich.edu#include "base/remote_gdb.hh"
564159Sgblack@eecs.umich.edu#include "base/socket.hh"
574159Sgblack@eecs.umich.edu#include "base/trace.hh"
5810600Sgabeblack@google.com#include "cpu/base.hh"
594159Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
6011274Sshingarov@labware.com#include "debug/GDBAcc.hh"
6110600Sgabeblack@google.com#include "mem/page_table.hh"
6210600Sgabeblack@google.com#include "sim/full_system.hh"
634159Sgblack@eecs.umich.edu
644159Sgblack@eecs.umich.eduusing namespace std;
655567Snate@binkert.orgusing namespace X86ISA;
664159Sgblack@eecs.umich.edu
6712449Sgabeblack@google.comRemoteGDB::RemoteGDB(System *_system, ThreadContext *c, int _port) :
6812449Sgabeblack@google.com    BaseRemoteGDB(_system, c, _port), regCache32(this), regCache64(this)
694159Sgblack@eecs.umich.edu{}
704159Sgblack@eecs.umich.edu
7110600Sgabeblack@google.combool
7210600Sgabeblack@google.comRemoteGDB::acc(Addr va, size_t len)
734159Sgblack@eecs.umich.edu{
7410600Sgabeblack@google.com    if (FullSystem) {
7512406Sgabeblack@google.com        Walker *walker = dynamic_cast<TLB *>(
7612449Sgabeblack@google.com            context()->getDTBPtr())->getWalker();
7710600Sgabeblack@google.com        unsigned logBytes;
7812449Sgabeblack@google.com        Fault fault = walker->startFunctional(context(), va, logBytes,
7910600Sgabeblack@google.com                                              BaseTLB::Read);
8010600Sgabeblack@google.com        if (fault != NoFault)
8110600Sgabeblack@google.com            return false;
8210600Sgabeblack@google.com
8310600Sgabeblack@google.com        Addr endVa = va + len - 1;
8410600Sgabeblack@google.com        if ((va & ~mask(logBytes)) == (endVa & ~mask(logBytes)))
8510600Sgabeblack@google.com            return true;
8610600Sgabeblack@google.com
8712449Sgabeblack@google.com        fault = walker->startFunctional(context(), endVa, logBytes,
8810600Sgabeblack@google.com                                        BaseTLB::Read);
8910600Sgabeblack@google.com        return fault == NoFault;
9010600Sgabeblack@google.com    } else {
9112455Sgabeblack@google.com        return context()->getProcessPtr()->pTable->lookup(va) != nullptr;
9210600Sgabeblack@google.com    }
934159Sgblack@eecs.umich.edu}
944159Sgblack@eecs.umich.edu
9512449Sgabeblack@google.comBaseGdbRegCache*
9611274Sshingarov@labware.comRemoteGDB::gdbRegs()
974159Sgblack@eecs.umich.edu{
9812449Sgabeblack@google.com    HandyM5Reg m5reg = context()->readMiscRegNoEffect(MISCREG_M5_REG);
9911274Sshingarov@labware.com    if (m5reg.submode == SixtyFourBitMode)
10012031Sgabeblack@google.com        return &regCache64;
10111274Sshingarov@labware.com    else
10212031Sgabeblack@google.com        return &regCache32;
10311274Sshingarov@labware.com}
10411274Sshingarov@labware.com
10511274Sshingarov@labware.com
10611274Sshingarov@labware.com
10711274Sshingarov@labware.comvoid
10811274Sshingarov@labware.comRemoteGDB::AMD64GdbRegCache::getRegs(ThreadContext *context)
10911274Sshingarov@labware.com{
11011274Sshingarov@labware.com    DPRINTF(GDBAcc, "getRegs in remotegdb \n");
11111274Sshingarov@labware.com    r.rax = context->readIntReg(INTREG_RAX);
11211274Sshingarov@labware.com    r.rbx = context->readIntReg(INTREG_RBX);
11311274Sshingarov@labware.com    r.rcx = context->readIntReg(INTREG_RCX);
11411274Sshingarov@labware.com    r.rdx = context->readIntReg(INTREG_RDX);
11511274Sshingarov@labware.com    r.rsi = context->readIntReg(INTREG_RSI);
11611274Sshingarov@labware.com    r.rdi = context->readIntReg(INTREG_RDI);
11711274Sshingarov@labware.com    r.rbp = context->readIntReg(INTREG_RBP);
11811274Sshingarov@labware.com    r.rsp = context->readIntReg(INTREG_RSP);
11911274Sshingarov@labware.com    r.r8 = context->readIntReg(INTREG_R8);
12011274Sshingarov@labware.com    r.r9 = context->readIntReg(INTREG_R9);
12111274Sshingarov@labware.com    r.r10 = context->readIntReg(INTREG_R10);
12211274Sshingarov@labware.com    r.r11 = context->readIntReg(INTREG_R11);
12311274Sshingarov@labware.com    r.r12 = context->readIntReg(INTREG_R12);
12411274Sshingarov@labware.com    r.r13 = context->readIntReg(INTREG_R13);
12511274Sshingarov@labware.com    r.r14 = context->readIntReg(INTREG_R14);
12611274Sshingarov@labware.com    r.r15 = context->readIntReg(INTREG_R15);
12711274Sshingarov@labware.com    r.rip = context->pcState().pc();
12811274Sshingarov@labware.com    r.eflags = context->readMiscRegNoEffect(MISCREG_RFLAGS);
12911274Sshingarov@labware.com    r.cs = context->readMiscRegNoEffect(MISCREG_CS);
13011274Sshingarov@labware.com    r.ss = context->readMiscRegNoEffect(MISCREG_SS);
13111274Sshingarov@labware.com    r.ds = context->readMiscRegNoEffect(MISCREG_DS);
13211274Sshingarov@labware.com    r.es = context->readMiscRegNoEffect(MISCREG_ES);
13311274Sshingarov@labware.com    r.fs = context->readMiscRegNoEffect(MISCREG_FS);
13411274Sshingarov@labware.com    r.gs = context->readMiscRegNoEffect(MISCREG_GS);
1354159Sgblack@eecs.umich.edu}
1364159Sgblack@eecs.umich.edu
13710600Sgabeblack@google.comvoid
13811274Sshingarov@labware.comRemoteGDB::X86GdbRegCache::getRegs(ThreadContext *context)
1394159Sgblack@eecs.umich.edu{
14011274Sshingarov@labware.com    DPRINTF(GDBAcc, "getRegs in remotegdb \n");
14111274Sshingarov@labware.com    r.eax = context->readIntReg(INTREG_RAX);
14211274Sshingarov@labware.com    r.ecx = context->readIntReg(INTREG_RCX);
14311274Sshingarov@labware.com    r.edx = context->readIntReg(INTREG_RDX);
14411274Sshingarov@labware.com    r.ebx = context->readIntReg(INTREG_RBX);
14511274Sshingarov@labware.com    r.esp = context->readIntReg(INTREG_RSP);
14611274Sshingarov@labware.com    r.ebp = context->readIntReg(INTREG_RBP);
14711274Sshingarov@labware.com    r.esi = context->readIntReg(INTREG_RSI);
14811274Sshingarov@labware.com    r.edi = context->readIntReg(INTREG_RDI);
14911274Sshingarov@labware.com    r.eip = context->pcState().pc();
15011274Sshingarov@labware.com    r.eflags = context->readMiscRegNoEffect(MISCREG_RFLAGS);
15111274Sshingarov@labware.com    r.cs = context->readMiscRegNoEffect(MISCREG_CS);
15211274Sshingarov@labware.com    r.ss = context->readMiscRegNoEffect(MISCREG_SS);
15311274Sshingarov@labware.com    r.ds = context->readMiscRegNoEffect(MISCREG_DS);
15411274Sshingarov@labware.com    r.es = context->readMiscRegNoEffect(MISCREG_ES);
15511274Sshingarov@labware.com    r.fs = context->readMiscRegNoEffect(MISCREG_FS);
15611274Sshingarov@labware.com    r.gs = context->readMiscRegNoEffect(MISCREG_GS);
1574159Sgblack@eecs.umich.edu}
15811274Sshingarov@labware.com
15911274Sshingarov@labware.comvoid
16011274Sshingarov@labware.comRemoteGDB::AMD64GdbRegCache::setRegs(ThreadContext *context) const
16111274Sshingarov@labware.com{
16211274Sshingarov@labware.com    DPRINTF(GDBAcc, "setRegs in remotegdb \n");
16311274Sshingarov@labware.com    context->setIntReg(INTREG_RAX, r.rax);
16411274Sshingarov@labware.com    context->setIntReg(INTREG_RBX, r.rbx);
16511274Sshingarov@labware.com    context->setIntReg(INTREG_RCX, r.rcx);
16611274Sshingarov@labware.com    context->setIntReg(INTREG_RDX, r.rdx);
16711274Sshingarov@labware.com    context->setIntReg(INTREG_RSI, r.rsi);
16811274Sshingarov@labware.com    context->setIntReg(INTREG_RDI, r.rdi);
16911274Sshingarov@labware.com    context->setIntReg(INTREG_RBP, r.rbp);
17011274Sshingarov@labware.com    context->setIntReg(INTREG_RSP, r.rsp);
17111274Sshingarov@labware.com    context->setIntReg(INTREG_R8, r.r8);
17211274Sshingarov@labware.com    context->setIntReg(INTREG_R9, r.r9);
17311274Sshingarov@labware.com    context->setIntReg(INTREG_R10, r.r10);
17411274Sshingarov@labware.com    context->setIntReg(INTREG_R11, r.r11);
17511274Sshingarov@labware.com    context->setIntReg(INTREG_R12, r.r12);
17611274Sshingarov@labware.com    context->setIntReg(INTREG_R13, r.r13);
17711274Sshingarov@labware.com    context->setIntReg(INTREG_R14, r.r14);
17811274Sshingarov@labware.com    context->setIntReg(INTREG_R15, r.r15);
17911274Sshingarov@labware.com    context->pcState(r.rip);
18011274Sshingarov@labware.com    context->setMiscReg(MISCREG_RFLAGS, r.eflags);
18111274Sshingarov@labware.com    if (r.cs != context->readMiscRegNoEffect(MISCREG_CS))
18211274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to CS.\n");
18311274Sshingarov@labware.com    if (r.ss != context->readMiscRegNoEffect(MISCREG_SS))
18411274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to SS.\n");
18511274Sshingarov@labware.com    if (r.ds != context->readMiscRegNoEffect(MISCREG_DS))
18611274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to DS.\n");
18711274Sshingarov@labware.com    if (r.es != context->readMiscRegNoEffect(MISCREG_ES))
18811274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to ES.\n");
18911274Sshingarov@labware.com    if (r.fs != context->readMiscRegNoEffect(MISCREG_FS))
19011274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to FS.\n");
19111274Sshingarov@labware.com    if (r.gs != context->readMiscRegNoEffect(MISCREG_GS))
19211274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to GS.\n");
19311274Sshingarov@labware.com}
19411274Sshingarov@labware.com
19511274Sshingarov@labware.comvoid
19611274Sshingarov@labware.comRemoteGDB::X86GdbRegCache::setRegs(ThreadContext *context) const
19711274Sshingarov@labware.com{
19811274Sshingarov@labware.com    DPRINTF(GDBAcc, "setRegs in remotegdb \n");
19911274Sshingarov@labware.com    context->setIntReg(INTREG_RAX, r.eax);
20011274Sshingarov@labware.com    context->setIntReg(INTREG_RCX, r.ecx);
20111274Sshingarov@labware.com    context->setIntReg(INTREG_RDX, r.edx);
20211274Sshingarov@labware.com    context->setIntReg(INTREG_RBX, r.ebx);
20311274Sshingarov@labware.com    context->setIntReg(INTREG_RSP, r.esp);
20411274Sshingarov@labware.com    context->setIntReg(INTREG_RBP, r.ebp);
20511274Sshingarov@labware.com    context->setIntReg(INTREG_RSI, r.esi);
20611274Sshingarov@labware.com    context->setIntReg(INTREG_RDI, r.edi);
20711274Sshingarov@labware.com    context->pcState(r.eip);
20811274Sshingarov@labware.com    context->setMiscReg(MISCREG_RFLAGS, r.eflags);
20911274Sshingarov@labware.com    if (r.cs != context->readMiscRegNoEffect(MISCREG_CS))
21011274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to CS.\n");
21111274Sshingarov@labware.com    if (r.ss != context->readMiscRegNoEffect(MISCREG_SS))
21211274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to SS.\n");
21311274Sshingarov@labware.com    if (r.ds != context->readMiscRegNoEffect(MISCREG_DS))
21411274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to DS.\n");
21511274Sshingarov@labware.com    if (r.es != context->readMiscRegNoEffect(MISCREG_ES))
21611274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to ES.\n");
21711274Sshingarov@labware.com    if (r.fs != context->readMiscRegNoEffect(MISCREG_FS))
21811274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to FS.\n");
21911274Sshingarov@labware.com    if (r.gs != context->readMiscRegNoEffect(MISCREG_GS))
22011274Sshingarov@labware.com        warn("Remote gdb: Ignoring update to GS.\n");
22111274Sshingarov@labware.com}
222