1 /* ARM EABI compliant unwinding routines.
2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Paul Brook
4
5 This file is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
8 later version.
9
10 In addition to the permissions in the GNU General Public License, the
11 Free Software Foundation gives you unlimited permission to link the
12 compiled version of this file into combinations with other programs,
13 and to distribute those combinations without any restriction coming
14 from the use of this file. (The General Public License restrictions
15 do apply in other respects; for example, they cover modification of
16 the file, and distribution when not linked into a combine
17 executable.)
18
19 This file is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
27 Boston, MA 02110-1301, USA. */
28
29 /****************************************************************************
30 * The functions here are derived from gcc/config/arm/unwind-arm.c from the
31 * 4.3.x release. The main changes here involve the use of ptrace to retrieve
32 * memory/processor states from a remote process.
33 ****************************************************************************/
34
35 #include <cutils/logd.h>
36 #include <sys/ptrace.h>
37 #include <unwind.h>
38 #include "utility.h"
39
40 #include "symbol_table.h"
41
42 typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */
43
44 void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp);
45 bool __attribute__((weak)) __cxa_begin_cleanup(_Unwind_Control_Block *ucbp);
46 bool __attribute__((weak)) __cxa_type_match(_Unwind_Control_Block *ucbp,
47 const type_info *rttip,
48 bool is_reference,
49 void **matched_object);
50
51 /* Misc constants. */
52 #define R_IP 12
53 #define R_SP 13
54 #define R_LR 14
55 #define R_PC 15
56
57 #define EXIDX_CANTUNWIND 1
58 #define uint32_highbit (((_uw) 1) << 31)
59
60 #define UCB_FORCED_STOP_FN(ucbp) ((ucbp)->unwinder_cache.reserved1)
61 #define UCB_PR_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved2)
62 #define UCB_SAVED_CALLSITE_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved3)
63 #define UCB_FORCED_STOP_ARG(ucbp) ((ucbp)->unwinder_cache.reserved4)
64
65 struct core_regs
66 {
67 _uw r[16];
68 };
69
70 /* We use normal integer types here to avoid the compiler generating
71 coprocessor instructions. */
72 struct vfp_regs
73 {
74 _uw64 d[16];
75 _uw pad;
76 };
77
78 struct vfpv3_regs
79 {
80 /* Always populated via VSTM, so no need for the "pad" field from
81 vfp_regs (which is used to store the format word for FSTMX). */
82 _uw64 d[16];
83 };
84
85 struct fpa_reg
86 {
87 _uw w[3];
88 };
89
90 struct fpa_regs
91 {
92 struct fpa_reg f[8];
93 };
94
95 struct wmmxd_regs
96 {
97 _uw64 wd[16];
98 };
99
100 struct wmmxc_regs
101 {
102 _uw wc[4];
103 };
104
105 /* Unwind descriptors. */
106
107 typedef struct
108 {
109 _uw16 length;
110 _uw16 offset;
111 } EHT16;
112
113 typedef struct
114 {
115 _uw length;
116 _uw offset;
117 } EHT32;
118
119 /* The ABI specifies that the unwind routines may only use core registers,
120 except when actually manipulating coprocessor state. This allows
121 us to write one implementation that works on all platforms by
122 demand-saving coprocessor registers.
123
124 During unwinding we hold the coprocessor state in the actual hardware
125 registers and allocate demand-save areas for use during phase1
126 unwinding. */
127
128 typedef struct
129 {
130 /* The first fields must be the same as a phase2_vrs. */
131 _uw demand_save_flags;
132 struct core_regs core;
133 _uw prev_sp; /* Only valid during forced unwinding. */
134 struct vfp_regs vfp;
135 struct vfpv3_regs vfp_regs_16_to_31;
136 struct fpa_regs fpa;
137 struct wmmxd_regs wmmxd;
138 struct wmmxc_regs wmmxc;
139 } phase1_vrs;
140
141 /* This must match the structure created by the assembly wrappers. */
142 typedef struct
143 {
144 _uw demand_save_flags;
145 struct core_regs core;
146 } phase2_vrs;
147
148
149 /* An exception index table entry. */
150
151 typedef struct __EIT_entry
152 {
153 _uw fnoffset;
154 _uw content;
155 } __EIT_entry;
156
157 /* Derived version to use ptrace */
158 typedef _Unwind_Reason_Code (*personality_routine_with_ptrace)
159 (_Unwind_State,
160 _Unwind_Control_Block *,
161 _Unwind_Context *,
162 pid_t);
163
164 /* Derived version to use ptrace */
165 /* ABI defined personality routines. */
166 static _Unwind_Reason_Code unwind_cpp_pr0_with_ptrace (_Unwind_State,
167 _Unwind_Control_Block *, _Unwind_Context *, pid_t);
168 static _Unwind_Reason_Code unwind_cpp_pr1_with_ptrace (_Unwind_State,
169 _Unwind_Control_Block *, _Unwind_Context *, pid_t);
170 static _Unwind_Reason_Code unwind_cpp_pr2_with_ptrace (_Unwind_State,
171 _Unwind_Control_Block *, _Unwind_Context *, pid_t);
172
173 /* Execute the unwinding instructions described by UWS. */
174 extern _Unwind_Reason_Code
175 unwind_execute_with_ptrace(_Unwind_Context * context, __gnu_unwind_state * uws,
176 pid_t pid);
177
178 /* Derived version to use ptrace. Only handles core registers. Disregards
179 * FP and others.
180 */
181 /* ABI defined function to pop registers off the stack. */
182
unwind_VRS_Pop_with_ptrace(_Unwind_Context * context,_Unwind_VRS_RegClass regclass,_uw discriminator,_Unwind_VRS_DataRepresentation representation,pid_t pid)183 _Unwind_VRS_Result unwind_VRS_Pop_with_ptrace (_Unwind_Context *context,
184 _Unwind_VRS_RegClass regclass,
185 _uw discriminator,
186 _Unwind_VRS_DataRepresentation representation,
187 pid_t pid)
188 {
189 phase1_vrs *vrs = (phase1_vrs *) context;
190
191 switch (regclass)
192 {
193 case _UVRSC_CORE:
194 {
195 _uw *ptr;
196 _uw mask;
197 int i;
198
199 if (representation != _UVRSD_UINT32)
200 return _UVRSR_FAILED;
201
202 mask = discriminator & 0xffff;
203 ptr = (_uw *) vrs->core.r[R_SP];
204 /* Pop the requested registers. */
205 for (i = 0; i < 16; i++)
206 {
207 if (mask & (1 << i)) {
208 vrs->core.r[i] = get_remote_word(pid, ptr);
209 ptr++;
210 }
211 }
212 /* Writeback the stack pointer value if it wasn't restored. */
213 if ((mask & (1 << R_SP)) == 0)
214 vrs->core.r[R_SP] = (_uw) ptr;
215 }
216 return _UVRSR_OK;
217
218 default:
219 return _UVRSR_FAILED;
220 }
221 }
222
223 /* Core unwinding functions. */
224
225 /* Calculate the address encoded by a 31-bit self-relative offset at address
226 P. */
227 static inline _uw
selfrel_offset31(const _uw * p,pid_t pid)228 selfrel_offset31 (const _uw *p, pid_t pid)
229 {
230 _uw offset = get_remote_word(pid, (void*)p);
231
232 //offset = *p;
233 /* Sign extend to 32 bits. */
234 if (offset & (1 << 30))
235 offset |= 1u << 31;
236 else
237 offset &= ~(1u << 31);
238
239 return offset + (_uw) p;
240 }
241
242
243 /* Perform a binary search for RETURN_ADDRESS in TABLE. The table contains
244 NREC entries. */
245
246 static const __EIT_entry *
search_EIT_table(const __EIT_entry * table,int nrec,_uw return_address,pid_t pid)247 search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address,
248 pid_t pid)
249 {
250 _uw next_fn;
251 _uw this_fn;
252 int n, left, right;
253
254 if (nrec == 0)
255 return (__EIT_entry *) 0;
256
257 left = 0;
258 right = nrec - 1;
259
260 while (1)
261 {
262 n = (left + right) / 2;
263 this_fn = selfrel_offset31 (&table[n].fnoffset, pid);
264 if (n != nrec - 1)
265 next_fn = selfrel_offset31 (&table[n + 1].fnoffset, pid) - 1;
266 else
267 next_fn = (_uw)0 - 1;
268
269 if (return_address < this_fn)
270 {
271 if (n == left)
272 return (__EIT_entry *) 0;
273 right = n - 1;
274 }
275 else if (return_address <= next_fn)
276 return &table[n];
277 else
278 left = n + 1;
279 }
280 }
281
282 /* Find the exception index table eintry for the given address. */
283 static const __EIT_entry*
get_eitp(_uw return_address,pid_t pid,mapinfo * map,mapinfo ** containing_map)284 get_eitp(_uw return_address, pid_t pid, mapinfo *map, mapinfo **containing_map)
285 {
286 const __EIT_entry *eitp = NULL;
287 int nrec;
288 mapinfo *mi;
289
290 /* The return address is the address of the instruction following the
291 call instruction (plus one in thumb mode). If this was the last
292 instruction in the function the address will lie in the following
293 function. Subtract 2 from the address so that it points within the call
294 instruction itself. */
295 if (return_address >= 2)
296 return_address -= 2;
297
298 for (mi = map; mi != NULL; mi = mi->next) {
299 if (return_address >= mi->start && return_address <= mi->end) break;
300 }
301
302 if (mi) {
303 if (containing_map) *containing_map = mi;
304 eitp = (__EIT_entry *) mi->exidx_start;
305 nrec = (mi->exidx_end - mi->exidx_start)/sizeof(__EIT_entry);
306 eitp = search_EIT_table (eitp, nrec, return_address, pid);
307 }
308 return eitp;
309 }
310
311 /* Find the exception index table eintry for the given address.
312 Fill in the relevant fields of the UCB.
313 Returns _URC_FAILURE if an error occurred, _URC_OK on success. */
314
315 static _Unwind_Reason_Code
get_eit_entry(_Unwind_Control_Block * ucbp,_uw return_address,pid_t pid,mapinfo * map,mapinfo ** containing_map)316 get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address, pid_t pid,
317 mapinfo *map, mapinfo **containing_map)
318 {
319 const __EIT_entry *eitp;
320
321 eitp = get_eitp(return_address, pid, map, containing_map);
322
323 if (!eitp)
324 {
325 UCB_PR_ADDR (ucbp) = 0;
326 return _URC_FAILURE;
327 }
328 ucbp->pr_cache.fnstart = selfrel_offset31 (&eitp->fnoffset, pid);
329
330 _uw eitp_content = get_remote_word(pid, (void *)&eitp->content);
331
332 /* Can this frame be unwound at all? */
333 if (eitp_content == EXIDX_CANTUNWIND)
334 {
335 UCB_PR_ADDR (ucbp) = 0;
336 return _URC_END_OF_STACK;
337 }
338
339 /* Obtain the address of the "real" __EHT_Header word. */
340
341 if (eitp_content & uint32_highbit)
342 {
343 /* It is immediate data. */
344 ucbp->pr_cache.ehtp = (_Unwind_EHT_Header *)&eitp->content;
345 ucbp->pr_cache.additional = 1;
346 }
347 else
348 {
349 /* The low 31 bits of the content field are a self-relative
350 offset to an _Unwind_EHT_Entry structure. */
351 ucbp->pr_cache.ehtp =
352 (_Unwind_EHT_Header *) selfrel_offset31 (&eitp->content, pid);
353 ucbp->pr_cache.additional = 0;
354 }
355
356 /* Discover the personality routine address. */
357 if (get_remote_word(pid, ucbp->pr_cache.ehtp) & (1u << 31))
358 {
359 /* One of the predefined standard routines. */
360 _uw idx = (get_remote_word(pid, ucbp->pr_cache.ehtp) >> 24) & 0xf;
361 if (idx == 0)
362 UCB_PR_ADDR (ucbp) = (_uw) &unwind_cpp_pr0_with_ptrace;
363 else if (idx == 1)
364 UCB_PR_ADDR (ucbp) = (_uw) &unwind_cpp_pr1_with_ptrace;
365 else if (idx == 2)
366 UCB_PR_ADDR (ucbp) = (_uw) &unwind_cpp_pr2_with_ptrace;
367 else
368 { /* Failed */
369 UCB_PR_ADDR (ucbp) = 0;
370 return _URC_FAILURE;
371 }
372 }
373 else
374 {
375 /* Execute region offset to PR */
376 UCB_PR_ADDR (ucbp) = selfrel_offset31 (ucbp->pr_cache.ehtp, pid);
377 /* Since we are unwinding the stack from a different process, it is
378 * impossible to execute the personality routine in debuggerd. Punt here.
379 */
380 return _URC_FAILURE;
381 }
382 return _URC_OK;
383 }
384
385 /* Print out the current call level, pc, and module name in the crash log */
log_function(_Unwind_Context * context,pid_t pid,int tfd,int stack_level,mapinfo * map,unsigned int sp_list[],bool at_fault)386 static _Unwind_Reason_Code log_function(_Unwind_Context *context, pid_t pid,
387 int tfd,
388 int stack_level,
389 mapinfo *map,
390 unsigned int sp_list[],
391 bool at_fault)
392 {
393 _uw pc;
394 _uw rel_pc;
395 phase2_vrs *vrs = (phase2_vrs*) context;
396 const mapinfo *mi;
397 bool only_in_tombstone = !at_fault;
398 const struct symbol* sym = 0;
399
400 if (stack_level < STACK_CONTENT_DEPTH) {
401 sp_list[stack_level] = vrs->core.r[R_SP];
402 }
403 pc = vrs->core.r[R_PC];
404
405 // Top level frame
406 if (stack_level == 0) {
407 pc &= ~1;
408 }
409 // For deeper framers, rollback pc by one instruction
410 else {
411 pc = vrs->core.r[R_PC];
412 /* Thumb mode - need to check whether the bl(x) has long offset or not.
413 * Examples:
414 *
415 * arm blx in the middle of thumb:
416 * 187ae: 2300 movs r3, #0
417 * 187b0: f7fe ee1c blx 173ec
418 * 187b4: 2c00 cmp r4, #0
419 *
420 * arm bl in the middle of thumb:
421 * 187d8: 1c20 adds r0, r4, #0
422 * 187da: f136 fd15 bl 14f208
423 * 187de: 2800 cmp r0, #0
424 *
425 * pure thumb:
426 * 18894: 189b adds r3, r3, r2
427 * 18896: 4798 blx r3
428 * 18898: b001 add sp, #4
429 */
430 if (pc & 1) {
431 _uw prev_word;
432 pc = (pc & ~1);
433 prev_word = get_remote_word(pid, (char *) pc-4);
434 // Long offset
435 if ((prev_word & 0xf0000000) == 0xf0000000 &&
436 (prev_word & 0x0000e000) == 0x0000e000) {
437 pc -= 4;
438 }
439 else {
440 pc -= 2;
441 }
442 }
443 else {
444 pc -= 4;
445 }
446 }
447
448 /* We used to print the absolute PC in the back trace, and mask out the top
449 * 3 bits to guesstimate the offset in the .so file. This is not working for
450 * non-prelinked libraries since the starting offset may not be aligned on
451 * 1MB boundaries, and the library may be larger than 1MB. So for .so
452 * addresses we print the relative offset in back trace.
453 */
454 mi = pc_to_mapinfo(map, pc, &rel_pc);
455
456 /* See if we can determine what symbol this stack frame resides in */
457 if (mi != 0 && mi->symbols != 0) {
458 sym = symbol_table_lookup(mi->symbols, rel_pc);
459 }
460
461 if (sym) {
462 _LOG(tfd, only_in_tombstone,
463 " #%02d pc %08x %s (%s)\n", stack_level, rel_pc,
464 mi ? mi->name : "", sym->name);
465 } else {
466 _LOG(tfd, only_in_tombstone,
467 " #%02d pc %08x %s\n", stack_level, rel_pc,
468 mi ? mi->name : "");
469 }
470
471 return _URC_NO_REASON;
472 }
473
474 /* Derived from __gnu_Unwind_Backtrace to use ptrace */
475 /* Perform stack backtrace through unwind data. Return the level of stack it
476 * unwinds.
477 */
unwind_backtrace_with_ptrace(int tfd,pid_t pid,mapinfo * map,unsigned int sp_list[],int * frame0_pc_sane,bool at_fault)478 int unwind_backtrace_with_ptrace(int tfd, pid_t pid, mapinfo *map,
479 unsigned int sp_list[], int *frame0_pc_sane,
480 bool at_fault)
481 {
482 phase1_vrs saved_vrs;
483 _Unwind_Reason_Code code = _URC_OK;
484 struct pt_regs r;
485 int i;
486 int stack_level = 0;
487
488 _Unwind_Control_Block ucb;
489 _Unwind_Control_Block *ucbp = &ucb;
490
491 if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return 0;
492
493 for (i = 0; i < 16; i++) {
494 saved_vrs.core.r[i] = r.uregs[i];
495 /*
496 _LOG(tfd, "r[%d] = 0x%x\n", i, saved_vrs.core.r[i]);
497 */
498 }
499
500 /* Set demand-save flags. */
501 saved_vrs.demand_save_flags = ~(_uw) 0;
502
503 /*
504 * If the app crashes because of calling the weeds, we cannot pass the PC
505 * to the usual unwinding code as the EXIDX mapping will fail.
506 * Instead, we simply print out the 0 as the top frame, and resume the
507 * unwinding process with the value stored in LR.
508 */
509 if (get_eitp(saved_vrs.core.r[R_PC], pid, map, NULL) == NULL) {
510 *frame0_pc_sane = 0;
511 log_function ((_Unwind_Context *) &saved_vrs, pid, tfd, stack_level,
512 map, sp_list, at_fault);
513 saved_vrs.core.r[R_PC] = saved_vrs.core.r[R_LR];
514 stack_level++;
515 }
516
517 do {
518 mapinfo *this_map = NULL;
519 /* Find the entry for this routine. */
520 if (get_eit_entry(ucbp, saved_vrs.core.r[R_PC], pid, map, &this_map)
521 != _URC_OK) {
522 /* Uncomment the code below to study why the unwinder failed */
523 #if 0
524 /* Shed more debugging info for stack unwinder improvement */
525 if (this_map) {
526 _LOG(tfd, 1,
527 "Relative PC=%#x from %s not contained in EXIDX\n",
528 saved_vrs.core.r[R_PC] - this_map->start, this_map->name);
529 }
530 _LOG(tfd, 1, "PC=%#x SP=%#x\n",
531 saved_vrs.core.r[R_PC], saved_vrs.core.r[R_SP]);
532 #endif
533 code = _URC_FAILURE;
534 break;
535 }
536
537 /* The dwarf unwinder assumes the context structure holds things
538 like the function and LSDA pointers. The ARM implementation
539 caches these in the exception header (UCB). To avoid
540 rewriting everything we make the virtual IP register point at
541 the UCB. */
542 _Unwind_SetGR((_Unwind_Context *)&saved_vrs, 12, (_Unwind_Ptr) ucbp);
543
544 /* Call log function. */
545 if (log_function ((_Unwind_Context *) &saved_vrs, pid, tfd, stack_level,
546 map, sp_list, at_fault) != _URC_NO_REASON) {
547 code = _URC_FAILURE;
548 break;
549 }
550 stack_level++;
551
552 /* Call the pr to decide what to do. */
553 code = ((personality_routine_with_ptrace) UCB_PR_ADDR (ucbp))(
554 _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND, ucbp,
555 (void *) &saved_vrs, pid);
556 /*
557 * In theory the unwinding process will stop when the end of stack is
558 * reached or there is no unwinding information for the code address.
559 * To add another level of guarantee that the unwinding process
560 * will terminate we will stop it when the STACK_CONTENT_DEPTH is reached.
561 */
562 } while (code != _URC_END_OF_STACK && code != _URC_FAILURE &&
563 stack_level < STACK_CONTENT_DEPTH);
564 return stack_level;
565 }
566
567
568 /* Derived version to use ptrace */
569 /* Common implementation for ARM ABI defined personality routines.
570 ID is the index of the personality routine, other arguments are as defined
571 by __aeabi_unwind_cpp_pr{0,1,2}. */
572
573 static _Unwind_Reason_Code
unwind_pr_common_with_ptrace(_Unwind_State state,_Unwind_Control_Block * ucbp,_Unwind_Context * context,int id,pid_t pid)574 unwind_pr_common_with_ptrace (_Unwind_State state,
575 _Unwind_Control_Block *ucbp,
576 _Unwind_Context *context,
577 int id,
578 pid_t pid)
579 {
580 __gnu_unwind_state uws;
581 _uw *data;
582 int phase2_call_unexpected_after_unwind = 0;
583
584 state &= _US_ACTION_MASK;
585
586 data = (_uw *) ucbp->pr_cache.ehtp;
587 uws.data = get_remote_word(pid, data);
588 data++;
589 uws.next = data;
590 if (id == 0)
591 {
592 uws.data <<= 8;
593 uws.words_left = 0;
594 uws.bytes_left = 3;
595 }
596 else
597 {
598 uws.words_left = (uws.data >> 16) & 0xff;
599 uws.data <<= 16;
600 uws.bytes_left = 2;
601 data += uws.words_left;
602 }
603
604 /* Restore the saved pointer. */
605 if (state == _US_UNWIND_FRAME_RESUME)
606 data = (_uw *) ucbp->cleanup_cache.bitpattern[0];
607
608 if ((ucbp->pr_cache.additional & 1) == 0)
609 {
610 /* Process descriptors. */
611 while (get_remote_word(pid, data)) {
612 /**********************************************************************
613 * The original code here seems to deal with exceptions that are not
614 * applicable in our toolchain, thus there is no way to test it for now.
615 * Instead of leaving it here and causing potential instability in
616 * debuggerd, we'd better punt here and leave the stack unwound.
617 * In the future when we discover cases where the stack should be unwound
618 * further but is not, we can revisit the code here.
619 **********************************************************************/
620 return _URC_FAILURE;
621 }
622 /* Finished processing this descriptor. */
623 }
624
625 if (unwind_execute_with_ptrace (context, &uws, pid) != _URC_OK)
626 return _URC_FAILURE;
627
628 if (phase2_call_unexpected_after_unwind)
629 {
630 /* Enter __cxa_unexpected as if called from the call site. */
631 _Unwind_SetGR (context, R_LR, _Unwind_GetGR (context, R_PC));
632 _Unwind_SetGR (context, R_PC, (_uw) &__cxa_call_unexpected);
633 return _URC_INSTALL_CONTEXT;
634 }
635
636 return _URC_CONTINUE_UNWIND;
637 }
638
639
640 /* ABI defined personality routine entry points. */
641
642 static _Unwind_Reason_Code
unwind_cpp_pr0_with_ptrace(_Unwind_State state,_Unwind_Control_Block * ucbp,_Unwind_Context * context,pid_t pid)643 unwind_cpp_pr0_with_ptrace (_Unwind_State state,
644 _Unwind_Control_Block *ucbp,
645 _Unwind_Context *context,
646 pid_t pid)
647 {
648 return unwind_pr_common_with_ptrace (state, ucbp, context, 0, pid);
649 }
650
651 static _Unwind_Reason_Code
unwind_cpp_pr1_with_ptrace(_Unwind_State state,_Unwind_Control_Block * ucbp,_Unwind_Context * context,pid_t pid)652 unwind_cpp_pr1_with_ptrace (_Unwind_State state,
653 _Unwind_Control_Block *ucbp,
654 _Unwind_Context *context,
655 pid_t pid)
656 {
657 return unwind_pr_common_with_ptrace (state, ucbp, context, 1, pid);
658 }
659
660 static _Unwind_Reason_Code
unwind_cpp_pr2_with_ptrace(_Unwind_State state,_Unwind_Control_Block * ucbp,_Unwind_Context * context,pid_t pid)661 unwind_cpp_pr2_with_ptrace (_Unwind_State state,
662 _Unwind_Control_Block *ucbp,
663 _Unwind_Context *context,
664 pid_t pid)
665 {
666 return unwind_pr_common_with_ptrace (state, ucbp, context, 2, pid);
667 }
668