signal_context.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  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_SNAPSHOT_LINUX_SNAPSHOT_SIGNAL_CONTEXT_H_
  15. #define CRASHPAD_SNAPSHOT_LINUX_SNAPSHOT_SIGNAL_CONTEXT_H_
  16. #include <signal.h>
  17. #include <stdint.h>
  18. #include <sys/types.h>
  19. #include <sys/ucontext.h>
  20. #include <cstddef>
  21. #include <type_traits>
  22. #include "build/build_config.h"
  23. #include "util/linux/thread_info.h"
  24. #include "util/linux/traits.h"
  25. namespace crashpad {
  26. namespace internal {
  27. #pragma pack(push, 1)
  28. template <class Traits>
  29. union Sigval {
  30. int32_t sigval;
  31. typename Traits::Address pointer;
  32. };
  33. template <class Traits>
  34. struct Siginfo {
  35. int32_t signo;
  36. #ifdef ARCH_CPU_MIPS_FAMILY
  37. // Attribute order for signo_t defined in kernel is different for MIPS.
  38. int32_t code;
  39. int32_t err;
  40. #else
  41. int32_t err;
  42. int32_t code;
  43. #endif
  44. typename Traits::UInteger32_64Only padding;
  45. union {
  46. // SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGTRAP
  47. struct {
  48. typename Traits::Address address;
  49. };
  50. // SIGPOLL
  51. struct {
  52. typename Traits::Long band;
  53. int32_t fd;
  54. };
  55. // SIGSYS
  56. struct {
  57. typename Traits::Address call_address;
  58. int32_t syscall;
  59. uint32_t arch;
  60. };
  61. // Everything else
  62. struct {
  63. union {
  64. struct {
  65. pid_t pid;
  66. uid_t uid;
  67. };
  68. struct {
  69. int32_t timerid;
  70. int32_t overrun;
  71. };
  72. };
  73. union {
  74. Sigval<Traits> sigval;
  75. // SIGCHLD
  76. struct {
  77. int32_t status;
  78. typename Traits::Clock utime;
  79. typename Traits::Clock stime;
  80. };
  81. };
  82. };
  83. };
  84. };
  85. template <typename Traits>
  86. struct SignalStack {
  87. typename Traits::Address stack_pointer;
  88. uint32_t flags;
  89. typename Traits::UInteger32_64Only padding;
  90. typename Traits::Size size;
  91. };
  92. template <typename Traits, typename Enable = void>
  93. struct Sigset {};
  94. template <typename Traits>
  95. struct Sigset<
  96. Traits,
  97. typename std::enable_if<std::is_base_of<Traits32, Traits>::value>::type> {
  98. uint64_t val;
  99. };
  100. template <typename Traits>
  101. struct Sigset<
  102. Traits,
  103. typename std::enable_if<std::is_base_of<Traits64, Traits>::value>::type> {
  104. #if BUILDFLAG(IS_ANDROID)
  105. uint64_t val;
  106. #else
  107. typename Traits::ULong val[16];
  108. #endif // BUILDFLAG(IS_ANDROID)
  109. };
  110. #if defined(ARCH_CPU_X86_FAMILY)
  111. struct SignalThreadContext32 {
  112. uint32_t xgs;
  113. uint32_t xfs;
  114. uint32_t xes;
  115. uint32_t xds;
  116. uint32_t edi;
  117. uint32_t esi;
  118. uint32_t ebp;
  119. uint32_t esp;
  120. uint32_t ebx;
  121. uint32_t edx;
  122. uint32_t ecx;
  123. uint32_t eax;
  124. uint32_t trapno;
  125. uint32_t err;
  126. uint32_t eip;
  127. uint32_t xcs;
  128. uint32_t eflags;
  129. uint32_t uesp;
  130. uint32_t xss;
  131. };
  132. struct SignalThreadContext64 {
  133. uint64_t r8;
  134. uint64_t r9;
  135. uint64_t r10;
  136. uint64_t r11;
  137. uint64_t r12;
  138. uint64_t r13;
  139. uint64_t r14;
  140. uint64_t r15;
  141. uint64_t rdi;
  142. uint64_t rsi;
  143. uint64_t rbp;
  144. uint64_t rbx;
  145. uint64_t rdx;
  146. uint64_t rax;
  147. uint64_t rcx;
  148. uint64_t rsp;
  149. uint64_t rip;
  150. uint64_t eflags;
  151. uint16_t cs;
  152. uint16_t gs;
  153. uint16_t fs;
  154. uint16_t padding;
  155. uint64_t err;
  156. uint64_t trapno;
  157. uint64_t oldmask;
  158. uint64_t cr2;
  159. };
  160. struct SignalFloatContext32 {
  161. CPUContextX86::Fsave fsave;
  162. uint16_t status;
  163. uint16_t magic;
  164. CPUContextX86::Fxsave fxsave[0];
  165. };
  166. using SignalFloatContext64 = CPUContextX86_64::Fxsave;
  167. struct ContextTraits32 : public Traits32 {
  168. using ThreadContext = SignalThreadContext32;
  169. using FloatContext = SignalFloatContext32;
  170. };
  171. struct ContextTraits64 : public Traits64 {
  172. using ThreadContext = SignalThreadContext64;
  173. using FloatContext = SignalFloatContext64;
  174. };
  175. template <typename Traits>
  176. struct MContext {
  177. typename Traits::ThreadContext gprs;
  178. typename Traits::Address fpptr;
  179. typename Traits::ULong_32Only oldmask;
  180. typename Traits::ULong_32Only cr2;
  181. typename Traits::ULong_64Only reserved[8];
  182. };
  183. template <typename Traits>
  184. struct UContext {
  185. typename Traits::ULong flags;
  186. typename Traits::Address link;
  187. SignalStack<Traits> stack;
  188. MContext<Traits> mcontext;
  189. Sigset<Traits> sigmask;
  190. char fpregs_mem[0];
  191. };
  192. #elif defined(ARCH_CPU_ARM_FAMILY)
  193. struct CoprocessorContextHead {
  194. uint32_t magic;
  195. uint32_t size;
  196. };
  197. struct SignalFPSIMDContext {
  198. uint32_t fpsr;
  199. uint32_t fpcr;
  200. uint128_struct vregs[32];
  201. };
  202. struct SignalVFPContext {
  203. FloatContext::f32_t::vfp_t vfp;
  204. struct vfp_exc {
  205. uint32_t fpexc;
  206. uint32_t fpinst;
  207. uint32_t fpinst2;
  208. } vfp_exc;
  209. uint32_t padding;
  210. };
  211. struct SignalThreadContext32 {
  212. uint32_t regs[11];
  213. uint32_t fp;
  214. uint32_t ip;
  215. uint32_t sp;
  216. uint32_t lr;
  217. uint32_t pc;
  218. uint32_t cpsr;
  219. };
  220. using SignalThreadContext64 = ThreadContext::t64_t;
  221. struct MContext32Data {
  222. uint32_t trap_no;
  223. uint32_t error_code;
  224. uint32_t oldmask;
  225. SignalThreadContext32 gprs;
  226. uint32_t fault_address;
  227. };
  228. struct MContext64Data {
  229. uint64_t fault_address;
  230. SignalThreadContext64 gprs;
  231. };
  232. struct ContextTraits32 : public Traits32 {
  233. using MContext32 = MContext32Data;
  234. using MContext64 = Nothing;
  235. };
  236. struct ContextTraits64 : public Traits64 {
  237. using MContext32 = Nothing;
  238. using MContext64 = MContext64Data;
  239. };
  240. template <typename Traits>
  241. struct UContext {
  242. typename Traits::ULong flags;
  243. typename Traits::Address link;
  244. SignalStack<Traits> stack;
  245. typename Traits::MContext32 mcontext32;
  246. Sigset<Traits> sigmask;
  247. char padding[128 - sizeof(sigmask)];
  248. typename Traits::Char_64Only padding2[8];
  249. typename Traits::MContext64 mcontext64;
  250. typename Traits::Char_64Only padding3[8];
  251. char reserved[0];
  252. };
  253. #if defined(ARCH_CPU_ARMEL)
  254. static_assert(offsetof(UContext<ContextTraits32>, mcontext32) ==
  255. offsetof(ucontext_t, uc_mcontext),
  256. "context offset mismatch");
  257. static_assert(offsetof(UContext<ContextTraits32>, reserved) ==
  258. offsetof(ucontext_t, uc_regspace),
  259. "regspace offset mismatch");
  260. #elif defined(ARCH_CPU_ARM64)
  261. static_assert(offsetof(UContext<ContextTraits64>, mcontext64) ==
  262. offsetof(ucontext_t, uc_mcontext),
  263. "context offset mismtach");
  264. static_assert(offsetof(UContext<ContextTraits64>, reserved) ==
  265. offsetof(ucontext_t, uc_mcontext) +
  266. offsetof(mcontext_t, __reserved),
  267. "reserved space offset mismtach");
  268. #endif
  269. #elif defined(ARCH_CPU_MIPS_FAMILY)
  270. struct MContext32 {
  271. uint32_t regmask;
  272. uint32_t status;
  273. uint64_t pc;
  274. uint64_t gregs[32];
  275. struct {
  276. float _fp_fregs;
  277. unsigned int _fp_pad;
  278. } fpregs[32];
  279. uint32_t fp_owned;
  280. uint32_t fpc_csr;
  281. uint32_t fpc_eir;
  282. uint32_t used_math;
  283. uint32_t dsp;
  284. uint64_t mdhi;
  285. uint64_t mdlo;
  286. uint32_t hi1;
  287. uint32_t lo1;
  288. uint32_t hi2;
  289. uint32_t lo2;
  290. uint32_t hi3;
  291. uint32_t lo3;
  292. };
  293. struct MContext64 {
  294. uint64_t gregs[32];
  295. double fpregs[32];
  296. uint64_t mdhi;
  297. uint64_t hi1;
  298. uint64_t hi2;
  299. uint64_t hi3;
  300. uint64_t mdlo;
  301. uint64_t lo1;
  302. uint64_t lo2;
  303. uint64_t lo3;
  304. uint64_t pc;
  305. uint32_t fpc_csr;
  306. uint32_t used_math;
  307. uint32_t dsp;
  308. uint32_t __glibc_reserved1;
  309. };
  310. struct SignalThreadContext32 {
  311. uint64_t regs[32];
  312. uint32_t lo;
  313. uint32_t hi;
  314. uint32_t cp0_epc;
  315. uint32_t cp0_badvaddr;
  316. uint32_t cp0_status;
  317. uint32_t cp0_cause;
  318. SignalThreadContext32() {}
  319. explicit SignalThreadContext32(
  320. const struct ThreadContext::t32_t& thread_context) {
  321. for (size_t reg = 0; reg < 32; ++reg) {
  322. regs[reg] = thread_context.regs[reg];
  323. }
  324. lo = thread_context.lo;
  325. hi = thread_context.hi;
  326. cp0_epc = thread_context.cp0_epc;
  327. cp0_badvaddr = thread_context.cp0_badvaddr;
  328. cp0_status = thread_context.cp0_status;
  329. cp0_cause = thread_context.cp0_cause;
  330. }
  331. };
  332. struct ContextTraits32 : public Traits32 {
  333. using MContext = MContext32;
  334. using SignalThreadContext = SignalThreadContext32;
  335. using SignalFloatContext = FloatContext::f32_t;
  336. using CPUContext = CPUContextMIPS;
  337. };
  338. struct ContextTraits64 : public Traits64 {
  339. using MContext = MContext64;
  340. using SignalThreadContext = ThreadContext::t64_t;
  341. using SignalFloatContext = FloatContext::f64_t;
  342. using CPUContext = CPUContextMIPS64;
  343. };
  344. template <typename Traits>
  345. struct UContext {
  346. typename Traits::ULong flags;
  347. typename Traits::Address link;
  348. SignalStack<Traits> stack;
  349. typename Traits::ULong_32Only alignment_padding_;
  350. typename Traits::MContext mcontext;
  351. Sigset<Traits> sigmask;
  352. };
  353. #if defined(ARCH_CPU_MIPSEL)
  354. static_assert(offsetof(UContext<ContextTraits32>, mcontext) ==
  355. offsetof(ucontext_t, uc_mcontext),
  356. "context offset mismatch");
  357. static_assert(offsetof(UContext<ContextTraits32>, mcontext.gregs) ==
  358. offsetof(ucontext_t, uc_mcontext.gregs),
  359. "context offset mismatch");
  360. static_assert(offsetof(UContext<ContextTraits32>, mcontext.fpregs) ==
  361. offsetof(ucontext_t, uc_mcontext.fpregs),
  362. "context offset mismatch");
  363. #elif defined(ARCH_CPU_MIPS64EL)
  364. static_assert(offsetof(UContext<ContextTraits64>, mcontext) ==
  365. offsetof(ucontext_t, uc_mcontext),
  366. "context offset mismtach");
  367. static_assert(offsetof(UContext<ContextTraits64>, mcontext.gregs) ==
  368. offsetof(ucontext_t, uc_mcontext.gregs),
  369. "context offset mismatch");
  370. static_assert(offsetof(UContext<ContextTraits64>, mcontext.fpregs) ==
  371. offsetof(ucontext_t, uc_mcontext.fpregs),
  372. "context offset mismatch");
  373. #endif
  374. #elif defined(ARCH_CPU_RISCV_FAMILY)
  375. struct MContext32 {
  376. uint32_t gregs[32];
  377. uint64_t fpregs[32];
  378. unsigned int fcsr;
  379. };
  380. struct MContext64 {
  381. uint64_t gregs[32];
  382. uint64_t fpregs[32];
  383. unsigned int fcsr;
  384. };
  385. struct ContextTraits32 : public Traits32 {
  386. using MContext = MContext32;
  387. using SignalThreadContext = ThreadContext::t32_t;
  388. using SignalFloatContext = FloatContext::f32_t;
  389. using CPUContext = CPUContextRISCV;
  390. };
  391. struct ContextTraits64 : public Traits64 {
  392. using MContext = MContext64;
  393. using SignalThreadContext = ThreadContext::t64_t;
  394. using SignalFloatContext = FloatContext::f64_t;
  395. using CPUContext = CPUContextRISCV64;
  396. };
  397. template <typename Traits>
  398. struct UContext {
  399. typename Traits::ULong flags;
  400. typename Traits::Address link;
  401. SignalStack<Traits> stack;
  402. Sigset<Traits> sigmask;
  403. char padding[128 - sizeof(sigmask)];
  404. typename Traits::Char_64Only padding2[8];
  405. typename Traits::MContext mcontext;
  406. };
  407. #if defined(ARCH_CPU_RISCV)
  408. static_assert(offsetof(UContext<ContextTraits32>, mcontext) ==
  409. offsetof(ucontext_t, uc_mcontext),
  410. "context offset mismatch");
  411. static_assert(offsetof(UContext<ContextTraits32>, mcontext.gregs) ==
  412. offsetof(ucontext_t, uc_mcontext.__gregs),
  413. "context offset mismatch");
  414. static_assert(offsetof(UContext<ContextTraits32>, mcontext.fpregs) ==
  415. offsetof(ucontext_t, uc_mcontext.__fpregs),
  416. "context offset mismatch");
  417. #elif defined(ARCH_CPU_RISCV64)
  418. static_assert(offsetof(UContext<ContextTraits64>, mcontext) ==
  419. offsetof(ucontext_t, uc_mcontext),
  420. "context offset mismatch");
  421. static_assert(offsetof(UContext<ContextTraits64>, mcontext.gregs) ==
  422. offsetof(ucontext_t, uc_mcontext.__gregs),
  423. "context offset mismatch");
  424. static_assert(offsetof(UContext<ContextTraits64>, mcontext.fpregs) ==
  425. offsetof(ucontext_t, uc_mcontext.__fpregs),
  426. "context offset mismatch");
  427. #endif
  428. #else
  429. #error Port.
  430. #endif // ARCH_CPU_X86_FAMILY
  431. #pragma pack(pop)
  432. } // namespace internal
  433. } // namespace crashpad
  434. #endif // CRASHPAD_SNAPSHOT_LINUX_SNAPSHOT_SIGNAL_CONTEXT_H_