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