tracechild.cc revision 5049
12SN/A/* 28733Sgeoffrey.blake@arm.com * Copyright (c) 2007 The Regents of The University of Michigan 38733Sgeoffrey.blake@arm.com * All rights reserved. 48733Sgeoffrey.blake@arm.com * 58733Sgeoffrey.blake@arm.com * Redistribution and use in source and binary forms, with or without 68733Sgeoffrey.blake@arm.com * modification, are permitted provided that the following conditions are 78733Sgeoffrey.blake@arm.com * met: redistributions of source code must retain the above copyright 88733Sgeoffrey.blake@arm.com * notice, this list of conditions and the following disclaimer; 98733Sgeoffrey.blake@arm.com * redistributions in binary form must reproduce the above copyright 108733Sgeoffrey.blake@arm.com * notice, this list of conditions and the following disclaimer in the 118733Sgeoffrey.blake@arm.com * documentation and/or other materials provided with the distribution; 128733Sgeoffrey.blake@arm.com * neither the name of the copyright holders nor the names of its 138733Sgeoffrey.blake@arm.com * contributors may be used to endorse or promote products derived from 142188SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272SN/A * 282SN/A * Authors: Gabe Black 292SN/A */ 302SN/A 312SN/A#include <iostream> 322SN/A#include <iomanip> 332SN/A#include <errno.h> 342SN/A#include <sys/ptrace.h> 352SN/A#include <stdint.h> 362SN/A 372SN/A#include "tracechild_amd64.hh" 382SN/A 392665SN/Ausing namespace std; 402665SN/A 412665SN/Achar * AMD64TraceChild::regNames[numregs] = { 422SN/A //GPRs 432SN/A "rax", "rbx", "rcx", "rdx", 442683Sktlim@umich.edu //Index registers 452683Sktlim@umich.edu "rsi", "rdi", 462SN/A //Base pointer and stack pointer 479020Sgblack@eecs.umich.edu "rbp", "rsp", 486313Sgblack@eecs.umich.edu //New 64 bit mode registers 492190SN/A "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 506329Sgblack@eecs.umich.edu //Segmentation registers 514997Sgblack@eecs.umich.edu "cs", "ds", "es", "fs", "gs", "ss", "fs_base", "gs_base", 526316Sgblack@eecs.umich.edu //PC 536216Snate@binkert.org "rip", 546658Snate@binkert.org //Flags 552680SN/A "eflags", 562683Sktlim@umich.edu //MMX 578232Snate@binkert.org "mmx0_0", "mmx0_1", 588232Snate@binkert.org "mmx1_0", "mmx1_1", 598777Sgblack@eecs.umich.edu "mmx2_0", "mmx2_1", 602395SN/A "mmx3_0", "mmx3_1", 612190SN/A "mmx4_0", "mmx4_1", 622188SN/A "mmx5_0", "mmx5_1", 638777Sgblack@eecs.umich.edu "mmx6_0", "mmx6_1", 64217SN/A "mmx7_0", "mmx7_1", 658777Sgblack@eecs.umich.edu //XMM 662SN/A "xmm0_0", "xmm0_1", "xmm0_2", "xmm0_3", 672SN/A "xmm1_0", "xmm1_1", "xmm1_2", "xmm1_3", 688887Sgeoffrey.blake@arm.com "xmm2_0", "xmm2_1", "xmm2_2", "xmm2_3", 691070SN/A "xmm3_0", "xmm3_1", "xmm3_2", "xmm3_3", 701917SN/A "xmm4_0", "xmm4_1", "xmm4_2", "xmm4_3", 711917SN/A "xmm5_0", "xmm5_1", "xmm5_2", "xmm5_3", 722521SN/A "xmm6_0", "xmm6_1", "xmm6_2", "xmm6_3", 733548Sgblack@eecs.umich.edu "xmm7_0", "xmm7_1", "xmm7_2", "xmm7_3", 743548Sgblack@eecs.umich.edu "xmm8_0", "xmm8_1", "xmm8_2", "xmm8_3", 753548Sgblack@eecs.umich.edu "xmm9_0", "xmm9_1", "xmm9_2", "xmm9_3", 768902Sandreas.hansson@arm.com "xmm10_0", "xmm10_1", "xmm10_2", "xmm10_3", 778902Sandreas.hansson@arm.com "xmm11_0", "xmm11_1", "xmm11_2", "xmm11_3", 782330SN/A "xmm12_0", "xmm12_1", "xmm12_2", "xmm12_3", 792683Sktlim@umich.edu "xmm13_0", "xmm13_1", "xmm13_2", "xmm13_3", 802683Sktlim@umich.edu "xmm14_0", "xmm14_1", "xmm14_2", "xmm14_3", 812683Sktlim@umich.edu "xmm15_0", "xmm15_1", "xmm15_2", "xmm15_3"}; 822683Sktlim@umich.edu 832683Sktlim@umich.edubool AMD64TraceChild::sendState(int socket) 842683Sktlim@umich.edu{ 852683Sktlim@umich.edu uint64_t regVal64 = 0; 862683Sktlim@umich.edu uint32_t regVal32 = 0; 872683Sktlim@umich.edu for(int x = 0; x <= R15; x++) 882683Sktlim@umich.edu { 892683Sktlim@umich.edu regVal64 = getRegVal(x); 902683Sktlim@umich.edu if(write(socket, ®Val64, sizeof(regVal64)) == -1) 912683Sktlim@umich.edu { 922683Sktlim@umich.edu cerr << "Write failed! " << strerror(errno) << endl; 932683Sktlim@umich.edu tracing = false; 942SN/A return false; 952683Sktlim@umich.edu } 962SN/A } 972107SN/A regVal64 = getRegVal(RIP); 982107SN/A if(write(socket, ®Val64, sizeof(regVal64)) == -1) 992159SN/A { 1002455SN/A cerr << "Write failed! " << strerror(errno) << endl; 1012455SN/A tracing = false; 1022SN/A return false; 1032680SN/A } 1042SN/A for(int x = MMX0_0; x <= MMX7_1; x++) 1052190SN/A { 1066315Sgblack@eecs.umich.edu regVal32 = getRegVal(x); 1076315Sgblack@eecs.umich.edu if(write(socket, ®Val32, sizeof(regVal32)) == -1) 1086315Sgblack@eecs.umich.edu { 1096315Sgblack@eecs.umich.edu cerr << "Write failed! " << strerror(errno) << endl; 1106316Sgblack@eecs.umich.edu tracing = false; 1119384SAndreas.Sandberg@arm.com return false; 1122SN/A } 1137720Sgblack@eecs.umich.edu } 1146324Sgblack@eecs.umich.edu for(int x = XMM0_0; x <= XMM15_3; x++) 1157597Sminkyu.jeong@arm.com { 1167597Sminkyu.jeong@arm.com regVal32 = getRegVal(x); 1177597Sminkyu.jeong@arm.com if(write(socket, ®Val32, sizeof(regVal32)) == -1) 1182190SN/A { 1198357Sksewell@umich.edu cerr << "Write failed! " << strerror(errno) << endl; 1208357Sksewell@umich.edu tracing = false; 1218735Sandreas.hanson@arm.com return false; 1228357Sksewell@umich.edu } 1238357Sksewell@umich.edu } 1242683Sktlim@umich.edu return true; 1252188SN/A} 1262378SN/A 1272400SN/Aint64_t AMD64TraceChild::getRegs(user_regs_struct & myregs, 1286022Sgblack@eecs.umich.edu user_fpregs_struct & myfpregs, int num) 1296022Sgblack@eecs.umich.edu{ 1302SN/A assert(num < numregs && num >= 0); 1319020Sgblack@eecs.umich.edu switch(num) 1328541Sgblack@eecs.umich.edu { 1332683Sktlim@umich.edu //GPRs 1348793Sgblack@eecs.umich.edu case RAX: return myregs.rax; 1352683Sktlim@umich.edu case RBX: return myregs.rbx; 1369384SAndreas.Sandberg@arm.com case RCX: return myregs.rcx; 1372683Sktlim@umich.edu case RDX: return myregs.rdx; 1388793Sgblack@eecs.umich.edu //Index registers 1398820Sgblack@eecs.umich.edu case RSI: return myregs.rsi; 1409384SAndreas.Sandberg@arm.com case RDI: return myregs.rdi; 1419384SAndreas.Sandberg@arm.com //Base pointer and stack pointer 1422862Sktlim@umich.edu case RBP: return myregs.rbp; 1432864Sktlim@umich.edu case RSP: return myregs.rsp; 1442862Sktlim@umich.edu //New 64 bit mode registers 1452683Sktlim@umich.edu case R8: return myregs.r8; 1462SN/A case R9: return myregs.r9; 1472680SN/A case R10: return myregs.r10; 148180SN/A case R11: return myregs.r11; 1492SN/A case R12: return myregs.r12; 1502SN/A case R13: return myregs.r13; 1512864Sktlim@umich.edu case R14: return myregs.r14; 1522864Sktlim@umich.edu case R15: return myregs.r15; 1532862Sktlim@umich.edu //Segmentation registers 1542862Sktlim@umich.edu case CS: return myregs.cs; 155217SN/A case DS: return myregs.ds; 156237SN/A case ES: return myregs.es; 157217SN/A case FS: return myregs.fs; 1582683Sktlim@umich.edu case GS: return myregs.gs; 1592683Sktlim@umich.edu case SS: return myregs.ss; 1605891Sgblack@eecs.umich.edu case FS_BASE: return myregs.fs_base; 1612683Sktlim@umich.edu case GS_BASE: return myregs.gs_base; 1622190SN/A //PC 1632683Sktlim@umich.edu case RIP: return myregs.rip; 1642683Sktlim@umich.edu //Flags 1652683Sktlim@umich.edu case EFLAGS: return myregs.eflags; 1662683Sktlim@umich.edu //MMX 1672680SN/A case MMX0_0: return myfpregs.st_space[0]; 1682190SN/A case MMX0_1: return myfpregs.st_space[1]; 1695358Sgblack@eecs.umich.edu case MMX1_0: return myfpregs.st_space[2]; 1705358Sgblack@eecs.umich.edu case MMX1_1: return myfpregs.st_space[3]; 1715358Sgblack@eecs.umich.edu case MMX2_0: return myfpregs.st_space[4]; 1725358Sgblack@eecs.umich.edu case MMX2_1: return myfpregs.st_space[5]; 1735358Sgblack@eecs.umich.edu case MMX3_0: return myfpregs.st_space[6]; 1745358Sgblack@eecs.umich.edu case MMX3_1: return myfpregs.st_space[7]; 1755358Sgblack@eecs.umich.edu case MMX4_0: return myfpregs.st_space[8]; 1765358Sgblack@eecs.umich.edu case MMX4_1: return myfpregs.st_space[9]; 1775358Sgblack@eecs.umich.edu case MMX5_0: return myfpregs.st_space[10]; 1785358Sgblack@eecs.umich.edu case MMX5_1: return myfpregs.st_space[11]; 1795358Sgblack@eecs.umich.edu case MMX6_0: return myfpregs.st_space[12]; 1805358Sgblack@eecs.umich.edu case MMX6_1: return myfpregs.st_space[13]; 1815358Sgblack@eecs.umich.edu case MMX7_0: return myfpregs.st_space[14]; 1825358Sgblack@eecs.umich.edu case MMX7_1: return myfpregs.st_space[15]; 1835358Sgblack@eecs.umich.edu //XMM 1845358Sgblack@eecs.umich.edu case XMM0_0: return myfpregs.xmm_space[0]; 1852683Sktlim@umich.edu case XMM0_1: return myfpregs.xmm_space[1]; 1862521SN/A case XMM0_2: return myfpregs.xmm_space[2]; 1875702Ssaidi@eecs.umich.edu case XMM0_3: return myfpregs.xmm_space[3]; 1885702Ssaidi@eecs.umich.edu case XMM1_0: return myfpregs.xmm_space[4]; 1895702Ssaidi@eecs.umich.edu case XMM1_1: return myfpregs.xmm_space[5]; 1905702Ssaidi@eecs.umich.edu case XMM1_2: return myfpregs.xmm_space[6]; 1912683Sktlim@umich.edu case XMM1_3: return myfpregs.xmm_space[7]; 1922683Sktlim@umich.edu case XMM2_0: return myfpregs.xmm_space[8]; 1932683Sktlim@umich.edu case XMM2_1: return myfpregs.xmm_space[9]; 1942683Sktlim@umich.edu case XMM2_2: return myfpregs.xmm_space[10]; 1958735Sandreas.hanson@arm.com case XMM2_3: return myfpregs.xmm_space[11]; 1962683Sktlim@umich.edu case XMM3_0: return myfpregs.xmm_space[12]; 1976022Sgblack@eecs.umich.edu case XMM3_1: return myfpregs.xmm_space[13]; 1982683Sktlim@umich.edu case XMM3_2: return myfpregs.xmm_space[14]; 1996022Sgblack@eecs.umich.edu case XMM3_3: return myfpregs.xmm_space[15]; 2002683Sktlim@umich.edu case XMM4_0: return myfpregs.xmm_space[16]; 2018887Sgeoffrey.blake@arm.com case XMM4_1: return myfpregs.xmm_space[17]; 2028733Sgeoffrey.blake@arm.com case XMM4_2: return myfpregs.xmm_space[18]; 2039020Sgblack@eecs.umich.edu case XMM4_3: return myfpregs.xmm_space[19]; 2048541Sgblack@eecs.umich.edu case XMM5_0: return myfpregs.xmm_space[20]; 2054997Sgblack@eecs.umich.edu case XMM5_1: return myfpregs.xmm_space[21]; 2064997Sgblack@eecs.umich.edu case XMM5_2: return myfpregs.xmm_space[22]; 2072683Sktlim@umich.edu case XMM5_3: return myfpregs.xmm_space[23]; 2082683Sktlim@umich.edu case XMM6_0: return myfpregs.xmm_space[24]; 2092683Sktlim@umich.edu case XMM6_1: return myfpregs.xmm_space[25]; 2102683Sktlim@umich.edu case XMM6_2: return myfpregs.xmm_space[26]; 2112683Sktlim@umich.edu case XMM6_3: return myfpregs.xmm_space[27]; 2122683Sktlim@umich.edu case XMM7_0: return myfpregs.xmm_space[28]; 2139180Sandreas.hansson@arm.com case XMM7_1: return myfpregs.xmm_space[29]; 2142683Sktlim@umich.edu case XMM7_2: return myfpregs.xmm_space[30]; 2152683Sktlim@umich.edu case XMM7_3: return myfpregs.xmm_space[31]; 2162683Sktlim@umich.edu case XMM8_0: return myfpregs.xmm_space[32]; 2172683Sktlim@umich.edu case XMM8_1: return myfpregs.xmm_space[33]; 2182683Sktlim@umich.edu case XMM8_2: return myfpregs.xmm_space[34]; 2192683Sktlim@umich.edu case XMM8_3: return myfpregs.xmm_space[35]; 2202683Sktlim@umich.edu case XMM9_0: return myfpregs.xmm_space[36]; 2212SN/A case XMM9_1: return myfpregs.xmm_space[37]; 2222SN/A case XMM9_2: return myfpregs.xmm_space[38]; 2232683Sktlim@umich.edu case XMM9_3: return myfpregs.xmm_space[39]; 2242190SN/A case XMM10_0: return myfpregs.xmm_space[40]; 2256315Sgblack@eecs.umich.edu case XMM10_1: return myfpregs.xmm_space[41]; 2266315Sgblack@eecs.umich.edu case XMM10_2: return myfpregs.xmm_space[42]; 2277720Sgblack@eecs.umich.edu case XMM10_3: return myfpregs.xmm_space[43]; 2286316Sgblack@eecs.umich.edu case XMM11_0: return myfpregs.xmm_space[44]; 2296315Sgblack@eecs.umich.edu case XMM11_1: return myfpregs.xmm_space[45]; 2309384SAndreas.Sandberg@arm.com case XMM11_2: return myfpregs.xmm_space[46]; 2316315Sgblack@eecs.umich.edu case XMM11_3: return myfpregs.xmm_space[47]; 2322190SN/A case XMM12_0: return myfpregs.xmm_space[48]; 2332SN/A case XMM12_1: return myfpregs.xmm_space[49]; 2342SN/A case XMM12_2: return myfpregs.xmm_space[50]; 2352SN/A case XMM12_3: return myfpregs.xmm_space[51]; 2362SN/A case XMM13_0: return myfpregs.xmm_space[52]; 2372SN/A case XMM13_1: return myfpregs.xmm_space[53]; 2389384SAndreas.Sandberg@arm.com case XMM13_2: return myfpregs.xmm_space[54]; 2396323Sgblack@eecs.umich.edu case XMM13_3: return myfpregs.xmm_space[55]; 2406418Sgblack@eecs.umich.edu case XMM14_0: return myfpregs.xmm_space[56]; 2417601Sminkyu.jeong@arm.com case XMM14_1: return myfpregs.xmm_space[57]; 2427601Sminkyu.jeong@arm.com case XMM14_2: return myfpregs.xmm_space[58]; 2436418Sgblack@eecs.umich.edu case XMM14_3: return myfpregs.xmm_space[59]; 2442SN/A case XMM15_0: return myfpregs.xmm_space[60]; 2452SN/A case XMM15_1: return myfpregs.xmm_space[61]; 2462455SN/A case XMM15_2: return myfpregs.xmm_space[62]; 2472SN/A case XMM15_3: return myfpregs.xmm_space[63]; 2489384SAndreas.Sandberg@arm.com default: 2496323Sgblack@eecs.umich.edu assert(0); 2507341Sgblack@eecs.umich.edu return 0; 2517601Sminkyu.jeong@arm.com } 2527601Sminkyu.jeong@arm.com} 2537341Sgblack@eecs.umich.edu 2542SN/Abool AMD64TraceChild::update(int pid) 2552SN/A{ 2562455SN/A oldregs = regs; 2572455SN/A oldfpregs = fpregs; 2589384SAndreas.Sandberg@arm.com if(ptrace(PTRACE_GETREGS, pid, 0, ®s) != 0) 2596323Sgblack@eecs.umich.edu { 2607341Sgblack@eecs.umich.edu cerr << "update: " << strerror(errno) << endl; 2617601Sminkyu.jeong@arm.com return false; 2627601Sminkyu.jeong@arm.com } 2637341Sgblack@eecs.umich.edu if(ptrace(PTRACE_GETFPREGS, pid, 0, &fpregs) != 0) 2642SN/A { 2652SN/A cerr << "update: " << strerror(errno) << endl; 2662SN/A return false; 2672SN/A } 2689384SAndreas.Sandberg@arm.com for(unsigned int x = 0; x < numregs; x++) 2696323Sgblack@eecs.umich.edu regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x)); 2707601Sminkyu.jeong@arm.com return true; 2717601Sminkyu.jeong@arm.com} 2726316Sgblack@eecs.umich.edu 2732SN/AAMD64TraceChild::AMD64TraceChild() 2742SN/A{ 2752455SN/A for(unsigned int x = 0; x < numregs; x++) 2762SN/A regDiffSinceUpdate[x] = false; 2779384SAndreas.Sandberg@arm.com} 2786323Sgblack@eecs.umich.edu 2796315Sgblack@eecs.umich.eduint64_t AMD64TraceChild::getRegVal(int num) 2807601Sminkyu.jeong@arm.com{ 2817601Sminkyu.jeong@arm.com return getRegs(regs, fpregs, num); 2822SN/A} 2832SN/A 2842455SN/Aint64_t AMD64TraceChild::getOldRegVal(int num) 2852455SN/A{ 2869384SAndreas.Sandberg@arm.com return getRegs(oldregs, oldfpregs, num); 2876323Sgblack@eecs.umich.edu} 2888733Sgeoffrey.blake@arm.com 2898733Sgeoffrey.blake@arm.comchar * AMD64TraceChild::printReg(int num) 2908733Sgeoffrey.blake@arm.com{ 2918733Sgeoffrey.blake@arm.com sprintf(printBuffer, "0x%08X", getRegVal(num)); 2927601Sminkyu.jeong@arm.com return printBuffer; 2937601Sminkyu.jeong@arm.com} 2942SN/A 2952SN/Aostream & AMD64TraceChild::outputStartState(ostream & os) 2967720Sgblack@eecs.umich.edu{ 2977720Sgblack@eecs.umich.edu uint64_t sp = getSP(); 2982SN/A uint64_t pc = getPC(); 2997720Sgblack@eecs.umich.edu uint64_t highestInfo = 0; 3002SN/A char obuf[1024]; 3012SN/A sprintf(obuf, "Initial stack pointer = 0x%016llx\n", sp); 3027720Sgblack@eecs.umich.edu os << obuf; 3037720Sgblack@eecs.umich.edu sprintf(obuf, "Initial program counter = 0x%016llx\n", pc); 3042190SN/A os << obuf; 3057720Sgblack@eecs.umich.edu 3062190SN/A //Output the argument count 3072190SN/A uint64_t cargc = ptrace(PTRACE_PEEKDATA, pid, sp, 0); 3088733Sgeoffrey.blake@arm.com sprintf(obuf, "0x%016llx: Argc = 0x%016llx\n", sp, cargc); 3098733Sgeoffrey.blake@arm.com os << obuf; 3108733Sgeoffrey.blake@arm.com sp += 8; 3118733Sgeoffrey.blake@arm.com 3128733Sgeoffrey.blake@arm.com //Output argv pointers 3138733Sgeoffrey.blake@arm.com int argCount = 0; 3147720Sgblack@eecs.umich.edu uint64_t cargv; 3157720Sgblack@eecs.umich.edu do 3163276Sgblack@eecs.umich.edu { 3177720Sgblack@eecs.umich.edu cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0); 3183276Sgblack@eecs.umich.edu sprintf(obuf, "0x%016llx: argv[%d] = 0x%016llx\n", 3193276Sgblack@eecs.umich.edu sp, argCount++, cargv); 3207720Sgblack@eecs.umich.edu if(cargv) 3217720Sgblack@eecs.umich.edu if(highestInfo < cargv) 3223276Sgblack@eecs.umich.edu highestInfo = cargv; 3237720Sgblack@eecs.umich.edu os << obuf; 3243276Sgblack@eecs.umich.edu sp += 8; 3253276Sgblack@eecs.umich.edu } while(cargv); 3267720Sgblack@eecs.umich.edu 3277720Sgblack@eecs.umich.edu //Output the envp pointers 3282190SN/A int envCount = 0; 3297720Sgblack@eecs.umich.edu uint64_t cenvp; 3302251SN/A do 3312251SN/A { 3327597Sminkyu.jeong@arm.com cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0); 3337597Sminkyu.jeong@arm.com sprintf(obuf, "0x%016llx: envp[%d] = 0x%016llx\n", 3347597Sminkyu.jeong@arm.com sp, envCount++, cenvp); 3357597Sminkyu.jeong@arm.com os << obuf; 3367597Sminkyu.jeong@arm.com sp += 8; 3377597Sminkyu.jeong@arm.com } while(cenvp); 3387597Sminkyu.jeong@arm.com uint64_t auxType, auxVal; 3397597Sminkyu.jeong@arm.com do 3407597Sminkyu.jeong@arm.com { 3417597Sminkyu.jeong@arm.com auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0); 3426221Snate@binkert.org sp += 8; 3436221Snate@binkert.org auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0); 3444172Ssaidi@eecs.umich.edu sp += 8; 3459384SAndreas.Sandberg@arm.com sprintf(obuf, "0x%016llx: Auxiliary vector = {0x%016llx, 0x%016llx}\n", 3464172Ssaidi@eecs.umich.edu sp - 16, auxType, auxVal); 3474172Ssaidi@eecs.umich.edu os << obuf; 3486221Snate@binkert.org } while(auxType != 0 || auxVal != 0); 3496221Snate@binkert.org //Print out the argument strings, environment strings, and file name. 3502SN/A string current; 3519384SAndreas.Sandberg@arm.com uint64_t buf; 3522SN/A uint64_t currentStart = sp; 3532SN/A bool clearedInitialPadding = false; 3546221Snate@binkert.org do 3556221Snate@binkert.org { 3562SN/A buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0); 3579384SAndreas.Sandberg@arm.com char * cbuf = (char *)&buf; 3582SN/A for(int x = 0; x < sizeof(uint64_t); x++) 3592SN/A { 3606221Snate@binkert.org if(cbuf[x]) 3616221Snate@binkert.org current += cbuf[x]; 3622SN/A else 3639384SAndreas.Sandberg@arm.com { 3646313Sgblack@eecs.umich.edu sprintf(obuf, "0x%016llx: \"%s\"\n", 3656313Sgblack@eecs.umich.edu currentStart, current.c_str()); 3666313Sgblack@eecs.umich.edu os << obuf; 3676313Sgblack@eecs.umich.edu current = ""; 3686313Sgblack@eecs.umich.edu currentStart = sp + x + 1; 3699384SAndreas.Sandberg@arm.com } 3706313Sgblack@eecs.umich.edu } 3716313Sgblack@eecs.umich.edu sp += 8; 3726313Sgblack@eecs.umich.edu clearedInitialPadding = clearedInitialPadding || buf != 0; 3736313Sgblack@eecs.umich.edu } while(!clearedInitialPadding || buf != 0 || sp <= highestInfo); 3746313Sgblack@eecs.umich.edu return os; 3759384SAndreas.Sandberg@arm.com} 3762SN/A 3772SN/Auint64_t AMD64TraceChild::findSyscall() 3782190SN/A{ 3792190SN/A uint64_t rip = getPC(); 3802190SN/A bool foundOpcode = false; 3812190SN/A bool twoByteOpcode = false; 3822190SN/A for(;;) 3832561SN/A { 3842SN/A uint64_t buf = ptrace(PTRACE_PEEKDATA, pid, rip, 0); 3852680SN/A for(int i = 0; i < sizeof(uint64_t); i++) 3862SN/A { 3872SN/A unsigned char byte = buf & 0xFF; 3882SN/A if(!foundOpcode) 3892SN/A { 3902SN/A if(!(byte == 0x66 || //operand override 3912SN/A byte == 0x67 || //address override 3922683Sktlim@umich.edu byte == 0x2E || //cs 3932SN/A byte == 0x3E || //ds 3942SN/A byte == 0x26 || //es 3952SN/A byte == 0x64 || //fs 3962SN/A byte == 0x65 || //gs 3972190SN/A byte == 0x36 || //ss 398 byte == 0xF0 || //lock 399 byte == 0xF2 || //repe 400 byte == 0xF3 || //repne 401 (byte >= 0x40 && byte <= 0x4F) // REX 402 )) 403 { 404 foundOpcode = true; 405 } 406 } 407 if(foundOpcode) 408 { 409 if(twoByteOpcode) 410 { 411 //SYSCALL or SYSENTER 412 if(byte == 0x05 || byte == 0x34) 413 return rip + 1; 414 else 415 return 0; 416 } 417 if(!twoByteOpcode) 418 { 419 if(byte == 0xCC) // INT3 420 return rip + 1; 421 else if(byte == 0xCD) // INT with byte immediate 422 return rip + 2; 423 else if(byte == 0x0F) // two byte opcode prefix 424 twoByteOpcode = true; 425 else 426 return 0; 427 } 428 } 429 buf >>= 8; 430 rip++; 431 } 432 } 433} 434 435bool AMD64TraceChild::step() 436{ 437 uint64_t ripAfterSyscall = findSyscall(); 438 if(ripAfterSyscall) 439 { 440 //Get the original contents of memory 441 uint64_t buf = ptrace(PTRACE_PEEKDATA, pid, ripAfterSyscall, 0); 442 //Patch the first two bytes of the memory immediately after this with 443 //jmp -2. Either single stepping will take over before this 444 //instruction, leaving the rip where it should be, or it will take 445 //over after this instruction, -still- leaving the rip where it should 446 //be. 447 uint64_t newBuf = (buf & ~0xFFFF) | 0xFEEB; 448 //Write the patched memory to the processes address space 449 ptrace(PTRACE_POKEDATA, pid, ripAfterSyscall, newBuf); 450 //Step and hit it 451 ptraceSingleStep(); 452 //Put things back to the way they started 453 ptrace(PTRACE_POKEDATA, pid, ripAfterSyscall, buf); 454 } 455 else 456 { 457 //Get all the way past repe and repne string instructions in one shot. 458 uint64_t newPC, origPC = getPC(); 459 do 460 { 461 ptraceSingleStep(); 462 newPC = getPC(); 463 } while(newPC == origPC); 464 } 465} 466 467TraceChild * genTraceChild() 468{ 469 return new AMD64TraceChild; 470} 471