tracechild.cc revision 4780
17322Sgblack@eecs.umich.edu/*
27322Sgblack@eecs.umich.edu * Copyright (c) 2007 The Regents of The University of Michigan
313738Sciro.santilli@arm.com * All rights reserved.
47322Sgblack@eecs.umich.edu *
57322Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67322Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77322Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87322Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97322Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107322Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117322Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127322Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137322Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
147322Sgblack@eecs.umich.edu * this software without specific prior written permission.
157322Sgblack@eecs.umich.edu *
167322Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177322Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187322Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197322Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207322Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217322Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227322Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237322Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247322Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257322Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267322Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277322Sgblack@eecs.umich.edu *
287322Sgblack@eecs.umich.edu * Authors: Gabe Black
297322Sgblack@eecs.umich.edu */
307322Sgblack@eecs.umich.edu
317322Sgblack@eecs.umich.edu#include <iostream>
327322Sgblack@eecs.umich.edu#include <errno.h>
337322Sgblack@eecs.umich.edu#include <sys/ptrace.h>
347322Sgblack@eecs.umich.edu#include <stdint.h>
357322Sgblack@eecs.umich.edu
367322Sgblack@eecs.umich.edu#include "tracechild_amd64.hh"
377322Sgblack@eecs.umich.edu
387322Sgblack@eecs.umich.eduusing namespace std;
397322Sgblack@eecs.umich.edu
407376Sgblack@eecs.umich.educhar * AMD64TraceChild::regNames[numregs] = {
417376Sgblack@eecs.umich.edu                //GPRs
427376Sgblack@eecs.umich.edu                "rax", "rbx", "rcx", "rdx",
437376Sgblack@eecs.umich.edu                //Index registers
447376Sgblack@eecs.umich.edu                "rsi", "rdi",
457376Sgblack@eecs.umich.edu                //Base pointer and stack pointer
467376Sgblack@eecs.umich.edu                "rbp", "rsp",
477376Sgblack@eecs.umich.edu                //New 64 bit mode registers
487376Sgblack@eecs.umich.edu                "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
497376Sgblack@eecs.umich.edu                //Segmentation registers
507376Sgblack@eecs.umich.edu                "cs", "ds", "es", "fs", "gs", "ss", "fs_base", "gs_base",
517376Sgblack@eecs.umich.edu                //PC
527376Sgblack@eecs.umich.edu                "rip",
537376Sgblack@eecs.umich.edu                //Flags
547376Sgblack@eecs.umich.edu                "eflags"};
557376Sgblack@eecs.umich.edu
567376Sgblack@eecs.umich.edubool AMD64TraceChild::sendState(int socket)
577376Sgblack@eecs.umich.edu{
587376Sgblack@eecs.umich.edu    uint64_t regVal = 0;
597376Sgblack@eecs.umich.edu    for(int x = 0; x <= R15; x++)
607376Sgblack@eecs.umich.edu    {
617376Sgblack@eecs.umich.edu        regVal = getRegVal(x);
627376Sgblack@eecs.umich.edu        if(write(socket, &regVal, sizeof(regVal)) == -1)
637376Sgblack@eecs.umich.edu        {
647376Sgblack@eecs.umich.edu            cerr << "Write failed! " << strerror(errno) << endl;
657376Sgblack@eecs.umich.edu            tracing = false;
6612032Sandreas.sandberg@arm.com            return false;
677376Sgblack@eecs.umich.edu        }
687376Sgblack@eecs.umich.edu    }
697376Sgblack@eecs.umich.edu    regVal = getRegVal(RIP);
707376Sgblack@eecs.umich.edu    if(write(socket, &regVal, sizeof(regVal)) == -1)
717376Sgblack@eecs.umich.edu    {
727376Sgblack@eecs.umich.edu        cerr << "Write failed! " << strerror(errno) << endl;
737376Sgblack@eecs.umich.edu        tracing = false;
747376Sgblack@eecs.umich.edu        return false;
757376Sgblack@eecs.umich.edu    }
767376Sgblack@eecs.umich.edu    return true;
777376Sgblack@eecs.umich.edu}
787376Sgblack@eecs.umich.edu
797376Sgblack@eecs.umich.eduint64_t AMD64TraceChild::getRegs(user_regs_struct & myregs, int num)
807376Sgblack@eecs.umich.edu{
817376Sgblack@eecs.umich.edu        assert(num < numregs && num >= 0);
827376Sgblack@eecs.umich.edu        switch(num)
837376Sgblack@eecs.umich.edu        {
847376Sgblack@eecs.umich.edu                //GPRs
857376Sgblack@eecs.umich.edu                case RAX: return myregs.rax;
867376Sgblack@eecs.umich.edu                case RBX: return myregs.rbx;
877376Sgblack@eecs.umich.edu                case RCX: return myregs.rcx;
887376Sgblack@eecs.umich.edu                case RDX: return myregs.rdx;
897376Sgblack@eecs.umich.edu                //Index registers
907376Sgblack@eecs.umich.edu                case RSI: return myregs.rsi;
917376Sgblack@eecs.umich.edu                case RDI: return myregs.rdi;
927376Sgblack@eecs.umich.edu                //Base pointer and stack pointer
937376Sgblack@eecs.umich.edu                case RBP: return myregs.rbp;
947376Sgblack@eecs.umich.edu                case RSP: return myregs.rsp;
957376Sgblack@eecs.umich.edu                //New 64 bit mode registers
967376Sgblack@eecs.umich.edu                case R8: return myregs.r8;
977376Sgblack@eecs.umich.edu                case R9: return myregs.r9;
987376Sgblack@eecs.umich.edu                case R10: return myregs.r10;
997376Sgblack@eecs.umich.edu                case R11: return myregs.r11;
10012032Sandreas.sandberg@arm.com                case R12: return myregs.r12;
1017376Sgblack@eecs.umich.edu                case R13: return myregs.r13;
1027376Sgblack@eecs.umich.edu                case R14: return myregs.r14;
1037376Sgblack@eecs.umich.edu                case R15: return myregs.r15;
1047376Sgblack@eecs.umich.edu                //Segmentation registers
1057376Sgblack@eecs.umich.edu                case CS: return myregs.cs;
1067376Sgblack@eecs.umich.edu                case DS: return myregs.ds;
1077376Sgblack@eecs.umich.edu                case ES: return myregs.es;
1087376Sgblack@eecs.umich.edu                case FS: return myregs.fs;
1097376Sgblack@eecs.umich.edu                case GS: return myregs.gs;
1107376Sgblack@eecs.umich.edu                case SS: return myregs.ss;
1117376Sgblack@eecs.umich.edu                case FS_BASE: return myregs.fs_base;
1127376Sgblack@eecs.umich.edu                case GS_BASE: return myregs.gs_base;
1137376Sgblack@eecs.umich.edu                //PC
1147376Sgblack@eecs.umich.edu                case RIP: return myregs.rip;
1157376Sgblack@eecs.umich.edu                //Flags
1167376Sgblack@eecs.umich.edu                case EFLAGS: return myregs.eflags;
1177376Sgblack@eecs.umich.edu                default:
1187376Sgblack@eecs.umich.edu                        assert(0);
1197376Sgblack@eecs.umich.edu                        return 0;
1207376Sgblack@eecs.umich.edu        }
1217376Sgblack@eecs.umich.edu}
1227376Sgblack@eecs.umich.edu
1237376Sgblack@eecs.umich.edubool AMD64TraceChild::update(int pid)
1247376Sgblack@eecs.umich.edu{
1257376Sgblack@eecs.umich.edu    oldregs = regs;
1267376Sgblack@eecs.umich.edu    if(ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0)
1277376Sgblack@eecs.umich.edu    {
1287376Sgblack@eecs.umich.edu        cerr << "update: " << strerror(errno) << endl;
1297376Sgblack@eecs.umich.edu        return false;
1307376Sgblack@eecs.umich.edu    }
1317376Sgblack@eecs.umich.edu    for(unsigned int x = 0; x < numregs; x++)
1327376Sgblack@eecs.umich.edu        regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x));
1337376Sgblack@eecs.umich.edu    return true;
13412032Sandreas.sandberg@arm.com}
1357376Sgblack@eecs.umich.edu
1367376Sgblack@eecs.umich.eduAMD64TraceChild::AMD64TraceChild()
1377376Sgblack@eecs.umich.edu{
1387376Sgblack@eecs.umich.edu    for(unsigned int x = 0; x < numregs; x++)
1397376Sgblack@eecs.umich.edu        regDiffSinceUpdate[x] = false;
1407376Sgblack@eecs.umich.edu}
1417376Sgblack@eecs.umich.edu
1427376Sgblack@eecs.umich.eduint64_t AMD64TraceChild::getRegVal(int num)
1437376Sgblack@eecs.umich.edu{
1447376Sgblack@eecs.umich.edu        return getRegs(regs, num);
1457376Sgblack@eecs.umich.edu}
1467376Sgblack@eecs.umich.edu
1477376Sgblack@eecs.umich.eduint64_t AMD64TraceChild::getOldRegVal(int num)
1487376Sgblack@eecs.umich.edu{
1497376Sgblack@eecs.umich.edu        return getRegs(oldregs, num);
1507376Sgblack@eecs.umich.edu}
1517376Sgblack@eecs.umich.edu
1527376Sgblack@eecs.umich.educhar * AMD64TraceChild::printReg(int num)
1537376Sgblack@eecs.umich.edu{
1547376Sgblack@eecs.umich.edu        sprintf(printBuffer, "0x%08X", getRegVal(num));
1557376Sgblack@eecs.umich.edu        return printBuffer;
1567376Sgblack@eecs.umich.edu}
1577376Sgblack@eecs.umich.edu
1587376Sgblack@eecs.umich.eduostream & AMD64TraceChild::outputStartState(ostream & os)
1597376Sgblack@eecs.umich.edu{
1607376Sgblack@eecs.umich.edu    uint64_t sp = getSP();
1617376Sgblack@eecs.umich.edu    uint64_t pc = getPC();
1627376Sgblack@eecs.umich.edu    char obuf[1024];
1637376Sgblack@eecs.umich.edu    sprintf(obuf, "Initial stack pointer = 0x%016llx\n", sp);
1647376Sgblack@eecs.umich.edu    os << obuf;
1657376Sgblack@eecs.umich.edu    sprintf(obuf, "Initial program counter = 0x%016llx\n", pc);
1667376Sgblack@eecs.umich.edu    os << obuf;
1677376Sgblack@eecs.umich.edu
16812032Sandreas.sandberg@arm.com    //Output the argument count
1697376Sgblack@eecs.umich.edu    uint64_t cargc = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
1707376Sgblack@eecs.umich.edu    sprintf(obuf, "0x%016llx: Argc = 0x%016llx\n", sp, cargc);
1717376Sgblack@eecs.umich.edu    os << obuf;
1727376Sgblack@eecs.umich.edu    sp += 8;
1737376Sgblack@eecs.umich.edu
1747376Sgblack@eecs.umich.edu    //Output argv pointers
1757376Sgblack@eecs.umich.edu    int argCount = 0;
1767376Sgblack@eecs.umich.edu    uint64_t cargv;
1777376Sgblack@eecs.umich.edu    do
1787376Sgblack@eecs.umich.edu    {
1797376Sgblack@eecs.umich.edu        cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
1807322Sgblack@eecs.umich.edu        sprintf(obuf, "0x%016llx: argv[%d] = 0x%016llx\n",
1817322Sgblack@eecs.umich.edu                sp, argCount++, cargv);
1827322Sgblack@eecs.umich.edu        os << obuf;
1837322Sgblack@eecs.umich.edu        sp += 8;
1847322Sgblack@eecs.umich.edu    } while(cargv);
1857322Sgblack@eecs.umich.edu
18610037SARM gem5 Developers    //Output the envp pointers
18710037SARM gem5 Developers    int envCount = 0;
18810037SARM gem5 Developers    uint64_t cenvp;
18910037SARM gem5 Developers    do
19010037SARM gem5 Developers    {
19110037SARM gem5 Developers        cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
1927760SGiacomo.Gabrielli@arm.com        sprintf(obuf, "0x%016llx: envp[%d] = 0x%016llx\n",
1937760SGiacomo.Gabrielli@arm.com                sp, envCount++, cenvp);
1947648SAli.Saidi@ARM.com        os << obuf;
19510037SARM gem5 Developers        sp += 8;
19610037SARM gem5 Developers    } while(cenvp);
1977322Sgblack@eecs.umich.edu    uint64_t auxType, auxVal;
1987324Sgblack@eecs.umich.edu    do
1997644Sali.saidi@arm.com    {
2007643Sgblack@eecs.umich.edu        auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
2017643Sgblack@eecs.umich.edu        sp += 8;
2027643Sgblack@eecs.umich.edu        auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
2037643Sgblack@eecs.umich.edu        sp += 8;
2047643Sgblack@eecs.umich.edu        sprintf(obuf, "0x%016llx: Auxiliary vector = {0x%016llx, 0x%016llx}\n",
2057760SGiacomo.Gabrielli@arm.com                sp - 8, auxType, auxVal);
2067783SGiacomo.Gabrielli@arm.com        os << obuf;
2078070SAli.Saidi@ARM.com    } while(auxType != 0 || auxVal != 0);
2088070SAli.Saidi@ARM.com    //Print out the argument strings, environment strings, and file name.
2097643Sgblack@eecs.umich.edu    string current;
2107643Sgblack@eecs.umich.edu    uint64_t buf;
2117643Sgblack@eecs.umich.edu    uint64_t currentStart = sp;
2127643Sgblack@eecs.umich.edu    bool clearedInitialPadding = false;
21310037SARM gem5 Developers    do
21410037SARM gem5 Developers    {
21510037SARM gem5 Developers        buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0);
21610037SARM gem5 Developers        char * cbuf = (char *)&buf;
21710037SARM gem5 Developers        for(int x = 0; x < sizeof(uint64_t); x++)
21810037SARM gem5 Developers        {
21912106SRekai.GonzalezAlberquilla@arm.com            if(cbuf[x])
22010037SARM gem5 Developers                current += cbuf[x];
22110037SARM gem5 Developers            else
22210037SARM gem5 Developers            {
22310037SARM gem5 Developers                sprintf(obuf, "0x%016llx: \"%s\"\n",
22410037SARM gem5 Developers                        currentStart, current.c_str());
22510037SARM gem5 Developers                os << obuf;
22610037SARM gem5 Developers                current = "";
22710037SARM gem5 Developers                currentStart = sp + x + 1;
22810037SARM gem5 Developers            }
22910474Sandreas.hansson@arm.com        }
23010037SARM gem5 Developers        sp += 8;
23110037SARM gem5 Developers        clearedInitialPadding = clearedInitialPadding || buf != 0;
23210037SARM gem5 Developers    } while(!clearedInitialPadding || buf != 0);
23310037SARM gem5 Developers    return os;
23410037SARM gem5 Developers}
23510037SARM gem5 Developers
23610037SARM gem5 DevelopersTraceChild * genTraceChild()
23710037SARM gem5 Developers{
2387760SGiacomo.Gabrielli@arm.com        return new AMD64TraceChild;
2397783SGiacomo.Gabrielli@arm.com}
2407783SGiacomo.Gabrielli@arm.com