1 /* go-unwind.c -- unwind the stack for panic/recover.
3 Copyright 2010 The Go Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file. */
16 /* These constants are documented here:
17 https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/dwarfext.html
20 #define DW_EH_PE_omit 0xff
21 #define DW_EH_PE_absptr 0x00
22 #define DW_EH_PE_uleb128 0x01
23 #define DW_EH_PE_udata2 0x02
24 #define DW_EH_PE_udata4 0x03
25 #define DW_EH_PE_udata8 0x04
26 #define DW_EH_PE_sleb128 0x09
27 #define DW_EH_PE_sdata2 0x0A
28 #define DW_EH_PE_sdata4 0x0B
29 #define DW_EH_PE_sdata8 0x0C
30 #define DW_EH_PE_pcrel 0x10
31 #define DW_EH_PE_textrel 0x20
32 #define DW_EH_PE_datarel 0x30
33 #define DW_EH_PE_funcrel 0x40
34 #define DW_EH_PE_aligned 0x50
35 #define DW_EH_PE_indirect 0x80
37 /* The code for a Go exception. */
39 #ifdef __ARM_EABI_UNWINDER__
40 static const _Unwind_Exception_Class __go_exception_class
=
41 { 'G', 'N', 'U', 'C', 'G', 'O', '\0', '\0' };
43 static const _Unwind_Exception_Class __go_exception_class
=
44 ((((((((_Unwind_Exception_Class
) 'G'
45 << 8 | (_Unwind_Exception_Class
) 'N')
46 << 8 | (_Unwind_Exception_Class
) 'U')
47 << 8 | (_Unwind_Exception_Class
) 'C')
48 << 8 | (_Unwind_Exception_Class
) 'G')
49 << 8 | (_Unwind_Exception_Class
) 'O')
50 << 8 | (_Unwind_Exception_Class
) '\0')
51 << 8 | (_Unwind_Exception_Class
) '\0');
54 /* Rethrow an exception. */
56 void rethrowException (void) __asm__(GOSYM_PREFIX
"runtime.rethrowException");
61 struct _Unwind_Exception
*hdr
;
63 hdr
= (struct _Unwind_Exception
*) runtime_g()->exception
;
65 #ifdef __USING_SJLJ_EXCEPTIONS__
66 _Unwind_SjLj_Resume_or_Rethrow (hdr
);
68 #if defined(_LIBUNWIND_STD_ABI)
69 _Unwind_RaiseException (hdr
);
71 _Unwind_Resume_or_Rethrow (hdr
);
75 /* Rethrowing the exception should not return. */
79 /* Return the size of the type that holds an exception header, so that
80 it can be allocated by Go code. */
82 uintptr
unwindExceptionSize(void)
83 __asm__ (GOSYM_PREFIX
"runtime.unwindExceptionSize");
86 unwindExceptionSize ()
90 ret
= sizeof (struct _Unwind_Exception
);
91 /* Adjust the size fo make sure that we can get an aligned value. */
92 align
= __alignof__ (struct _Unwind_Exception
);
93 if (align
> __alignof__ (uintptr
))
94 ret
+= align
- __alignof__ (uintptr
);
98 /* Throw an exception. This is called with g->exception pointing to
99 an uninitialized _Unwind_Exception instance. */
101 void throwException (void) __asm__(GOSYM_PREFIX
"runtime.throwException");
106 struct _Unwind_Exception
*hdr
;
109 hdr
= (struct _Unwind_Exception
*)runtime_g ()->exception
;
111 /* Make sure the value is correctly aligned. It will be large
112 enough, because of unwindExceptionSize. */
113 align
= __alignof__ (struct _Unwind_Exception
);
114 hdr
= ((struct _Unwind_Exception
*)
115 (((uintptr
) hdr
+ align
- 1) &~ (align
- 1)));
117 __builtin_memcpy (&hdr
->exception_class
, &__go_exception_class
,
118 sizeof hdr
->exception_class
);
119 hdr
->exception_cleanup
= NULL
;
121 #ifdef __USING_SJLJ_EXCEPTIONS__
122 _Unwind_SjLj_RaiseException (hdr
);
124 _Unwind_RaiseException (hdr
);
127 /* Raising an exception should not return. */
131 static inline _Unwind_Ptr
132 encoded_value_base (uint8_t encoding
, struct _Unwind_Context
*context
)
134 if (encoding
== DW_EH_PE_omit
)
136 switch (encoding
& 0x70)
138 case DW_EH_PE_absptr
:
140 case DW_EH_PE_aligned
:
142 case DW_EH_PE_textrel
:
143 return _Unwind_GetTextRelBase(context
);
144 case DW_EH_PE_datarel
:
145 return _Unwind_GetDataRelBase(context
);
146 case DW_EH_PE_funcrel
:
147 return _Unwind_GetRegionStart(context
);
152 /* Read an unsigned leb128 value. */
154 static inline const uint8_t *
155 read_uleb128 (const uint8_t *p
, _uleb128_t
*val
)
157 unsigned int shift
= 0;
158 _uleb128_t result
= 0;
164 result
|= ((_uleb128_t
)byte
& 0x7f) << shift
;
173 /* Similar, but read a signed leb128 value. */
175 static inline const uint8_t *
176 read_sleb128 (const uint8_t *p
, _sleb128_t
*val
)
178 unsigned int shift
= 0;
179 _uleb128_t result
= 0;
185 result
|= ((_uleb128_t
)byte
& 0x7f) << shift
;
191 if (shift
< (8 * sizeof(result
)) && (byte
& 0x40) != 0)
192 result
|= (((_uleb128_t
)~0) << shift
);
194 *val
= (_sleb128_t
)result
;
198 #define ROUND_UP_TO_PVB(x) (x + sizeof(void *) - 1) &- sizeof(void *)
200 static inline const uint8_t *
201 read_encoded_value (struct _Unwind_Context
*context
, uint8_t encoding
,
202 const uint8_t *p
, _Unwind_Ptr
*val
)
204 _Unwind_Ptr base
= encoded_value_base (encoding
, context
);
205 _Unwind_Internal_Ptr decoded
= 0;
206 const uint8_t *origp
= p
;
208 if (encoding
== DW_EH_PE_aligned
)
210 _Unwind_Internal_Ptr uip
= (_Unwind_Internal_Ptr
)p
;
211 uip
= ROUND_UP_TO_PVB (uip
);
212 decoded
= *(_Unwind_Internal_Ptr
*)uip
;
213 p
= (const uint8_t *)(uip
+ sizeof(void *));
217 switch (encoding
& 0x0f)
219 case DW_EH_PE_sdata2
:
222 __builtin_memcpy (&result
, p
, sizeof(int16_t));
224 p
+= sizeof(int16_t);
227 case DW_EH_PE_udata2
:
230 __builtin_memcpy (&result
, p
, sizeof(uint16_t));
232 p
+= sizeof(uint16_t);
235 case DW_EH_PE_sdata4
:
238 __builtin_memcpy (&result
, p
, sizeof(int32_t));
240 p
+= sizeof(int32_t);
243 case DW_EH_PE_udata4
:
246 __builtin_memcpy (&result
, p
, sizeof(uint32_t));
248 p
+= sizeof(uint32_t);
251 case DW_EH_PE_sdata8
:
254 __builtin_memcpy (&result
, p
, sizeof(int64_t));
256 p
+= sizeof(int64_t);
259 case DW_EH_PE_udata8
:
262 __builtin_memcpy (&result
, p
, sizeof(uint64_t));
264 p
+= sizeof(uint64_t);
267 case DW_EH_PE_uleb128
:
270 p
= read_uleb128 (p
, &value
);
271 decoded
= (_Unwind_Internal_Ptr
)value
;
274 case DW_EH_PE_sleb128
:
277 p
= read_sleb128 (p
, &value
);
278 decoded
= (_Unwind_Internal_Ptr
)value
;
281 case DW_EH_PE_absptr
:
282 __builtin_memcpy (&decoded
, (const void *)p
, sizeof(const void*));
295 if ((encoding
& 0x70) == DW_EH_PE_pcrel
)
296 decoded
+= ((_Unwind_Internal_Ptr
)origp
);
300 if ((encoding
& DW_EH_PE_indirect
) != 0)
301 decoded
= *(_Unwind_Internal_Ptr
*)decoded
;
308 value_size (uint8_t encoding
)
310 switch (encoding
& 0x0f)
312 case DW_EH_PE_sdata2
:
313 case DW_EH_PE_udata2
:
315 case DW_EH_PE_sdata4
:
316 case DW_EH_PE_udata4
:
318 case DW_EH_PE_sdata8
:
319 case DW_EH_PE_udata8
:
321 case DW_EH_PE_absptr
:
322 return sizeof(uintptr
);
329 /* The rest of this code is really similar to gcc/unwind-c.c and
330 libjava/exception.cc. */
336 _Unwind_Ptr ttype_base
;
337 const unsigned char *TType
;
338 const unsigned char *action_table
;
339 unsigned char ttype_encoding
;
340 unsigned char call_site_encoding
;
343 static const unsigned char *
344 parse_lsda_header (struct _Unwind_Context
*context
, const unsigned char *p
,
345 lsda_header_info
*info
)
348 unsigned char lpstart_encoding
;
350 info
->Start
= (context
? _Unwind_GetRegionStart (context
) : 0);
352 /* Find @LPStart, the base to which landing pad offsets are relative. */
353 lpstart_encoding
= *p
++;
354 if (lpstart_encoding
!= DW_EH_PE_omit
)
355 p
= read_encoded_value (context
, lpstart_encoding
, p
, &info
->LPStart
);
357 info
->LPStart
= info
->Start
;
359 /* Find @TType, the base of the handler and exception spec type data. */
360 info
->ttype_encoding
= *p
++;
361 if (info
->ttype_encoding
!= DW_EH_PE_omit
)
363 p
= read_uleb128 (p
, &tmp
);
364 info
->TType
= p
+ tmp
;
369 /* The encoding and length of the call-site table; the action table
370 immediately follows. */
371 info
->call_site_encoding
= *p
++;
372 p
= read_uleb128 (p
, &tmp
);
373 info
->action_table
= p
+ tmp
;
378 /* The personality function is invoked when unwinding the stack due to
379 a panic. Its job is to find the cleanup and exception handlers to
380 run. We can't split the stack here, because we won't be able to
381 unwind from that split. */
383 #ifdef __ARM_EABI_UNWINDER__
384 /* ARM EABI personality routines must also unwind the stack. */
385 #define CONTINUE_UNWINDING \
388 if (__gnu_unwind_frame (ue_header, context) != _URC_OK) \
389 return _URC_FAILURE; \
390 return _URC_CONTINUE_UNWIND; \
394 #define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND
397 #ifdef __ARM_EABI_UNWINDER__
398 #define STOP_UNWINDING _URC_FAILURE
400 #define STOP_UNWINDING _URC_NORMAL_STOP
403 #ifdef __USING_SJLJ_EXCEPTIONS__
404 #define PERSONALITY_FUNCTION __gccgo_personality_sj0
405 #define __builtin_eh_return_data_regno(x) x
407 #define PERSONALITY_FUNCTION __gccgo_personality_v0
410 #ifdef __ARM_EABI_UNWINDER__
412 PERSONALITY_FUNCTION (_Unwind_State
, struct _Unwind_Exception
*,
413 struct _Unwind_Context
*)
414 __attribute__ ((no_split_stack
, flatten
));
417 PERSONALITY_FUNCTION (_Unwind_State state
,
418 struct _Unwind_Exception
* ue_header
,
419 struct _Unwind_Context
* context
)
422 PERSONALITY_FUNCTION (int, _Unwind_Action
, _Unwind_Exception_Class
,
423 struct _Unwind_Exception
*, struct _Unwind_Context
*)
424 __attribute__ ((no_split_stack
, flatten
));
427 PERSONALITY_FUNCTION (int version
,
428 _Unwind_Action actions
,
429 _Unwind_Exception_Class exception_class
,
430 struct _Unwind_Exception
*ue_header
,
431 struct _Unwind_Context
*context
)
434 lsda_header_info info
;
435 const unsigned char *language_specific_data
, *p
, *action_record
;
436 _Unwind_Ptr landing_pad
, ip
;
437 int ip_before_insn
= 0;
441 #ifdef __ARM_EABI_UNWINDER__
442 _Unwind_Action actions
;
444 switch (state
& _US_ACTION_MASK
)
446 case _US_VIRTUAL_UNWIND_FRAME
:
447 if (state
& _UA_FORCE_UNWIND
)
448 /* We are called from _Unwind_Backtrace. No handler to run. */
450 actions
= _UA_SEARCH_PHASE
;
453 case _US_UNWIND_FRAME_STARTING
:
454 actions
= _UA_CLEANUP_PHASE
;
455 if (!(state
& _US_FORCE_UNWIND
)
456 && ue_header
->barrier_cache
.sp
== _Unwind_GetGR(context
, 13))
457 actions
|= _UA_HANDLER_FRAME
;
460 case _US_UNWIND_FRAME_RESUME
:
467 actions
|= state
& _US_FORCE_UNWIND
;
471 /* The dwarf unwinder assumes the context structure holds things like the
472 function and LSDA pointers. The ARM implementation caches these in
473 the exception header (UCB). To avoid rewriting everything we make the
474 virtual IP register point at the UCB. */
475 ip
= (_Unwind_Ptr
) ue_header
;
476 _Unwind_SetGR (context
, 12, ip
);
479 return _URC_FATAL_PHASE1_ERROR
;
481 is_foreign
= exception_class
!= __go_exception_class
;
484 language_specific_data
= (const unsigned char *)
485 _Unwind_GetLanguageSpecificData (context
);
487 /* If no LSDA, then there are no handlers or cleanups. */
488 if (! language_specific_data
)
491 /* Parse the LSDA header. */
492 p
= parse_lsda_header (context
, language_specific_data
, &info
);
493 #ifdef HAVE_GETIPINFO
494 ip
= _Unwind_GetIPInfo (context
, &ip_before_insn
);
496 ip
= _Unwind_GetIP (context
);
498 if (! ip_before_insn
)
501 action_record
= NULL
;
503 #ifdef __USING_SJLJ_EXCEPTIONS__
504 /* The given "IP" is an index into the call-site table, with two
505 exceptions -- -1 means no-action, and 0 means terminate. But
506 since we're using uleb128 values, we've not got random access
509 return _URC_CONTINUE_UNWIND
;
512 _uleb128_t cs_lp
, cs_action
;
515 p
= read_uleb128 (p
, &cs_lp
);
516 p
= read_uleb128 (p
, &cs_action
);
520 /* Can never have null landing pad for sjlj -- that would have
521 been indicated by a -1 call site index. */
522 landing_pad
= (_Unwind_Ptr
)cs_lp
+ 1;
524 action_record
= info
.action_table
+ cs_action
- 1;
525 goto found_something
;
528 /* Search the call-site table for the action associated with this IP. */
529 while (p
< info
.action_table
)
531 _Unwind_Ptr cs_start
, cs_len
, cs_lp
;
532 _uleb128_t cs_action
;
534 /* Note that all call-site encodings are "absolute" displacements. */
535 p
= read_encoded_value (0, info
.call_site_encoding
, p
, &cs_start
);
536 p
= read_encoded_value (0, info
.call_site_encoding
, p
, &cs_len
);
537 p
= read_encoded_value (0, info
.call_site_encoding
, p
, &cs_lp
);
538 p
= read_uleb128 (p
, &cs_action
);
540 /* The table is sorted, so if we've passed the ip, stop. */
541 if (ip
< info
.Start
+ cs_start
)
542 p
= info
.action_table
;
543 else if (ip
< info
.Start
+ cs_start
+ cs_len
)
546 landing_pad
= info
.LPStart
+ cs_lp
;
548 action_record
= info
.action_table
+ cs_action
- 1;
549 goto found_something
;
554 /* IP is not in table. No associated cleanups. */
558 if (landing_pad
== 0)
560 /* IP is present, but has a null landing pad.
561 No handler to be run. */
565 if (actions
& _UA_SEARCH_PHASE
)
567 if (action_record
== 0)
569 /* This indicates a cleanup rather than an exception
574 return _URC_HANDLER_FOUND
;
577 /* It's possible for g to be NULL here for an exception thrown by a
578 language other than Go. */
587 g
->exception
= ue_header
;
588 g
->isforeign
= is_foreign
;
591 _Unwind_SetGR (context
, __builtin_eh_return_data_regno (0),
592 (_Unwind_Ptr
) ue_header
);
593 _Unwind_SetGR (context
, __builtin_eh_return_data_regno (1), 0);
594 _Unwind_SetIP (context
, landing_pad
);
595 return _URC_INSTALL_CONTEXT
;
598 // A dummy personality function, which doesn't capture any exception
599 // and simply passes by. This is used for functions that don't
600 // capture exceptions but need LSDA for stack maps.
602 __gccgo_personality_dummy (int, _Unwind_Action
, _Unwind_Exception_Class
,
603 struct _Unwind_Exception
*, struct _Unwind_Context
*)
604 __attribute__ ((no_split_stack
));
607 __gccgo_personality_dummy (int version
__attribute__ ((unused
)),
608 _Unwind_Action actions
__attribute__ ((unused
)),
609 _Unwind_Exception_Class exception_class
__attribute__ ((unused
)),
610 struct _Unwind_Exception
*ue_header
__attribute__ ((unused
)),
611 struct _Unwind_Context
*context
__attribute__ ((unused
)))
616 // A sentinel value for Go functions.
617 // A function is a Go function if it has LSDA, which has type info,
618 // and the first (dummy) landing pad's type info is a pointer to
620 #define GO_FUNC_SENTINEL ((uint64)'G' | ((uint64)'O'<<8) | \
621 ((uint64)'.'<<16) | ((uint64)'.'<<24) | \
622 ((uint64)'F'<<32) | ((uint64)'U'<<40) | \
623 ((uint64)'N'<<48) | ((uint64)'C'<<56))
627 uint8 data
[1]; // variabe length
631 runtime_scanstackblockwithmap (uintptr ip
, uintptr sp
, uintptr size
, uint8
*ptrmask
, void* gcw
)
632 __asm__ (GOSYM_PREFIX
"runtime.scanstackblockwithmap");
635 #define NOTFOUND_OK 1
636 #define NOTFOUND_BAD 2
638 // Helper function to search for stack maps in the unwinding records of a frame.
639 // If found, populate ip, sp, and stackmap. Returns the #define'd values above.
641 findstackmaps (struct _Unwind_Context
*context
, _Unwind_Ptr
*ip
, _Unwind_Ptr
*sp
, struct _stackmap
**stackmap
)
643 lsda_header_info info
;
644 const unsigned char *language_specific_data
, *p
, *action_record
;
646 struct _stackmap
*stackmap1
;
648 int ip_before_insn
= 0;
652 #ifdef __ARM_EABI_UNWINDER__
654 _Unwind_Control_Block
*ucbp
;
655 ucbp
= (_Unwind_Control_Block
*) _Unwind_GetGR (context
, 12);
656 if (*ucbp
->pr_cache
.ehtp
& (1u << 31))
657 // The "compact" model is used, with one of the predefined
658 // personality functions. It doesn't have standard LSDA.
663 language_specific_data
= (const unsigned char *)
664 _Unwind_GetLanguageSpecificData (context
);
666 /* If no LSDA, then there is no stack maps. */
667 if (! language_specific_data
)
670 p
= parse_lsda_header (context
, language_specific_data
, &info
);
672 if (info
.TType
== NULL
)
675 #ifdef HAVE_GETIPINFO
676 ip1
= _Unwind_GetIPInfo (context
, &ip_before_insn
);
678 ip1
= _Unwind_GetIP (context
);
680 if (! ip_before_insn
)
683 size
= value_size (info
.ttype_encoding
);
685 action_record
= NULL
;
688 /* Search the call-site table for the action associated with this IP. */
689 while (p
< info
.action_table
)
691 _Unwind_Ptr cs_start
, cs_len
, cs_lp
;
692 _uleb128_t cs_action
;
694 /* Note that all call-site encodings are "absolute" displacements. */
695 p
= read_encoded_value (0, info
.call_site_encoding
, p
, &cs_start
);
696 p
= read_encoded_value (0, info
.call_site_encoding
, p
, &cs_len
);
697 p
= read_encoded_value (0, info
.call_site_encoding
, p
, &cs_lp
);
698 p
= read_uleb128 (p
, &cs_action
);
702 // For a Go function, the first entry points to the sentinel value.
704 const unsigned char *p1
, *action1
;
710 action1
= info
.action_table
+ cs_action
- 1;
711 read_sleb128 (action1
, &index
);
712 p1
= info
.TType
- index
*size
;
713 read_encoded_value (context
, info
.ttype_encoding
, p1
, (_Unwind_Ptr
*)&x
);
714 if (x
== NULL
|| *x
!= GO_FUNC_SENTINEL
)
721 /* The table is sorted, so if we've passed the ip, stop. */
722 if (ip1
< info
.Start
+ cs_start
)
724 else if (ip1
< info
.Start
+ cs_start
+ cs_len
)
727 action_record
= info
.action_table
+ cs_action
- 1;
732 if (action_record
== NULL
)
735 read_sleb128 (action_record
, &index
);
736 p
= info
.TType
- index
*size
;
737 read_encoded_value (context
, info
.ttype_encoding
, p
, (_Unwind_Ptr
*)&stackmap1
);
738 if (stackmap1
== NULL
)
744 *sp
= _Unwind_GetCFA (context
);
745 if (stackmap
!= NULL
)
746 *stackmap
= stackmap1
;
750 // Callback function to scan a stack frame with stack maps.
751 // It skips non-Go functions.
752 static _Unwind_Reason_Code
753 scanstackwithmap_callback (struct _Unwind_Context
*context
, void *arg
)
755 struct _stackmap
*stackmap
;
760 switch (findstackmaps (context
, &ip
, &sp
, &stackmap
))
763 // Not a Go function. Skip this frame.
764 return _URC_NO_REASON
;
767 // No stack map found.
768 // If we're scanning from the signal stack, the goroutine
769 // may be not stopped at a safepoint. Allow this case.
771 if (gp
!= gp
->m
->gsignal
)
773 // TODO: print gp, pc, sp
774 runtime_throw ("no stack map");
776 return STOP_UNWINDING
;
784 runtime_scanstackblockwithmap (ip
, sp
, (uintptr
)(stackmap
->len
) * sizeof(uintptr
), stackmap
->data
, gcw
);
786 return _URC_NO_REASON
;
789 // Scan the stack with stack maps. Return whether the scan
792 scanstackwithmap (void *gcw
)
794 _Unwind_Reason_Code code
;
795 runtime_xadd (&__go_runtime_in_callers
, 1);
796 code
= _Unwind_Backtrace (scanstackwithmap_callback
, gcw
);
797 runtime_xadd (&__go_runtime_in_callers
, -1);
798 return code
== _URC_END_OF_STACK
;
801 // Returns whether stack map is enabled.
805 return runtime_usestackmaps
;
808 // Callback function to probe if a stack frame has stack maps.
809 static _Unwind_Reason_Code
810 probestackmaps_callback (struct _Unwind_Context
*context
,
811 void *arg
__attribute__ ((unused
)))
813 switch (findstackmaps (context
, NULL
, NULL
, NULL
))
817 return _URC_NO_REASON
;
824 // Found a stack map. No need to keep unwinding.
825 runtime_usestackmaps
= true;
826 return STOP_UNWINDING
;
829 // Try to find a stack map, store the result in global variable runtime_usestackmaps.
830 // Called in start-up time from Go code, so there is a Go frame on the stack.
834 runtime_usestackmaps
= false;
835 _Unwind_Backtrace (probestackmaps_callback
, NULL
);
836 return runtime_usestackmaps
;