thread_info.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. // Copyright 2017 The Crashpad Authors. All rights reserved.
  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. #ifndef CRASHPAD_UTIL_LINUX_THREAD_INFO_H_
  15. #define CRASHPAD_UTIL_LINUX_THREAD_INFO_H_
  16. #include <stdint.h>
  17. #include <sys/user.h>
  18. #include <type_traits>
  19. #include "build/build_config.h"
  20. #include "util/linux/address_types.h"
  21. #include "util/numeric/int128.h"
  22. #if BUILDFLAG(IS_ANDROID)
  23. #include <android/api-level.h>
  24. #endif
  25. namespace crashpad {
  26. //! \brief The set of general purpose registers for an architecture family.
  27. union ThreadContext {
  28. ThreadContext();
  29. ~ThreadContext();
  30. //! \brief The general purpose registers used by the 32-bit variant of the
  31. //! architecture.
  32. struct t32_t {
  33. #if defined(ARCH_CPU_X86_FAMILY)
  34. // Reflects user_regs_struct in sys/user.h.
  35. uint32_t ebx;
  36. uint32_t ecx;
  37. uint32_t edx;
  38. uint32_t esi;
  39. uint32_t edi;
  40. uint32_t ebp;
  41. uint32_t eax;
  42. uint32_t xds;
  43. uint32_t xes;
  44. uint32_t xfs;
  45. uint32_t xgs;
  46. uint32_t orig_eax;
  47. uint32_t eip;
  48. uint32_t xcs;
  49. uint32_t eflags;
  50. uint32_t esp;
  51. uint32_t xss;
  52. #elif defined(ARCH_CPU_ARM_FAMILY)
  53. // Reflects user_regs in sys/user.h.
  54. uint32_t regs[11];
  55. uint32_t fp;
  56. uint32_t ip;
  57. uint32_t sp;
  58. uint32_t lr;
  59. uint32_t pc;
  60. uint32_t cpsr;
  61. uint32_t orig_r0;
  62. #elif defined(ARCH_CPU_MIPS_FAMILY)
  63. // Reflects output format of static int gpr32_get(), defined in
  64. // arch/mips/kernel/ptrace.c in kernel source
  65. uint32_t padding0_[6];
  66. uint32_t regs[32];
  67. uint32_t lo;
  68. uint32_t hi;
  69. uint32_t cp0_epc;
  70. uint32_t cp0_badvaddr;
  71. uint32_t cp0_status;
  72. uint32_t cp0_cause;
  73. uint32_t padding1_;
  74. #elif defined(ARCH_CPU_RISCV_FAMILY)
  75. // Reflects user_regs_struct in asm/ptrace.h.
  76. uint32_t pc;
  77. uint32_t ra;
  78. uint32_t sp;
  79. uint32_t gp;
  80. uint32_t tp;
  81. uint32_t t0;
  82. uint32_t t1;
  83. uint32_t t2;
  84. uint32_t s0;
  85. uint32_t s1;
  86. uint32_t a0;
  87. uint32_t a1;
  88. uint32_t a2;
  89. uint32_t a3;
  90. uint32_t a4;
  91. uint32_t a5;
  92. uint32_t a6;
  93. uint32_t a7;
  94. uint32_t s2;
  95. uint32_t s3;
  96. uint32_t s4;
  97. uint32_t s5;
  98. uint32_t s6;
  99. uint32_t s7;
  100. uint32_t s8;
  101. uint32_t s9;
  102. uint32_t s10;
  103. uint32_t s11;
  104. uint32_t t3;
  105. uint32_t t4;
  106. uint32_t t5;
  107. uint32_t t6;
  108. #else
  109. #error Port.
  110. #endif // ARCH_CPU_X86_FAMILY
  111. } t32;
  112. //! \brief The general purpose registers used by the 64-bit variant of the
  113. //! architecture.
  114. struct t64_t {
  115. #if defined(ARCH_CPU_X86_FAMILY)
  116. // Reflects user_regs_struct in sys/user.h.
  117. uint64_t r15;
  118. uint64_t r14;
  119. uint64_t r13;
  120. uint64_t r12;
  121. uint64_t rbp;
  122. uint64_t rbx;
  123. uint64_t r11;
  124. uint64_t r10;
  125. uint64_t r9;
  126. uint64_t r8;
  127. uint64_t rax;
  128. uint64_t rcx;
  129. uint64_t rdx;
  130. uint64_t rsi;
  131. uint64_t rdi;
  132. uint64_t orig_rax;
  133. uint64_t rip;
  134. uint64_t cs;
  135. uint64_t eflags;
  136. uint64_t rsp;
  137. uint64_t ss;
  138. uint64_t fs_base;
  139. uint64_t gs_base;
  140. uint64_t ds;
  141. uint64_t es;
  142. uint64_t fs;
  143. uint64_t gs;
  144. #elif defined(ARCH_CPU_ARM_FAMILY)
  145. // Reflects user_regs_struct in sys/user.h.
  146. uint64_t regs[31];
  147. uint64_t sp;
  148. uint64_t pc;
  149. uint64_t pstate;
  150. #elif defined(ARCH_CPU_MIPS_FAMILY)
  151. // Reflects output format of static int gpr64_get(), defined in
  152. // arch/mips/kernel/ptrace.c in kernel source
  153. uint64_t regs[32];
  154. uint64_t lo;
  155. uint64_t hi;
  156. uint64_t cp0_epc;
  157. uint64_t cp0_badvaddr;
  158. uint64_t cp0_status;
  159. uint64_t cp0_cause;
  160. #elif defined(ARCH_CPU_RISCV_FAMILY)
  161. // Reflects user_regs_struct in asm/ptrace.h.
  162. uint64_t pc;
  163. uint64_t ra;
  164. uint64_t sp;
  165. uint64_t gp;
  166. uint64_t tp;
  167. uint64_t t0;
  168. uint64_t t1;
  169. uint64_t t2;
  170. uint64_t s0;
  171. uint64_t s1;
  172. uint64_t a0;
  173. uint64_t a1;
  174. uint64_t a2;
  175. uint64_t a3;
  176. uint64_t a4;
  177. uint64_t a5;
  178. uint64_t a6;
  179. uint64_t a7;
  180. uint64_t s2;
  181. uint64_t s3;
  182. uint64_t s4;
  183. uint64_t s5;
  184. uint64_t s6;
  185. uint64_t s7;
  186. uint64_t s8;
  187. uint64_t s9;
  188. uint64_t s10;
  189. uint64_t s11;
  190. uint64_t t3;
  191. uint64_t t4;
  192. uint64_t t5;
  193. uint64_t t6;
  194. #else
  195. #error Port.
  196. #endif // ARCH_CPU_X86_FAMILY
  197. } t64;
  198. #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM64)
  199. using NativeThreadContext = user_regs_struct;
  200. #elif defined(ARCH_CPU_ARMEL)
  201. using NativeThreadContext = user_regs;
  202. #elif defined(ARCH_CPU_MIPS_FAMILY)
  203. // No appropriate NativeThreadsContext type available for MIPS
  204. #elif defined(ARCH_CPU_RISCV_FAMILY)
  205. #else
  206. #error Port.
  207. #endif // ARCH_CPU_X86_FAMILY || ARCH_CPU_ARM64
  208. #if !defined(ARCH_CPU_MIPS_FAMILY) && !defined(ARCH_CPU_RISCV_FAMILY)
  209. #if defined(ARCH_CPU_32_BITS)
  210. static_assert(sizeof(t32_t) == sizeof(NativeThreadContext), "Size mismatch");
  211. #else // ARCH_CPU_64_BITS
  212. static_assert(sizeof(t64_t) == sizeof(NativeThreadContext), "Size mismatch");
  213. #endif // ARCH_CPU_32_BITS
  214. #endif // !ARCH_CPU_MIPS_FAMILY
  215. };
  216. static_assert(std::is_standard_layout<ThreadContext>::value,
  217. "Not standard layout");
  218. //! \brief The floating point registers used for an architecture family.
  219. union FloatContext {
  220. FloatContext();
  221. ~FloatContext();
  222. //! \brief The floating point registers used by the 32-bit variant of the
  223. //! architecture.
  224. struct f32_t {
  225. #if defined(ARCH_CPU_X86_FAMILY)
  226. // Reflects user_fpxregs_struct in sys/user.h
  227. struct fxsave {
  228. uint16_t cwd;
  229. uint16_t swd;
  230. uint16_t twd;
  231. uint16_t fop;
  232. uint32_t fip;
  233. uint32_t fcs;
  234. uint32_t foo;
  235. uint32_t fos;
  236. uint32_t mxcsr;
  237. uint32_t reserved;
  238. uint32_t st_space[32];
  239. uint32_t xmm_space[32];
  240. uint32_t padding[56];
  241. } fxsave;
  242. #elif defined(ARCH_CPU_ARM_FAMILY)
  243. // Reflects user_fpregs in sys/user.h.
  244. struct fpregs {
  245. struct fp_reg {
  246. uint32_t sign1 : 1;
  247. uint32_t unused : 15;
  248. uint32_t sign2 : 1;
  249. uint32_t exponent : 14;
  250. uint32_t j : 1;
  251. uint32_t mantissa1 : 31;
  252. uint32_t mantisss0 : 32;
  253. } fpregs[8];
  254. uint32_t fpsr : 32;
  255. uint32_t fpcr : 32;
  256. uint8_t type[8];
  257. uint32_t init_flag;
  258. } fpregs;
  259. // Reflects user_vfp in sys/user.h.
  260. struct vfp_t {
  261. uint64_t fpregs[32];
  262. uint32_t fpscr;
  263. } vfp;
  264. bool have_fpregs;
  265. bool have_vfp;
  266. #elif defined(ARCH_CPU_MIPS_FAMILY)
  267. // Reflects data format filled by ptrace_getfpregs() in
  268. // arch/mips/kernel/ptrace.c
  269. struct {
  270. float _fp_fregs;
  271. unsigned int _fp_pad;
  272. } fpregs[32];
  273. uint32_t fpcsr;
  274. uint32_t fpu_id;
  275. #elif defined(ARCH_CPU_RISCV_FAMILY)
  276. uint64_t f[32];
  277. uint32_t fcsr;
  278. #else
  279. #error Port.
  280. #endif // ARCH_CPU_X86_FAMILY
  281. } f32;
  282. //! \brief The floating point registers used by the 64-bit variant of the
  283. //! architecture.
  284. struct f64_t {
  285. #if defined(ARCH_CPU_X86_FAMILY)
  286. // Refelects user_fpregs_struct in sys/user.h
  287. struct fxsave {
  288. uint16_t cwd;
  289. uint16_t swd;
  290. uint16_t ftw;
  291. uint16_t fop;
  292. uint64_t rip;
  293. uint64_t rdp;
  294. uint32_t mxcsr;
  295. uint32_t mxcr_mask;
  296. uint32_t st_space[32];
  297. uint32_t xmm_space[64];
  298. uint32_t padding[24];
  299. } fxsave;
  300. #elif defined(ARCH_CPU_ARM_FAMILY)
  301. uint128_struct vregs[32];
  302. uint32_t fpsr;
  303. uint32_t fpcr;
  304. uint8_t padding[8];
  305. #elif defined(ARCH_CPU_MIPS_FAMILY)
  306. // Reflects data format filled by ptrace_getfpregs() in
  307. // arch/mips/kernel/ptrace.c
  308. double fpregs[32];
  309. uint32_t fpcsr;
  310. uint32_t fpu_id;
  311. #elif defined(ARCH_CPU_RISCV_FAMILY)
  312. uint64_t f[32];
  313. uint32_t fcsr;
  314. #else
  315. #error Port.
  316. #endif // ARCH_CPU_X86_FAMILY
  317. } f64;
  318. #if defined(ARCH_CPU_X86)
  319. // __ANDROID_API_N__ is a proxy for determining whether unified headers are in
  320. // use. It’s only defined by unified headers. Unified headers call this
  321. // structure user_fpxregs_struct regardless of API level.
  322. #if BUILDFLAG(IS_ANDROID) && __ANDROID_API__ <= 19 && \
  323. !defined(__ANDROID_API_N__)
  324. using NativeFpxregs = user_fxsr_struct;
  325. #else
  326. using NativeFpxregs = user_fpxregs_struct;
  327. #endif // BUILDFLAG(IS_ANDROID)
  328. static_assert(sizeof(f32_t::fxsave) == sizeof(NativeFpxregs),
  329. "Size mismatch");
  330. #elif defined(ARCH_CPU_X86_64)
  331. static_assert(sizeof(f64_t::fxsave) == sizeof(user_fpregs_struct),
  332. "Size mismatch");
  333. #elif defined(ARCH_CPU_ARMEL)
  334. static_assert(sizeof(f32_t::fpregs) == sizeof(user_fpregs), "Size mismatch");
  335. #if !defined(__GLIBC__)
  336. static_assert(sizeof(f32_t::vfp) == sizeof(user_vfp), "Size mismatch");
  337. #endif
  338. #elif defined(ARCH_CPU_ARM64)
  339. static_assert(sizeof(f64) == sizeof(user_fpsimd_struct), "Size mismatch");
  340. #elif defined(ARCH_CPU_MIPS_FAMILY)
  341. // No appropriate floating point context native type for available MIPS.
  342. #elif defined(ARCH_CPU_RISCV_FAMILY)
  343. #else
  344. #error Port.
  345. #endif // ARCH_CPU_X86
  346. };
  347. static_assert(std::is_standard_layout<FloatContext>::value,
  348. "Not standard layout");
  349. //! \brief A collection of `ptrace`-able information about a thread.
  350. struct ThreadInfo {
  351. ThreadInfo();
  352. ~ThreadInfo();
  353. //! \brief The general purpose registers for the thread.
  354. ThreadContext thread_context;
  355. //! \brief The floating point registers for the thread.
  356. FloatContext float_context;
  357. //! \brief The thread-local storage address for the thread.
  358. LinuxVMAddress thread_specific_data_address;
  359. };
  360. } // namespace crashpad
  361. #endif // CRASHPAD_UTIL_LINUX_THREAD_INFO_H_