Skip to content

Commit e9fc6c1

Browse files
Andrew HsiehGerrit Code Review
Andrew Hsieh
authored and
Gerrit Code Review
committed
Merge "[ARM] Add unwind portable header adaptor."
2 parents 27bd326 + 55128d1 commit e9fc6c1

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

ndk/sources/android/libportable/Android.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ libportable_arch_src_files += \
7171
arch-arm/errno.c \
7272
arch-arm/socket.c \
7373
arch-arm/sockopt.c \
74-
arch-arm/stat.c
74+
arch-arm/stat.c \
75+
arch-arm/unwind.c
7576
endif
7677

7778
ifeq ($(TARGET_ARCH),x86)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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 <stdint.h>
18+
19+
struct _Unwind_Context;
20+
21+
typedef enum {
22+
_UVRSC_CORE = 0, // integer register
23+
_UVRSC_VFP = 1, // vfp
24+
_UVRSC_WMMXD = 3, // Intel WMMX data register
25+
_UVRSC_WMMXC = 4 // Intel WMMX control register
26+
} _Unwind_VRS_RegClass;
27+
28+
typedef enum {
29+
_UVRSD_UINT32 = 0,
30+
_UVRSD_VFPX = 1,
31+
_UVRSD_UINT64 = 3,
32+
_UVRSD_FLOAT = 4,
33+
_UVRSD_DOUBLE = 5
34+
} _Unwind_VRS_DataRepresentation;
35+
36+
typedef enum {
37+
_UVRSR_OK = 0,
38+
_UVRSR_NOT_IMPLEMENTED = 1,
39+
_UVRSR_FAILED = 2
40+
} _Unwind_VRS_Result;
41+
42+
_Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *context,
43+
_Unwind_VRS_RegClass regclass,
44+
uint32_t regno,
45+
_Unwind_VRS_DataRepresentation representation,
46+
void* valuep);
47+
48+
_Unwind_VRS_Result _Unwind_VRS_Set(struct _Unwind_Context *context,
49+
_Unwind_VRS_RegClass regclass,
50+
uint32_t regno,
51+
_Unwind_VRS_DataRepresentation representation,
52+
void* valuep);
53+
54+
#define UNWIND_POINTER_REG 12
55+
#define UNWIND_STACK_REG 13
56+
#define UNWIND_IP_REG 15
57+
58+
uint64_t _Unwind_GetGR_portable(struct _Unwind_Context* ctx, int index) {
59+
uint32_t val;
60+
_Unwind_VRS_Get(ctx, _UVRSC_CORE, index, _UVRSD_UINT32, &val);
61+
return (uint64_t)val;
62+
}
63+
64+
void _Unwind_SetGR_portable(struct _Unwind_Context* ctx, int index, uint64_t new_value) {
65+
uint32_t val = (uint32_t)new_value;
66+
_Unwind_VRS_Set(ctx, _UVRSC_CORE, index, _UVRSD_UINT32, &val);
67+
}
68+
69+
uint64_t _Unwind_GetIP_portable(struct _Unwind_Context* ctx) {
70+
return _Unwind_GetGR_portable(ctx, UNWIND_IP_REG) & ~1; // thumb bit
71+
}
72+
73+
void _Unwind_SetIP_portable(struct _Unwind_Context* ctx, uintptr_t new_value) {
74+
uint32_t val = (uint32_t)new_value;
75+
// Propagate thumb bit to instruction pointer
76+
uint32_t thumbState = _Unwind_GetGR_portable(ctx, UNWIND_IP_REG) & 1;
77+
uint64_t new_val = (uint64_t)(val | thumbState);
78+
_Unwind_SetGR_portable(ctx, UNWIND_IP_REG, new_val);
79+
}

0 commit comments

Comments
 (0)