• 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 #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