Home | History | Annotate | Download | only in arch-arm
      1 /*
      2  * Copyright 2013, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <portability.h>
     18 #include <stdint.h>
     19 
     20 struct _Unwind_Context;
     21 
     22 typedef enum {
     23   _UVRSC_CORE = 0,  // integer register
     24   _UVRSC_VFP = 1, // vfp
     25   _UVRSC_WMMXD = 3, // Intel WMMX data register
     26   _UVRSC_WMMXC = 4  // Intel WMMX control register
     27 } _Unwind_VRS_RegClass;
     28 
     29 typedef enum {
     30   _UVRSD_UINT32 = 0,
     31   _UVRSD_VFPX = 1,
     32   _UVRSD_UINT64 = 3,
     33   _UVRSD_FLOAT = 4,
     34   _UVRSD_DOUBLE = 5
     35 } _Unwind_VRS_DataRepresentation;
     36 
     37 typedef enum {
     38   _UVRSR_OK = 0,
     39   _UVRSR_NOT_IMPLEMENTED = 1,
     40   _UVRSR_FAILED = 2
     41 } _Unwind_VRS_Result;
     42 
     43 _Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *context,
     44                                    _Unwind_VRS_RegClass regclass,
     45                                    uint32_t regno,
     46                                    _Unwind_VRS_DataRepresentation representation,
     47                                    void* valuep);
     48 
     49 _Unwind_VRS_Result _Unwind_VRS_Set(struct _Unwind_Context *context,
     50                                    _Unwind_VRS_RegClass regclass,
     51                                    uint32_t regno,
     52                                    _Unwind_VRS_DataRepresentation representation,
     53                                    void* valuep);
     54 
     55 #define UNWIND_POINTER_REG  12
     56 #define UNWIND_STACK_REG    13
     57 #define UNWIND_IP_REG       15
     58 
     59 uint64_t WRAP(_Unwind_GetGR)(struct _Unwind_Context* ctx, int index) {
     60   uint32_t val;
     61   _Unwind_VRS_Get(ctx, _UVRSC_CORE, index, _UVRSD_UINT32, &val);
     62   return (uint64_t)val;
     63 }
     64 
     65 void WRAP(_Unwind_SetGR)(struct _Unwind_Context* ctx, int index, uint64_t new_value) {
     66   uint32_t val = (uint32_t)new_value;
     67   _Unwind_VRS_Set(ctx, _UVRSC_CORE, index, _UVRSD_UINT32, &val);
     68 }
     69 
     70 uint64_t WRAP(_Unwind_GetIP)(struct _Unwind_Context* ctx) {
     71   return WRAP(_Unwind_GetGR)(ctx, UNWIND_IP_REG) & ~1; // thumb bit
     72 }
     73 
     74 void WRAP(_Unwind_SetIP)(struct _Unwind_Context* ctx, uintptr_t new_value) {
     75   uint32_t val = (uint32_t)new_value;
     76   // Propagate thumb bit to instruction pointer
     77   uint32_t thumbState = WRAP(_Unwind_GetGR)(ctx, UNWIND_IP_REG) & 1;
     78   uint64_t new_val = (uint64_t)(val | thumbState);
     79   WRAP(_Unwind_SetGR)(ctx, UNWIND_IP_REG, new_val);
     80 }
     81