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, ®Val, 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, ®Val, 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, ®s) != 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