Home | History | Annotate | Line # | Download | only in unwind
      1      1.1  mrg // Exception handling and frame unwind runtime interface routines.
      2  1.1.1.3  mrg // Copyright (C) 2011-2022 Free Software Foundation, Inc.
      3      1.1  mrg 
      4      1.1  mrg // GCC is free software; you can redistribute it and/or modify it under
      5      1.1  mrg // the terms of the GNU General Public License as published by the Free
      6      1.1  mrg // Software Foundation; either version 3, or (at your option) any later
      7      1.1  mrg // version.
      8      1.1  mrg 
      9      1.1  mrg // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     10      1.1  mrg // WARRANTY; without even the implied warranty of MERCHANTABILITY or
     11      1.1  mrg // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     12      1.1  mrg // for more details.
     13      1.1  mrg 
     14      1.1  mrg // Under Section 7 of GPL version 3, you are granted additional
     15      1.1  mrg // permissions described in the GCC Runtime Library Exception, version
     16      1.1  mrg // 3.1, as published by the Free Software Foundation.
     17      1.1  mrg 
     18      1.1  mrg // You should have received a copy of the GNU General Public License and
     19      1.1  mrg // a copy of the GCC Runtime Library Exception along with this program;
     20      1.1  mrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     21      1.1  mrg // <http://www.gnu.org/licenses/>.
     22      1.1  mrg 
     23      1.1  mrg // extern(C) interface for the ARM EABI and C6X unwinders.
     24      1.1  mrg // This corresponds to unwind-arm-common.h
     25      1.1  mrg 
     26      1.1  mrg module gcc.unwind.arm_common;
     27      1.1  mrg 
     28      1.1  mrg import gcc.config;
     29      1.1  mrg 
     30      1.1  mrg static if (GNU_ARM_EABI_Unwinder):
     31      1.1  mrg 
     32      1.1  mrg import gcc.builtins;
     33      1.1  mrg 
     34      1.1  mrg extern (C):
     35      1.1  mrg 
     36      1.1  mrg // Placed outside @nogc in order to not constrain what the callback does.
     37      1.1  mrg // ??? Does this really need to be extern(C) alias?
     38      1.1  mrg extern(C) alias _Unwind_Exception_Cleanup_Fn
     39      1.1  mrg     = void function(_Unwind_Reason_Code, _Unwind_Exception*);
     40      1.1  mrg 
     41      1.1  mrg extern(C) alias personality_routine
     42      1.1  mrg     = _Unwind_Reason_Code function(_Unwind_State,
     43      1.1  mrg                                    _Unwind_Control_Block*,
     44      1.1  mrg                                    _Unwind_Context*);
     45      1.1  mrg 
     46      1.1  mrg extern(C) alias _Unwind_Stop_Fn
     47      1.1  mrg     =_Unwind_Reason_Code function(int, _Unwind_Action,
     48      1.1  mrg                                   _Unwind_Exception_Class,
     49      1.1  mrg                                   _Unwind_Control_Block*,
     50      1.1  mrg                                   _Unwind_Context*, void*);
     51      1.1  mrg 
     52      1.1  mrg extern(C) alias _Unwind_Trace_Fn
     53      1.1  mrg     = _Unwind_Reason_Code function(_Unwind_Context*, void*);
     54      1.1  mrg 
     55      1.1  mrg @nogc:
     56      1.1  mrg 
     57      1.1  mrg alias _Unwind_Word = __builtin_machine_uint;
     58      1.1  mrg alias _Unwind_Sword = __builtin_machine_int;
     59      1.1  mrg alias _Unwind_Ptr = __builtin_pointer_uint;
     60      1.1  mrg alias _Unwind_Internal_Ptr =__builtin_pointer_uint;
     61      1.1  mrg alias _uw = _Unwind_Word;
     62      1.1  mrg alias _uw64 = ulong;
     63      1.1  mrg alias _uw16 = ushort;
     64      1.1  mrg alias _uw8 = ubyte;
     65      1.1  mrg 
     66      1.1  mrg alias _Unwind_Reason_Code = uint;
     67      1.1  mrg enum : _Unwind_Reason_Code
     68      1.1  mrg {
     69      1.1  mrg     _URC_OK = 0,        // operation completed successfully
     70      1.1  mrg     _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
     71      1.1  mrg     _URC_END_OF_STACK = 5,
     72      1.1  mrg     _URC_HANDLER_FOUND = 6,
     73      1.1  mrg     _URC_INSTALL_CONTEXT = 7,
     74      1.1  mrg     _URC_CONTINUE_UNWIND = 8,
     75      1.1  mrg     _URC_FAILURE = 9    // unspecified failure of some kind
     76      1.1  mrg }
     77      1.1  mrg 
     78      1.1  mrg alias _Unwind_State = int;
     79      1.1  mrg enum : _Unwind_State
     80      1.1  mrg {
     81      1.1  mrg     _US_VIRTUAL_UNWIND_FRAME = 0,
     82      1.1  mrg     _US_UNWIND_FRAME_STARTING = 1,
     83      1.1  mrg     _US_UNWIND_FRAME_RESUME = 2,
     84      1.1  mrg     _US_ACTION_MASK = 3,
     85      1.1  mrg     _US_FORCE_UNWIND = 8,
     86      1.1  mrg     _US_END_OF_STACK = 16
     87      1.1  mrg }
     88      1.1  mrg 
     89      1.1  mrg // Provided only for for compatibility with existing code.
     90      1.1  mrg alias _Unwind_Action = int;
     91      1.1  mrg enum : _Unwind_Action
     92      1.1  mrg {
     93      1.1  mrg     _UA_SEARCH_PHASE = 1,
     94      1.1  mrg     _UA_CLEANUP_PHASE = 2,
     95      1.1  mrg     _UA_HANDLER_FRAME = 4,
     96      1.1  mrg     _UA_FORCE_UNWIND = 8,
     97      1.1  mrg     _UA_END_OF_STACK = 16,
     98      1.1  mrg     _URC_NO_REASON = _URC_OK
     99      1.1  mrg }
    100      1.1  mrg 
    101      1.1  mrg struct _Unwind_Context;
    102      1.1  mrg alias _Unwind_EHT_Header = _uw;
    103      1.1  mrg 
    104      1.1  mrg struct _Unwind_Control_Block
    105      1.1  mrg {
    106      1.1  mrg     _Unwind_Exception_Class exception_class = '\0';
    107      1.1  mrg     _Unwind_Exception_Cleanup_Fn exception_cleanup;
    108      1.1  mrg     // Unwinder cache, private fields for the unwinder's use
    109      1.1  mrg     struct _unwinder_cache
    110      1.1  mrg     {
    111      1.1  mrg         _uw reserved1;  // Forced unwind stop fn, 0 if not forced
    112      1.1  mrg         _uw reserved2;  // Personality routine address
    113      1.1  mrg         _uw reserved3;  // Saved callsite address
    114      1.1  mrg         _uw reserved4;  // Forced unwind stop arg
    115      1.1  mrg         _uw reserved5;
    116      1.1  mrg     }
    117      1.1  mrg     _unwinder_cache unwinder_cache;
    118      1.1  mrg     // Propagation barrier cache (valid after phase 1):
    119      1.1  mrg     struct _barrier_cache
    120      1.1  mrg     {
    121      1.1  mrg         _uw sp;
    122      1.1  mrg         _uw[5] bitpattern;
    123      1.1  mrg     }
    124      1.1  mrg     _barrier_cache barrier_cache;
    125      1.1  mrg     // Cleanup cache (preserved over cleanup):
    126      1.1  mrg     struct _cleanup_cache
    127      1.1  mrg     {
    128      1.1  mrg         _uw[4] bitpattern;
    129      1.1  mrg     }
    130      1.1  mrg     _cleanup_cache cleanup_cache;
    131      1.1  mrg     // Pr cache (for pr's benefit):
    132      1.1  mrg     struct _pr_cache
    133      1.1  mrg     {
    134      1.1  mrg         _uw fnstart;                // function start address */
    135      1.1  mrg         _Unwind_EHT_Header* ehtp;   // pointer to EHT entry header word
    136      1.1  mrg         _uw additional;             // additional data
    137      1.1  mrg         _uw reserved1;
    138      1.1  mrg     }
    139      1.1  mrg     _pr_cache pr_cache;
    140      1.1  mrg     long[0] _force_alignment;       // Force alignment to 8-byte boundary
    141      1.1  mrg }
    142      1.1  mrg 
    143      1.1  mrg // Virtual Register Set
    144      1.1  mrg alias _Unwind_VRS_RegClass = int;
    145      1.1  mrg enum : _Unwind_VRS_RegClass
    146      1.1  mrg {
    147      1.1  mrg     _UVRSC_CORE = 0,    // integer register
    148      1.1  mrg     _UVRSC_VFP = 1,     // vfp
    149      1.1  mrg     _UVRSC_FPA = 2,     // fpa
    150      1.1  mrg     _UVRSC_WMMXD = 3,   // Intel WMMX data register
    151      1.1  mrg     _UVRSC_WMMXC = 4    // Intel WMMX control register
    152      1.1  mrg }
    153      1.1  mrg 
    154      1.1  mrg alias _Unwind_VRS_DataRepresentation = int;
    155      1.1  mrg enum : _Unwind_VRS_DataRepresentation
    156      1.1  mrg {
    157      1.1  mrg     _UVRSD_UINT32 = 0,
    158      1.1  mrg     _UVRSD_VFPX = 1,
    159      1.1  mrg     _UVRSD_FPAX = 2,
    160      1.1  mrg     _UVRSD_UINT64 = 3,
    161      1.1  mrg     _UVRSD_FLOAT = 4,
    162      1.1  mrg     _UVRSD_DOUBLE = 5
    163      1.1  mrg }
    164      1.1  mrg 
    165      1.1  mrg alias _Unwind_VRS_Result = int;
    166      1.1  mrg enum : _Unwind_VRS_Result
    167      1.1  mrg {
    168      1.1  mrg     _UVRSR_OK = 0,
    169      1.1  mrg     _UVRSR_NOT_IMPLEMENTED = 1,
    170      1.1  mrg     _UVRSR_FAILED = 2
    171      1.1  mrg }
    172      1.1  mrg 
    173      1.1  mrg // Frame unwinding state.
    174      1.1  mrg struct __gnu_unwind_state
    175      1.1  mrg {
    176      1.1  mrg     _uw data;           // The current word (bytes packed msb first).
    177      1.1  mrg     _uw* next;          // Pointer to the next word of data.
    178      1.1  mrg     _uw8 bytes_left;    // The number of bytes left in this word.
    179      1.1  mrg     _uw8 words_left;    // The number of words pointed to by ptr.
    180      1.1  mrg }
    181      1.1  mrg 
    182      1.1  mrg _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context*, _Unwind_VRS_RegClass,
    183      1.1  mrg                                    _uw, _Unwind_VRS_DataRepresentation,
    184      1.1  mrg                                    void*);
    185      1.1  mrg 
    186      1.1  mrg _Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context*, _Unwind_VRS_RegClass,
    187      1.1  mrg                                    _uw, _Unwind_VRS_DataRepresentation,
    188      1.1  mrg                                    void*);
    189      1.1  mrg 
    190      1.1  mrg _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context*, _Unwind_VRS_RegClass,
    191      1.1  mrg                                    _uw, _Unwind_VRS_DataRepresentation);
    192      1.1  mrg 
    193      1.1  mrg 
    194      1.1  mrg // Support functions for the PR.
    195      1.1  mrg alias _Unwind_Exception = _Unwind_Control_Block;
    196      1.1  mrg alias _Unwind_Exception_Class = char[8];
    197      1.1  mrg 
    198      1.1  mrg void* _Unwind_GetLanguageSpecificData(_Unwind_Context*);
    199      1.1  mrg _Unwind_Ptr _Unwind_GetRegionStart(_Unwind_Context*);
    200      1.1  mrg 
    201      1.1  mrg _Unwind_Ptr _Unwind_GetDataRelBase(_Unwind_Context*);
    202      1.1  mrg // This should never be used.
    203      1.1  mrg _Unwind_Ptr _Unwind_GetTextRelBase(_Unwind_Context*);
    204      1.1  mrg 
    205      1.1  mrg // Interface functions:
    206      1.1  mrg _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block*);
    207      1.1  mrg void _Unwind_Resume(_Unwind_Control_Block*);
    208      1.1  mrg _Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Control_Block*);
    209      1.1  mrg 
    210      1.1  mrg _Unwind_Reason_Code _Unwind_ForcedUnwind(_Unwind_Control_Block*,
    211      1.1  mrg                                          _Unwind_Stop_Fn, void*);
    212      1.1  mrg 
    213      1.1  mrg // @@@ Use unwind data to perform a stack backtrace.  The trace callback
    214      1.1  mrg // is called for every stack frame in the call chain, but no cleanup
    215      1.1  mrg // actions are performed.
    216      1.1  mrg _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void*);
    217      1.1  mrg 
    218      1.1  mrg _Unwind_Word _Unwind_GetCFA(_Unwind_Context*);
    219      1.1  mrg void _Unwind_Complete(_Unwind_Control_Block*);
    220      1.1  mrg void _Unwind_DeleteException(_Unwind_Exception*);
    221      1.1  mrg 
    222      1.1  mrg _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Control_Block*,
    223      1.1  mrg                                        _Unwind_Context*);
    224      1.1  mrg _Unwind_Reason_Code __gnu_unwind_execute(_Unwind_Context*,
    225      1.1  mrg                                          __gnu_unwind_state*);
    226      1.1  mrg 
    227      1.1  mrg _Unwind_Word _Unwind_GetGR(_Unwind_Context* context, int regno)
    228      1.1  mrg {
    229      1.1  mrg     _uw val;
    230      1.1  mrg     _Unwind_VRS_Get(context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val);
    231      1.1  mrg     return val;
    232      1.1  mrg }
    233      1.1  mrg 
    234      1.1  mrg void _Unwind_SetGR(_Unwind_Context* context, int regno, _Unwind_Word val)
    235      1.1  mrg {
    236      1.1  mrg     _Unwind_VRS_Set(context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val);
    237      1.1  mrg }
    238      1.1  mrg 
    239      1.1  mrg // leb128 type numbers have a potentially unlimited size.
    240      1.1  mrg // The target of the following definitions of _sleb128_t and _uleb128_t
    241      1.1  mrg // is to have efficient data types large enough to hold the leb128 type
    242      1.1  mrg // numbers used in the unwind code.
    243      1.1  mrg alias _sleb128_t = __builtin_clong;
    244      1.1  mrg alias _uleb128_t = __builtin_culong;
    245