1# $FreeBSD$
2# Assembler-level macros for i386
3# Disassemble the next 10 instructions.
4define xi
5x/10i $eip
6end
7
8# Top 12 words on stack
9define xs
10x/12x $esp
11end
12
13# Top 12 words from frame pointer
14define xb
15x/12x $ebp
16end
17
18# single step through calls and disassemble the next instruction
19define z
20ni
21x/1i $eip
22end
23
24# single step over calls and disassemble the next instruction
25define zs
26si
27x/1i $eip
28end
29
30# show current stack frame and first 4 parameters
31define xp
32printf "      esp: " 
33output/x $esp
34echo  (
35output (((int)$ebp)-(int)$esp)/4-4
36printf " words on stack)\n      ebp: " 
37output/x $ebp
38printf "\n      eip: " 
39x/1i $eip
40printf "Saved ebp: " 
41output/x *(int*)$ebp
42printf " (maximum of "  
43output ((*(int*)$ebp)-(int)$ebp)/4-4
44printf " parameters possible)\nSaved eip: " 
45x/1i *(int*)($ebp+4)
46printf "\nParm 1 at " 
47output/x (int) ($ebp+8)
48printf ":    " 
49output (char*) *(int*)($ebp+8)
50printf "\nParm 2 at " 
51output/x (int) ($ebp+12)
52printf ":    " 
53output (char*) *(int*)($ebp+12)
54printf "\nParm 3 at " 
55output/x (int) ($ebp+16)
56printf ":    " 
57output (char*) *(int*)($ebp+16)
58printf "\nParm 4 at " 
59output/x (int) ($ebp+20)
60printf ":    " 
61output (char*) *(int*)($ebp+20)
62echo \n
63end
64document xp
65Show the register contents and the first four parameter
66words of the current frame.
67end
68
69# show current stack frame and first 10 parameters
70define xxp
71printf "      esp: " 
72output/x $esp
73printf "\n      ebp: " 
74output/x $ebp
75printf "\n      eip: " 
76x/1i $eip
77printf "Saved ebp: " 
78output/x *(int*)$ebp
79printf " (maximum of "  
80output ((*(int*)$ebp)-(int)$ebp)/4-4
81printf " parameters possible)\nSaved eip: " 
82x/1i *(int*)($ebp+4)
83printf "\nParm  1 at " 
84output/x (int) ($ebp+8)
85printf ":    " 
86output (char*) *(int*)($ebp+8)
87printf "\nParm  2 at " 
88output/x (int) ($ebp+12)
89printf ":    " 
90output (char*) *(int*)($ebp+12)
91printf "\nParm  3 at " 
92output/x (int) ($ebp+16)
93printf ":    " 
94output (char*) *(int*)($ebp+16)
95printf "\nParm  4 at " 
96output/x (int) ($ebp+20)
97printf ":    " 
98output (char*) *(int*)($ebp+20)
99printf "\nParm  5 at " 
100output/x (int) ($ebp+24)
101printf ":    " 
102output (char*) *(int*)($ebp+24)
103printf "\nParm  6 at " 
104output/x (int) ($ebp+28)
105printf ":    " 
106output (char*) *(int*)($ebp+28)
107printf "\nParm  7 at " 
108output/x (int) ($ebp+32)
109printf ":    " 
110output (char*) *(int*)($ebp+32)
111printf "\nParm  8 at " 
112output/x (int) ($ebp+36)
113printf ":    " 
114output (char*) *(int*)($ebp+36)
115printf "\nParm  9 at " 
116output/x (int) ($ebp+40)
117printf ":    " 
118output (char*) *(int*)($ebp+40)
119printf "\nParm 10 at " 
120output/x (int) ($ebp+44)
121printf ":    " 
122output (char*) *(int*)($ebp+44)
123echo \n
124end
125document xxp
126Show the register contents and the first ten parameter
127words of the current frame.
128end
129
130# Show first to fifth parameters of current frame as int, int * and char *.
131define xp0
132x/12x *(int*)$esp
133p *(int*)$esp
134p (char*)*$esp
135end
136define xp1
137x/12x *(int*)($ebp+4)
138p *(int*)($ebp+4)
139p (char**)($ebp+4)
140end
141define xp2
142x/12x *(int*)($ebp+8)
143p *(int*)($ebp+8)
144p *(char**)($ebp+8)
145end
146define xp3
147x/12x *(int*)($ebp+12)
148p *(int*)($ebp+12)
149p (char**)($ebp+12)
150end
151define xp4
152x/12x *(int*)($ebp+16)
153p *(int*)($ebp+16)
154p (char**)($ebp+16)
155end
156document xp0
157Show the first parameter of current stack frame in various formats
158end
159document xp1
160Show the second parameter of current stack frame in various formats
161end
162document xp2
163Show the third parameter of current stack frame in various formats
164end
165document xp3
166Show the fourth parameter of current stack frame in various formats
167end
168document xp4
169Show the fifth parameter of current stack frame in various formats
170end
171
172# Select frame 0 to 5 and show stack information.
173define f0
174f 0
175xp
176end
177define f1
178f 1
179xp
180end
181define f2
182f 2
183xp
184end
185define f3
186f 3
187xp
188end
189define f4
190f 4
191xp
192end
193define f5
194f 5
195xp
196end
197document f0
198Select stack frame 0 and show assembler-level details
199end
200document f1
201Select stack frame 1 and show assembler-level details
202end
203document f2
204Select stack frame 2 and show assembler-level details
205end
206document f3
207Select stack frame 3 and show assembler-level details
208end
209document f4
210Select stack frame 4 and show assembler-level details
211end
212document f5
213Select stack frame 5 and show assembler-level details
214end
215document z
216Single step 1 instruction (over calls) and show next instruction.
217end
218document zs
219Single step 1 instruction (through calls) and show next instruction.
220end
221document xi
222List the next 10 instructions from the current IP value
223end
224document xs
225Show the last 12 words on stack in hex
226end
227document xb
228Show 12 words starting at current BP value in hex
229end
230
231# pcb <pid>
232# show contents of pcb, currently only i386.
233define pcb
234    set $nproc = nprocs
235    set $aproc = allproc.lh_first
236    set $proc = allproc.lh_first
237    while (--$nproc >= 0)
238        set $pptr = $proc.p_pptr
239        if ($proc->p_pid == $arg0)
240           set $pcba = $proc->p_threads.tqh_first->td_pcb
241	   printf "ip: %08x sp: %08x bp: %08x bx: %08x\n", $pcba->pcb_eip, $pcba->pcb_esp, $pcba->pcb_ebp, $pcba->pcb_ebx
242	   x/1i $pcba->pcb_eip
243	   set $nproc = 0
244        end
245        set $aproc = $proc.p_list.le_next
246        if ($aproc == 0 && $nproc > 0)
247            set $aproc = zombproc
248        end
249        set $proc = $aproc
250    end
251end
252document pcb
253Show some pcb contents of process whose pid is specified.
254end
255
256# btr <frame>
257# primitive backtrace.  frame is a memory address.
258define btr
259set $frame = $arg0
260set $fno = 0
261while (*(int *) $frame > 0xc0000000)
262  set $myebp = *(int *) $frame
263  set $myeip = *(int *) ($frame + 4)
264  printf " frame %d at %p: ebp %8x, eip ", $fno, $frame, $myebp
265  x/1i $myeip
266  set $frame = $myebp
267  set $fno = $fno + 1
268end
269end
270document btr
271Show a backtrace from the ebp address specified.  This can be used to get a backtrace from any stack resident in memory.  It's the user's responsibility to ensure that the address is meaningful.
272end
273
274# btp <pid>
275# backtrace for process <pid>.  Uses btr (machine dependent) to perform the backtrace.
276# may produce nonsense.
277define btp
278    set $nproc = nprocs
279    set $aproc = allproc.lh_first
280    set $proc = allproc.lh_first
281    while (--$nproc >= 0)
282        if ($proc->p_pid == $arg0)
283	   btr $proc->p_threads.tqh_first->td_pcb->pcb_ebp
284	   set $nproc = 0
285	else
286           set $aproc = $proc.p_list.le_next
287           if ($aproc == 0 && $nproc > 0)
288              set $aproc = zombproc
289           end
290           set $proc = $aproc
291        end
292   end
293end
294document btp
295Show a backtrace for the process whose pid is specified as a parameter.
296end
297
298# Do backtraces for all processes in the system.
299# Uses btr (machine dependent) to perform the backtrace.
300define btpa
301    set $nproc = nprocs
302    set $aproc = allproc.lh_first
303    set $proc = allproc.lh_first
304    printf "  pid    proc   uid  ppid  pgrp   flag stat comm         wchan\n"
305    while (--$nproc >= 0)
306        set $pptr = $proc.p_pptr
307        if ($pptr == 0)
308           set $pptr = $proc
309        end
310        if ($proc.p_stat)
311            printf "%5d %08x %4d %5d %5d  %06x %d  %-10s   ", \
312                   $proc.p_pid, $aproc, \
313                   $proc.p_cred->p_ruid, $pptr->p_pid, \
314                   $proc.p_pgrp->pg_id, $proc.p_flag, $proc.p_stat, \
315                   &$proc.p_comm[0]
316            if ($proc.p_wchan)
317                if ($proc.p_wmesg)
318                    printf "%s ", $proc.p_wmesg
319                end
320                printf "%x", $proc.p_wchan
321            end
322            printf "\n"
323	   if ($proc->p_flag & 4)
324	      btr $proc->p_threads.tqh_first->td_pcb->pcb_ebp
325	   else
326              echo (not loaded)\n
327	   end
328        end
329        set $aproc = $proc.p_list.le_next
330        if ($aproc == 0 && $nproc > 0)
331            set $aproc = zombproc
332        end
333        set $proc = $aproc
334    end
335end
336document btpa
337Show backtraces for all processes in the system.
338end
339
340# Show backtrace for process selected with "defproc"
341define btpp
342btr $myvectorproc->p_threads.tqh_first->td_pcb->pcb_ebp
343end
344document btpp
345Show a backtrace for the process previously selected with 'defproc'.
346end
347
348# Specific stack fram of process selected with "defproc".
349define fr
350set $fno = 0
351set $searching = 1
352set $frame = $myvectorproc->p_threads.tqh_first->td_pcb->pcb_ebp
353while (($searching == 1) && (*(int *) $frame > 0xc0000000))
354  set $myebp = *(int *) $frame
355  set $myeip = *(int *) ($frame + 4)
356  if ($fno == $arg0)
357    printf " frame %d at %p: ebp %8x, eip ", $fno, $frame, $myebp
358    x/1i $myeip
359    printf "Called from %8x, stack frame at %8x\n", *(int *) ($myebp+4), *(int *) $myebp
360    printf "last 20 local variables:\n"
361    x/20x ($myebp-80)
362    printf "call parameters:\n"
363    x/8x ($myebp+8)
364    set $searching = 0
365  else
366    set $frame = $myebp
367    set $fno = $fno + 1
368  end
369end
370if ($searching == 1)
371  echo frame not found\n
372end
373end
374document fr
375Show the frame of the stack of the process previously selected with 'defproc'.
376end
377