2 * Copyright (c) 2006-2009 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include "tracechild_arm.hh"
41 const char* ARMTraceChild::regNames
[numregs
] = {
42 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
43 "r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc",
47 ARMTraceChild::ARMTraceChild()
49 for (int x
= 0; x
< numregs
; x
++)
50 regDiffSinceUpdate
[x
] = false;
53 bool ARMTraceChild::sendState(int socket
)
56 for(int x
= 0; x
< numregs
; x
++)
58 regVal
= getRegVal(x
);
59 if(write(socket
, ®Val
, sizeof(regVal
)) == -1)
61 cerr
<< "Write failed! " << strerror(errno
) << endl
;
71 uint32_t ARMTraceChild::getRegs(user_regs
&myregs
, int num
)
73 assert(num
< numregs
&& num
>= 0);
74 return myregs
.uregs
[num
];
77 bool ARMTraceChild::update(int pid
)
80 if(ptrace(PTRACE_GETREGS
, pid
, 0, ®s
) != 0)
82 cerr
<< "update: " << strerror(errno
) << endl
;
86 for(unsigned int x
= 0; x
< numregs
; x
++)
87 regDiffSinceUpdate
[x
] = (getRegVal(x
) != getOldRegVal(x
));
91 int64_t ARMTraceChild::getRegVal(int num
)
93 return getRegs(regs
, num
);
96 int64_t ARMTraceChild::getOldRegVal(int num
)
98 return getRegs(oldregs
, num
);
101 char * ARMTraceChild::printReg(int num
)
103 sprintf(printBuffer
, "0x%08X", (uint32_t)getRegVal(num
));
107 ostream
& ARMTraceChild::outputStartState(ostream
& os
)
109 uint32_t sp
= getSP();
110 uint32_t pc
= getPC();
111 uint32_t highestInfo
= 0;
113 sprintf(obuf
, "Initial stack pointer = 0x%08x\n", sp
);
115 sprintf(obuf
, "Initial program counter = 0x%08x\n", pc
);
118 //Output the argument count
119 int32_t cargc
= ptrace(PTRACE_PEEKDATA
, pid
, sp
, 0);
120 sprintf(obuf
, "0x%08x: Argc = 0x%08x\n", sp
, cargc
);
124 //Output argv pointers
129 cargv
= ptrace(PTRACE_PEEKDATA
, pid
, sp
, 0);
130 sprintf(obuf
, "0x%08x: argv[%d] = 0x%08x\n",
131 sp
, argCount
++, cargv
);
133 if(highestInfo
< cargv
)
139 //Output the envp pointers
144 cenvp
= ptrace(PTRACE_PEEKDATA
, pid
, sp
, 0);
145 sprintf(obuf
, "0x%08x: envp[%d] = 0x%08x\n",
146 sp
, envCount
++, cenvp
);
150 uint32_t auxType
, auxVal
;
153 auxType
= ptrace(PTRACE_PEEKDATA
, pid
, sp
, 0);
155 auxVal
= ptrace(PTRACE_PEEKDATA
, pid
, sp
, 0);
157 sprintf(obuf
, "0x%08x: Auxiliary vector = {0x%08x, 0x%08x}\n",
158 sp
- 8, auxType
, auxVal
);
160 } while(auxType
!= 0 || auxVal
!= 0);
161 //Print out the argument strings, environment strings, and file name.
164 uint32_t currentStart
= sp
;
165 bool clearedInitialPadding
= false;
168 buf
= ptrace(PTRACE_PEEKDATA
, pid
, sp
, 0);
169 char * cbuf
= (char *)&buf
;
170 for(int x
= 0; x
< sizeof(uint32_t); x
++)
176 sprintf(obuf
, "0x%08x: \"%s\"\n",
177 currentStart
, current
.c_str());
180 currentStart
= sp
+ x
+ 1;
184 clearedInitialPadding
= clearedInitialPadding
|| buf
!= 0;
185 } while(!clearedInitialPadding
|| buf
!= 0 || sp
<= highestInfo
);
189 bool ARMTraceChild::step()
192 const uint32_t bkpt_inst
= 0xE1200070;
193 const uint32_t bkpt_mask
= 0xFFF000F0;
195 const uint32_t swi_inst
= 0x0F0000000;
196 const uint32_t swi_mask
= 0x0F0000000;
198 uint32_t next_op
= ptrace(PTRACE_PEEKDATA
, pid
, getPC(), 0);
199 if ((next_op
& swi_mask
) == swi_inst
) {
200 ptrace(PTRACE_POKEDATA
, pid
, next_op
+ sizeof(uint32_t), bkpt_inst
);
202 ptrace(PTRACE_POKEDATA
, pid
, next_op
+ sizeof(uint32_t), next_op
);
211 TraceChild
* genTraceChild()
213 return new ARMTraceChild
;