Proyectos de Subversion Iphone Microlearning

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// Copyright 2019 Google
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
 
15
#include "Crashlytics/Crashlytics/Helpers/FIRCLSThreadState.h"
16
#include "Crashlytics/Crashlytics/Helpers/FIRCLSDefines.h"
17
#include "Crashlytics/Crashlytics/Helpers/FIRCLSUtility.h"
18
 
19
#if defined(__arm__) || defined(__arm64__)
20
#include <mach/arm/thread_status.h>
21
#include <ptrauth.h>
22
#endif
23
 
24
#if CLS_CPU_X86_64
25
#define GET_IP_REGISTER(r) (r->__ss.__rip)
26
#define GET_FP_REGISTER(r) (r->__ss.__rbp)
27
#define GET_SP_REGISTER(r) (r->__ss.__rsp)
28
#define GET_LR_REGISTER(r) 0
29
#define SET_IP_REGISTER(r, v) (r->__ss.__rip = v)
30
#define SET_FP_REGISTER(r, v) (r->__ss.__rbp = v)
31
#define SET_SP_REGISTER(r, v) (r->__ss.__rsp = v)
32
#define SET_LR_REGISTER(r, v)
33
#elif CLS_CPU_I386
34
#define GET_IP_REGISTER(r) (r->__ss.__eip)
35
#define GET_FP_REGISTER(r) (r->__ss.__ebp)
36
#define GET_SP_REGISTER(r) (r->__ss.__esp)
37
#define GET_LR_REGISTER(r) 0
38
#define SET_IP_REGISTER(r, v) (r->__ss.__eip = v)
39
#define SET_FP_REGISTER(r, v) (r->__ss.__ebp = v)
40
#define SET_SP_REGISTER(r, v) (r->__ss.__esp = v)
41
#define SET_LR_REGISTER(r, v)
42
#elif CLS_CPU_ARM64
43
// The arm_thread_state64_get_* macros translate down to the AUTIA and AUTIB instructions which
44
// authenticate the address, but don't clear the upper bits. From the docs:
45
//      "If the authentication passes, the upper bits of the address are restored to enable
46
//      subsequent use of the address. the authentication fails, the upper bits are corrupted and
47
//      any subsequent use of the address results in a Translation fault."
48
// Since we only want the address (with the metadata in the upper bits masked out), we used the
49
// ptrauth_strip macro to clear the upper bits.
50
//
51
// We found later that ptrauth_strip doesn't seem to do anything. In many cases, the upper bits were
52
// already stripped, so for most non-system-library code, Crashlytics would still symbolicate. But
53
// for system libraries, the upper bits were being left in even when we called ptrauth_strip.
54
// Instead, we're bit masking and only allowing the latter 36 bits.
55
#define CLS_PTRAUTH_STRIP(pointer) ((uintptr_t)pointer & 0x0000000FFFFFFFFF)
56
#define GET_IP_REGISTER(r) (CLS_PTRAUTH_STRIP(arm_thread_state64_get_pc(r->__ss)))
57
#define GET_FP_REGISTER(r) (CLS_PTRAUTH_STRIP(arm_thread_state64_get_fp(r->__ss)))
58
#define GET_SP_REGISTER(r) (CLS_PTRAUTH_STRIP(arm_thread_state64_get_sp(r->__ss)))
59
#define GET_LR_REGISTER(r) (CLS_PTRAUTH_STRIP(arm_thread_state64_get_lr(r->__ss)))
60
#define SET_IP_REGISTER(r, v) arm_thread_state64_set_pc_fptr(r->__ss, (void*)v)
61
#define SET_FP_REGISTER(r, v) arm_thread_state64_set_fp(r->__ss, v)
62
#define SET_SP_REGISTER(r, v) arm_thread_state64_set_sp(r->__ss, v)
63
#define SET_LR_REGISTER(r, v) arm_thread_state64_set_lr_fptr(r->__ss, (void*)v)
64
#elif CLS_CPU_ARM
65
#define GET_IP_REGISTER(r) (r->__ss.__pc)
66
#define GET_FP_REGISTER(r) (r->__ss.__r[7])
67
#define GET_SP_REGISTER(r) (r->__ss.__sp)
68
#define GET_LR_REGISTER(r) (r->__ss.__lr)
69
#define SET_IP_REGISTER(r, v) (r->__ss.__pc = v)
70
#define SET_FP_REGISTER(r, v) (r->__ss.__r[7] = v)
71
#define SET_SP_REGISTER(r, v) (r->__ss.__sp = v)
72
#define SET_LR_REGISTER(r, v) (r->__ss.__lr = v)
73
#else
74
#error "Architecture Unsupported"
75
#endif
76
 
77
uintptr_t FIRCLSThreadContextGetPC(FIRCLSThreadContext* registers) {
78
  if (!registers) {
79
    return 0;
80
  }
81
 
82
  return GET_IP_REGISTER(registers);
83
}
84
 
85
uintptr_t FIRCLSThreadContextGetStackPointer(const FIRCLSThreadContext* registers) {
86
  if (!registers) {
87
    return 0;
88
  }
89
 
90
  return GET_SP_REGISTER(registers);
91
}
92
 
93
bool FIRCLSThreadContextSetStackPointer(FIRCLSThreadContext* registers, uintptr_t value) {
94
  if (!FIRCLSIsValidPointer(registers)) {
95
    return false;
96
  }
97
 
98
  SET_SP_REGISTER(registers, value);
99
 
100
  return true;
101
}
102
 
103
uintptr_t FIRCLSThreadContextGetLinkRegister(const FIRCLSThreadContext* registers) {
104
  if (!FIRCLSIsValidPointer(registers)) {
105
    return 0;
106
  }
107
 
108
  return GET_LR_REGISTER(registers);
109
}
110
 
111
bool FIRCLSThreadContextSetLinkRegister(FIRCLSThreadContext* registers, uintptr_t value) {
112
  if (!FIRCLSIsValidPointer(registers)) {
113
    return false;
114
  }
115
 
116
  SET_LR_REGISTER(registers, value);
117
 
118
  return true;
119
}
120
 
121
bool FIRCLSThreadContextSetPC(FIRCLSThreadContext* registers, uintptr_t value) {
122
  if (!registers) {
123
    return false;
124
  }
125
 
126
  SET_IP_REGISTER(registers, value);
127
 
128
  return true;
129
}
130
 
131
uintptr_t FIRCLSThreadContextGetFramePointer(const FIRCLSThreadContext* registers) {
132
  if (!FIRCLSIsValidPointer(registers)) {
133
    return 0;
134
  }
135
 
136
  return GET_FP_REGISTER(registers);
137
}
138
 
139
bool FIRCLSThreadContextSetFramePointer(FIRCLSThreadContext* registers, uintptr_t value) {
140
  if (!FIRCLSIsValidPointer(registers)) {
141
    return false;
142
  }
143
 
144
  SET_FP_REGISTER(registers, value);
145
 
146
  return true;
147
}