0010-third-party-breakpad-breakpad.patch 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. diff --git a/src/client/linux/dump_writer_common/raw_context_cpu.h b/src/client/linux/dump_writer_common/raw_context_cpu.h
  2. index 07d9171a..24b76143 100644
  3. --- a/src/client/linux/dump_writer_common/raw_context_cpu.h
  4. +++ b/src/client/linux/dump_writer_common/raw_context_cpu.h
  5. @@ -44,6 +44,8 @@ typedef MDRawContextARM RawContextCPU;
  6. typedef MDRawContextARM64_Old RawContextCPU;
  7. #elif defined(__mips__)
  8. typedef MDRawContextMIPS RawContextCPU;
  9. +#elif defined(__riscv)
  10. +typedef MDRawContextRISCV64 RawContextCPU;
  11. #else
  12. #error "This code has not been ported to your platform yet."
  13. #endif
  14. diff --git a/src/client/linux/dump_writer_common/thread_info.cc b/src/client/linux/dump_writer_common/thread_info.cc
  15. index aae1dc13..39013591 100644
  16. --- a/src/client/linux/dump_writer_common/thread_info.cc
  17. +++ b/src/client/linux/dump_writer_common/thread_info.cc
  18. @@ -270,7 +270,22 @@ void ThreadInfo::FillCPUContext(RawContextCPU* out) const {
  19. out->float_save.fir = mcontext.fpc_eir;
  20. #endif
  21. }
  22. -#endif // __mips__
  23. +#elif defined(__riscv)
  24. +
  25. +uintptr_t ThreadInfo::GetInstructionPointer() const {
  26. + return mcontext.__gregs[REG_PC];
  27. +}
  28. +
  29. +void ThreadInfo::FillCPUContext(RawContextCPU* out) const {
  30. + out->context_flags = MD_CONTEXT_RISCV64_FULL;
  31. + my_memcpy (out->iregs, mcontext.__gregs, MD_CONTEXT_RISCV64_GPR_COUNT * 8);
  32. +
  33. + out->float_save.fcsr = mcontext.__fpregs.__d.__fcsr;
  34. + my_memcpy(&out->float_save.regs, &mcontext.__fpregs.__d.__f,
  35. + MD_FLOATINGSAVEAREA_RISCV64_FPR_COUNT * 8);
  36. +}
  37. +
  38. +#endif // __riscv
  39. void ThreadInfo::GetGeneralPurposeRegisters(void** gp_regs, size_t* size) {
  40. assert(gp_regs || size);
  41. @@ -279,6 +294,11 @@ void ThreadInfo::GetGeneralPurposeRegisters(void** gp_regs, size_t* size) {
  42. *gp_regs = mcontext.gregs;
  43. if (size)
  44. *size = sizeof(mcontext.gregs);
  45. +#elif defined(__riscv)
  46. + if (gp_regs)
  47. + *gp_regs = mcontext.__gregs;
  48. + if (size)
  49. + *size = sizeof(mcontext.__gregs);
  50. #else
  51. if (gp_regs)
  52. *gp_regs = &regs;
  53. @@ -294,6 +314,11 @@ void ThreadInfo::GetFloatingPointRegisters(void** fp_regs, size_t* size) {
  54. *fp_regs = &mcontext.fpregs;
  55. if (size)
  56. *size = sizeof(mcontext.fpregs);
  57. +#elif defined(__riscv)
  58. + if (fp_regs)
  59. + *fp_regs = &mcontext.__fpregs;
  60. + if (size)
  61. + *size = sizeof(mcontext.__fpregs);
  62. #else
  63. if (fp_regs)
  64. *fp_regs = &fpregs;
  65. diff --git a/src/client/linux/dump_writer_common/thread_info.h b/src/client/linux/dump_writer_common/thread_info.h
  66. index fb216fa6..65c231b4 100644
  67. --- a/src/client/linux/dump_writer_common/thread_info.h
  68. +++ b/src/client/linux/dump_writer_common/thread_info.h
  69. @@ -68,7 +68,7 @@ struct ThreadInfo {
  70. // Use the structures defined in <sys/user.h>
  71. struct user_regs_struct regs;
  72. struct user_fpsimd_struct fpregs;
  73. -#elif defined(__mips__)
  74. +#elif defined(__mips__) || defined(__riscv)
  75. // Use the structure defined in <sys/ucontext.h>.
  76. mcontext_t mcontext;
  77. #endif
  78. diff --git a/src/client/linux/dump_writer_common/ucontext_reader.cc b/src/client/linux/dump_writer_common/ucontext_reader.cc
  79. index 6eec1be2..c485e52c 100644
  80. --- a/src/client/linux/dump_writer_common/ucontext_reader.cc
  81. +++ b/src/client/linux/dump_writer_common/ucontext_reader.cc
  82. @@ -254,6 +254,26 @@ void UContextReader::FillCPUContext(RawContextCPU* out, const ucontext_t* uc) {
  83. out->float_save.fir = uc->uc_mcontext.fpc_eir; // Unused.
  84. #endif
  85. }
  86. +
  87. +#elif defined(__riscv)
  88. +
  89. +uintptr_t UContextReader::GetStackPointer(const ucontext_t* uc) {
  90. + return uc->uc_mcontext.__gregs[REG_SP];
  91. +}
  92. +
  93. +uintptr_t UContextReader::GetInstructionPointer(const ucontext_t* uc) {
  94. + return uc->uc_mcontext.__gregs[REG_PC];
  95. +}
  96. +
  97. +void UContextReader::FillCPUContext(RawContextCPU* out, const ucontext_t* uc) {
  98. + out->context_flags = MD_CONTEXT_RISCV64_FULL;
  99. + for (int i = 0; i < MD_CONTEXT_RISCV64_GPR_COUNT; ++i)
  100. + out->iregs[i] = uc->uc_mcontext.__gregs[i];
  101. +
  102. + out->float_save.fcsr = uc->uc_mcontext.__fpregs.__d.__fcsr;
  103. + for (int i = 0; i < MD_FLOATINGSAVEAREA_RISCV64_FPR_COUNT; ++i)
  104. + out->float_save.regs[i] = uc->uc_mcontext.__fpregs.__d.__f[i];
  105. +}
  106. #endif
  107. } // namespace google_breakpad
  108. diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
  109. index 499be0a9..7e24a027 100644
  110. --- a/src/client/linux/handler/exception_handler.cc
  111. +++ b/src/client/linux/handler/exception_handler.cc
  112. @@ -461,7 +461,7 @@ bool ExceptionHandler::HandleSignal(int /*sig*/, siginfo_t* info, void* uc) {
  113. memcpy(&g_crash_context_.float_state, fp_ptr,
  114. sizeof(g_crash_context_.float_state));
  115. }
  116. -#elif !defined(__ARM_EABI__) && !defined(__mips__)
  117. +#elif !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  118. // FP state is not part of user ABI on ARM Linux.
  119. // In case of MIPS Linux FP state is already part of ucontext_t
  120. // and 'float_state' is not a member of CrashContext.
  121. @@ -701,7 +701,7 @@ bool ExceptionHandler::WriteMinidump() {
  122. }
  123. #endif
  124. -#if !defined(__ARM_EABI__) && !defined(__aarch64__) && !defined(__mips__)
  125. +#if !defined(__ARM_EABI__) && !defined(__aarch64__) && !defined(__mips__) && !defined(__riscv)
  126. // FPU state is not part of ARM EABI ucontext_t.
  127. memcpy(&context.float_state, context.context.uc_mcontext.fpregs,
  128. sizeof(context.float_state));
  129. @@ -726,6 +726,9 @@ bool ExceptionHandler::WriteMinidump() {
  130. #elif defined(__mips__)
  131. context.siginfo.si_addr =
  132. reinterpret_cast<void*>(context.context.uc_mcontext.pc);
  133. +#elif defined(__riscv)
  134. + context.siginfo.si_addr =
  135. + reinterpret_cast<void*>(context.context.uc_mcontext.__gregs[REG_PC]);
  136. #else
  137. #error "This code has not been ported to your platform yet."
  138. #endif
  139. diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h
  140. index f80843ea..6d2ab077 100644
  141. --- a/src/client/linux/handler/exception_handler.h
  142. +++ b/src/client/linux/handler/exception_handler.h
  143. @@ -192,7 +192,7 @@ class ExceptionHandler {
  144. siginfo_t siginfo;
  145. pid_t tid; // the crashing thread.
  146. ucontext_t context;
  147. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  148. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  149. // #ifdef this out because FP state is not part of user ABI for Linux ARM.
  150. // In case of MIPS Linux FP state is already part of ucontext_t so
  151. // 'float_state' is not required.
  152. diff --git a/src/client/linux/microdump_writer/microdump_writer.cc b/src/client/linux/microdump_writer/microdump_writer.cc
  153. index 22edb1b8..84fb37b9 100644
  154. --- a/src/client/linux/microdump_writer/microdump_writer.cc
  155. +++ b/src/client/linux/microdump_writer/microdump_writer.cc
  156. @@ -138,7 +138,7 @@ class MicrodumpWriter {
  157. const MicrodumpExtraInfo& microdump_extra_info,
  158. LinuxDumper* dumper)
  159. : ucontext_(context ? &context->context : NULL),
  160. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  161. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  162. float_state_(context ? &context->float_state : NULL),
  163. #endif
  164. dumper_(dumper),
  165. @@ -337,6 +337,12 @@ class MicrodumpWriter {
  166. # else
  167. # error "This mips ABI is currently not supported (n32)"
  168. #endif
  169. +#elif defined(__riscv)
  170. +# if __riscv_xlen == 64
  171. + const char kArch[] = "riscv64";
  172. +#else
  173. +# error "This RISC-V ABI is currently not supported"
  174. +#endif
  175. #else
  176. #error "This code has not been ported to your platform yet"
  177. #endif
  178. @@ -409,7 +415,7 @@ class MicrodumpWriter {
  179. void DumpCPUState() {
  180. RawContextCPU cpu;
  181. my_memset(&cpu, 0, sizeof(RawContextCPU));
  182. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  183. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  184. UContextReader::FillCPUContext(&cpu, ucontext_, float_state_);
  185. #else
  186. UContextReader::FillCPUContext(&cpu, ucontext_);
  187. @@ -605,7 +611,7 @@ class MicrodumpWriter {
  188. void* Alloc(unsigned bytes) { return dumper_->allocator()->Alloc(bytes); }
  189. const ucontext_t* const ucontext_;
  190. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  191. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  192. const google_breakpad::fpstate_t* const float_state_;
  193. #endif
  194. LinuxDumper* dumper_;
  195. diff --git a/src/client/linux/minidump_writer/linux_core_dumper.cc b/src/client/linux/minidump_writer/linux_core_dumper.cc
  196. index 92e3a844..1789c810 100644
  197. --- a/src/client/linux/minidump_writer/linux_core_dumper.cc
  198. +++ b/src/client/linux/minidump_writer/linux_core_dumper.cc
  199. @@ -112,6 +112,9 @@ bool LinuxCoreDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) {
  200. #elif defined(__mips__)
  201. stack_pointer =
  202. reinterpret_cast<uint8_t*>(info->mcontext.gregs[MD_CONTEXT_MIPS_REG_SP]);
  203. +#elif defined(__riscv)
  204. + stack_pointer =
  205. + reinterpret_cast<uint8_t*>(info->mcontext.__gregs[MD_CONTEXT_RISCV64_REG_SP]);
  206. #else
  207. #error "This code hasn't been ported to your platform yet."
  208. #endif
  209. @@ -218,6 +221,8 @@ bool LinuxCoreDumper::EnumerateThreads() {
  210. info.mcontext.mdlo = status->pr_reg[EF_LO];
  211. info.mcontext.mdhi = status->pr_reg[EF_HI];
  212. info.mcontext.pc = status->pr_reg[EF_CP0_EPC];
  213. +#elif defined(__riscv)
  214. + memcpy(info.mcontext.__gregs, status->pr_reg, sizeof(info.mcontext.__gregs));
  215. #else // __mips__
  216. memcpy(&info.regs, status->pr_reg, sizeof(info.regs));
  217. #endif // __mips__
  218. diff --git a/src/client/linux/minidump_writer/linux_dumper.h b/src/client/linux/minidump_writer/linux_dumper.h
  219. index 7bee160f..df04e2c0 100644
  220. --- a/src/client/linux/minidump_writer/linux_dumper.h
  221. +++ b/src/client/linux/minidump_writer/linux_dumper.h
  222. @@ -63,7 +63,8 @@ namespace google_breakpad {
  223. (defined(__mips__) && _MIPS_SIM == _ABIO32)
  224. typedef Elf32_auxv_t elf_aux_entry;
  225. #elif defined(__x86_64) || defined(__aarch64__) || \
  226. - (defined(__mips__) && _MIPS_SIM != _ABIO32)
  227. + (defined(__mips__) && _MIPS_SIM != _ABIO32) || \
  228. + (defined(__riscv) && __riscv_xlen == 64)
  229. typedef Elf64_auxv_t elf_aux_entry;
  230. #endif
  231. diff --git a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
  232. index e3ddb81a..0295fa3b 100644
  233. --- a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
  234. +++ b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
  235. @@ -298,6 +298,9 @@ bool LinuxPtraceDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) {
  236. #elif defined(__mips__)
  237. stack_pointer =
  238. reinterpret_cast<uint8_t*>(info->mcontext.gregs[MD_CONTEXT_MIPS_REG_SP]);
  239. +#elif defined(__riscv)
  240. + stack_pointer =
  241. + reinterpret_cast<uint8_t*>(info->mcontext.__gregs[MD_CONTEXT_RISCV64_REG_SP]);
  242. #else
  243. #error "This code hasn't been ported to your platform yet."
  244. #endif
  245. diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc
  246. index 72a92166..bc54a4bb 100644
  247. --- a/src/client/linux/minidump_writer/minidump_writer.cc
  248. +++ b/src/client/linux/minidump_writer/minidump_writer.cc
  249. @@ -136,7 +136,7 @@ class MinidumpWriter {
  250. : fd_(minidump_fd),
  251. path_(minidump_path),
  252. ucontext_(context ? &context->context : NULL),
  253. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  254. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  255. float_state_(context ? &context->float_state : NULL),
  256. #endif
  257. dumper_(dumper),
  258. @@ -468,7 +468,7 @@ class MinidumpWriter {
  259. if (!cpu.Allocate())
  260. return false;
  261. my_memset(cpu.get(), 0, sizeof(RawContextCPU));
  262. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  263. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  264. UContextReader::FillCPUContext(cpu.get(), ucontext_, float_state_);
  265. #else
  266. UContextReader::FillCPUContext(cpu.get(), ucontext_);
  267. @@ -897,7 +897,7 @@ class MinidumpWriter {
  268. dirent->location.rva = 0;
  269. }
  270. -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__)
  271. +#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || defined(__riscv)
  272. bool WriteCPUInformation(MDRawSystemInfo* sys_info) {
  273. char vendor_id[sizeof(sys_info->cpu.x86_cpu_info.vendor_id) + 1] = {0};
  274. static const char vendor_id_name[] = "vendor_id";
  275. @@ -925,6 +925,12 @@ class MinidumpWriter {
  276. # else
  277. # error "This mips ABI is currently not supported (n32)"
  278. #endif
  279. +#elif defined(__riscv)
  280. +# if __riscv_xlen == 64
  281. + MD_CPU_ARCHITECTURE_RISCV64;
  282. +# else
  283. +# error "This RISC-V ABI us currently not supported"
  284. +# endif
  285. #elif defined(__i386__)
  286. MD_CPU_ARCHITECTURE_X86;
  287. #else
  288. @@ -1333,7 +1339,7 @@ class MinidumpWriter {
  289. const char* path_; // Path to the file where the minidum should be written.
  290. const ucontext_t* const ucontext_; // also from the signal handler
  291. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  292. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  293. const google_breakpad::fpstate_t* const float_state_; // ditto
  294. #endif
  295. LinuxDumper* dumper_;
  296. diff --git a/src/client/linux/minidump_writer/minidump_writer.h b/src/client/linux/minidump_writer/minidump_writer.h
  297. index e3b0b16d..0d18c328 100644
  298. --- a/src/client/linux/minidump_writer/minidump_writer.h
  299. +++ b/src/client/linux/minidump_writer/minidump_writer.h
  300. @@ -48,7 +48,7 @@ class ExceptionHandler;
  301. #if defined(__aarch64__)
  302. typedef struct fpsimd_context fpstate_t;
  303. -#elif !defined(__ARM_EABI__) && !defined(__mips__)
  304. +#elif !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  305. typedef std::remove_pointer<fpregset_t>::type fpstate_t;
  306. #endif
  307. diff --git a/src/common/linux/breakpad_getcontext.S b/src/common/linux/breakpad_getcontext.S
  308. index 2ebcf319..b3c2873b 100644
  309. --- a/src/common/linux/breakpad_getcontext.S
  310. +++ b/src/common/linux/breakpad_getcontext.S
  311. @@ -526,6 +526,67 @@ breakpad_getcontext:
  312. ret
  313. .cfi_endproc
  314. .size breakpad_getcontext, . - breakpad_getcontext
  315. +#elif defined(__riscv) && __riscv_xlen == 64
  316. +
  317. +#define __NR_rt_sigprocmask 135
  318. +#define _NSIG8 64 / 8
  319. +#define SIG_BLOCK 0
  320. +
  321. + .text
  322. + .global breakpad_getcontext
  323. + .hidden breakpad_getcontext
  324. + .type breakpad_getcontext, @function
  325. + .align 2
  326. +breakpad_getcontext:
  327. + sd ra, MCONTEXT_GREGS_OFFSET + 0*8(a0)
  328. + sd ra, MCONTEXT_GREGS_OFFSET + 1*8(a0)
  329. + sd sp, MCONTEXT_GREGS_OFFSET + 2*8(a0)
  330. + sd s0, MCONTEXT_GREGS_OFFSET + 8*8(a0)
  331. + sd s1, MCONTEXT_GREGS_OFFSET + 9*8(a0)
  332. + sd x0, MCONTEXT_GREGS_OFFSET + 10*8(a0) /* return 0 by overwriting a0. */
  333. + sd s2, MCONTEXT_GREGS_OFFSET + 18*8(a0)
  334. + sd s3, MCONTEXT_GREGS_OFFSET + 19*8(a0)
  335. + sd s4, MCONTEXT_GREGS_OFFSET + 20*8(a0)
  336. + sd s5, MCONTEXT_GREGS_OFFSET + 21*8(a0)
  337. + sd s6, MCONTEXT_GREGS_OFFSET + 22*8(a0)
  338. + sd s7, MCONTEXT_GREGS_OFFSET + 23*8(a0)
  339. + sd s8, MCONTEXT_GREGS_OFFSET + 24*8(a0)
  340. + sd s9, MCONTEXT_GREGS_OFFSET + 25*8(a0)
  341. + sd s10, MCONTEXT_GREGS_OFFSET + 26*8(a0)
  342. + sd s11, MCONTEXT_GREGS_OFFSET + 27*8(a0)
  343. +
  344. +#ifndef __riscv_float_abi_soft
  345. + frsr a1
  346. +
  347. + fsd fs0, MCONTEXT_FPREGS_OFFSET + 8*8(a0)
  348. + fsd fs1, MCONTEXT_FPREGS_OFFSET + 9*8(a0)
  349. + fsd fs2, MCONTEXT_FPREGS_OFFSET + 18*8(a0)
  350. + fsd fs3, MCONTEXT_FPREGS_OFFSET + 19*8(a0)
  351. + fsd fs4, MCONTEXT_FPREGS_OFFSET + 20*8(a0)
  352. + fsd fs5, MCONTEXT_FPREGS_OFFSET + 21*8(a0)
  353. + fsd fs6, MCONTEXT_FPREGS_OFFSET + 22*8(a0)
  354. + fsd fs7, MCONTEXT_FPREGS_OFFSET + 23*8(a0)
  355. + fsd fs8, MCONTEXT_FPREGS_OFFSET + 24*8(a0)
  356. + fsd fs9, MCONTEXT_FPREGS_OFFSET + 25*8(a0)
  357. + fsd fs10, MCONTEXT_FPREGS_OFFSET + 26*8(a0)
  358. + fsd fs11, MCONTEXT_FPREGS_OFFSET + 27*8(a0)
  359. +
  360. + sw a1, MCONTEXT_FSR_OFFSET(a0)
  361. +#endif /* __riscv_float_abi_soft */
  362. +
  363. +/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG / 8) */
  364. + li a3, _NSIG8
  365. + add a2, a0, UCONTEXT_SIGMASK_OFFSET
  366. + mv a1, zero
  367. + li a0, SIG_BLOCK
  368. +
  369. + li a7, __NR_rt_sigprocmask
  370. + scall
  371. +
  372. + /* Always return 0 for success, even if sigprocmask failed. */
  373. + mv a0, zero
  374. + ret
  375. + .size breakpad_getcontext, . - breakpad_getcontext
  376. #else
  377. #error "This file has not been ported for your CPU!"
  378. diff --git a/src/common/linux/memory_mapped_file.cc b/src/common/linux/memory_mapped_file.cc
  379. index 99362945..f70549fd 100644
  380. --- a/src/common/linux/memory_mapped_file.cc
  381. +++ b/src/common/linux/memory_mapped_file.cc
  382. @@ -65,7 +65,8 @@ bool MemoryMappedFile::Map(const char* path, size_t offset) {
  383. }
  384. #if defined(__x86_64__) || defined(__aarch64__) || \
  385. - (defined(__mips__) && _MIPS_SIM == _ABI64)
  386. + (defined(__mips__) && _MIPS_SIM == _ABI64) || \
  387. + (defined(__riscv) && __riscv_xlen == 64)
  388. struct kernel_stat st;
  389. if (sys_fstat(fd, &st) == -1 || st.st_size < 0) {
  390. diff --git a/src/common/linux/ucontext_constants.h b/src/common/linux/ucontext_constants.h
  391. index c390508a..0a970e3b 100644
  392. --- a/src/common/linux/ucontext_constants.h
  393. +++ b/src/common/linux/ucontext_constants.h
  394. @@ -146,6 +146,14 @@
  395. #endif
  396. #define FPREGS_OFFSET_MXCSR 24
  397. +#elif defined(__riscv)
  398. +
  399. +#define UCONTEXT_SIGMASK_OFFSET 40
  400. +
  401. +#define MCONTEXT_GREGS_OFFSET 176
  402. +#define MCONTEXT_FPREGS_OFFSET 432
  403. +#define MCONTEXT_FSR_OFFSET (MCONTEXT_FPREGS_OFFSET + 32*8)
  404. +
  405. #else
  406. #error "This header has not been ported for your CPU"
  407. #endif
  408. diff --git a/src/google_breakpad/common/minidump_format.h b/src/google_breakpad/common/minidump_format.h
  409. index 7b36d112..1013a891 100644
  410. --- a/src/google_breakpad/common/minidump_format.h
  411. +++ b/src/google_breakpad/common/minidump_format.h
  412. @@ -118,6 +118,7 @@ typedef struct {
  413. #include "minidump_cpu_mips.h"
  414. #include "minidump_cpu_ppc.h"
  415. #include "minidump_cpu_ppc64.h"
  416. +#include "minidump_cpu_riscv64.h"
  417. #include "minidump_cpu_sparc.h"
  418. #include "minidump_cpu_x86.h"
  419. @@ -660,6 +661,7 @@ typedef enum {
  420. MD_CPU_ARCHITECTURE_PPC64 = 0x8002, /* Breakpad-defined value for PPC64 */
  421. MD_CPU_ARCHITECTURE_ARM64_OLD = 0x8003, /* Breakpad-defined value for ARM64 */
  422. MD_CPU_ARCHITECTURE_MIPS64 = 0x8004, /* Breakpad-defined value for MIPS64 */
  423. + MD_CPU_ARCHITECTURE_RISCV64 = 0x8005, /* Breakpad-defined value for RISCV64 */
  424. MD_CPU_ARCHITECTURE_UNKNOWN = 0xffff /* PROCESSOR_ARCHITECTURE_UNKNOWN */
  425. } MDCPUArchitecture;