0005-breakpad.patch 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. From 5f21ccb93d1f34564911c7474124fd0827d71297 Mon Sep 17 00:00:00 2001
  2. From: Rebecca Chang Swee Fun <rebecca.chang@starfivetech.com>
  3. Date: Wed, 22 Jun 2022 08:52:24 +0000
  4. Subject: [PATCH] patch for riscv64
  5. Signed-off-by: Rebecca Chang Swee Fun <rebecca.chang@starfivetech.com>
  6. ---
  7. .../dump_writer_common/raw_context_cpu.h | 2 +
  8. .../linux/dump_writer_common/thread_info.cc | 27 +++-
  9. .../linux/dump_writer_common/thread_info.h | 2 +-
  10. .../dump_writer_common/ucontext_reader.cc | 20 +++
  11. src/client/linux/handler/exception_handler.cc | 7 +-
  12. src/client/linux/handler/exception_handler.h | 2 +-
  13. .../microdump_writer/microdump_writer.cc | 12 +-
  14. .../minidump_writer/linux_core_dumper.cc | 5 +
  15. .../linux/minidump_writer/linux_dumper.h | 3 +-
  16. .../minidump_writer/linux_ptrace_dumper.cc | 3 +
  17. .../linux/minidump_writer/minidump_writer.cc | 14 +-
  18. .../linux/minidump_writer/minidump_writer.h | 2 +-
  19. src/common/linux/breakpad_getcontext.S | 61 +++++++++
  20. src/common/linux/memory_mapped_file.cc | 3 +-
  21. src/common/linux/ucontext_constants.h | 8 ++
  22. .../common/minidump_cpu_riscv64.h | 121 ++++++++++++++++++
  23. src/google_breakpad/common/minidump_format.h | 2 +
  24. 17 files changed, 279 insertions(+), 15 deletions(-)
  25. create mode 100644 src/google_breakpad/common/minidump_cpu_riscv64.h
  26. diff --git a/src/client/linux/dump_writer_common/raw_context_cpu.h b/src/client/linux/dump_writer_common/raw_context_cpu.h
  27. index 07d9171a..24b76143 100644
  28. --- a/src/client/linux/dump_writer_common/raw_context_cpu.h
  29. +++ b/src/client/linux/dump_writer_common/raw_context_cpu.h
  30. @@ -44,6 +44,8 @@ typedef MDRawContextARM RawContextCPU;
  31. typedef MDRawContextARM64_Old RawContextCPU;
  32. #elif defined(__mips__)
  33. typedef MDRawContextMIPS RawContextCPU;
  34. +#elif defined(__riscv)
  35. +typedef MDRawContextRISCV64 RawContextCPU;
  36. #else
  37. #error "This code has not been ported to your platform yet."
  38. #endif
  39. diff --git a/src/client/linux/dump_writer_common/thread_info.cc b/src/client/linux/dump_writer_common/thread_info.cc
  40. index aae1dc13..39013591 100644
  41. --- a/src/client/linux/dump_writer_common/thread_info.cc
  42. +++ b/src/client/linux/dump_writer_common/thread_info.cc
  43. @@ -270,7 +270,22 @@ void ThreadInfo::FillCPUContext(RawContextCPU* out) const {
  44. out->float_save.fir = mcontext.fpc_eir;
  45. #endif
  46. }
  47. -#endif // __mips__
  48. +#elif defined(__riscv)
  49. +
  50. +uintptr_t ThreadInfo::GetInstructionPointer() const {
  51. + return mcontext.__gregs[REG_PC];
  52. +}
  53. +
  54. +void ThreadInfo::FillCPUContext(RawContextCPU* out) const {
  55. + out->context_flags = MD_CONTEXT_RISCV64_FULL;
  56. + my_memcpy (out->iregs, mcontext.__gregs, MD_CONTEXT_RISCV64_GPR_COUNT * 8);
  57. +
  58. + out->float_save.fcsr = mcontext.__fpregs.__d.__fcsr;
  59. + my_memcpy(&out->float_save.regs, &mcontext.__fpregs.__d.__f,
  60. + MD_FLOATINGSAVEAREA_RISCV64_FPR_COUNT * 8);
  61. +}
  62. +
  63. +#endif // __riscv
  64. void ThreadInfo::GetGeneralPurposeRegisters(void** gp_regs, size_t* size) {
  65. assert(gp_regs || size);
  66. @@ -279,6 +294,11 @@ void ThreadInfo::GetGeneralPurposeRegisters(void** gp_regs, size_t* size) {
  67. *gp_regs = mcontext.gregs;
  68. if (size)
  69. *size = sizeof(mcontext.gregs);
  70. +#elif defined(__riscv)
  71. + if (gp_regs)
  72. + *gp_regs = mcontext.__gregs;
  73. + if (size)
  74. + *size = sizeof(mcontext.__gregs);
  75. #else
  76. if (gp_regs)
  77. *gp_regs = &regs;
  78. @@ -294,6 +314,11 @@ void ThreadInfo::GetFloatingPointRegisters(void** fp_regs, size_t* size) {
  79. *fp_regs = &mcontext.fpregs;
  80. if (size)
  81. *size = sizeof(mcontext.fpregs);
  82. +#elif defined(__riscv)
  83. + if (fp_regs)
  84. + *fp_regs = &mcontext.__fpregs;
  85. + if (size)
  86. + *size = sizeof(mcontext.__fpregs);
  87. #else
  88. if (fp_regs)
  89. *fp_regs = &fpregs;
  90. diff --git a/src/client/linux/dump_writer_common/thread_info.h b/src/client/linux/dump_writer_common/thread_info.h
  91. index fb216fa6..65c231b4 100644
  92. --- a/src/client/linux/dump_writer_common/thread_info.h
  93. +++ b/src/client/linux/dump_writer_common/thread_info.h
  94. @@ -68,7 +68,7 @@ struct ThreadInfo {
  95. // Use the structures defined in <sys/user.h>
  96. struct user_regs_struct regs;
  97. struct user_fpsimd_struct fpregs;
  98. -#elif defined(__mips__)
  99. +#elif defined(__mips__) || defined(__riscv)
  100. // Use the structure defined in <sys/ucontext.h>.
  101. mcontext_t mcontext;
  102. #endif
  103. diff --git a/src/client/linux/dump_writer_common/ucontext_reader.cc b/src/client/linux/dump_writer_common/ucontext_reader.cc
  104. index 6eec1be2..c485e52c 100644
  105. --- a/src/client/linux/dump_writer_common/ucontext_reader.cc
  106. +++ b/src/client/linux/dump_writer_common/ucontext_reader.cc
  107. @@ -254,6 +254,26 @@ void UContextReader::FillCPUContext(RawContextCPU* out, const ucontext_t* uc) {
  108. out->float_save.fir = uc->uc_mcontext.fpc_eir; // Unused.
  109. #endif
  110. }
  111. +
  112. +#elif defined(__riscv)
  113. +
  114. +uintptr_t UContextReader::GetStackPointer(const ucontext_t* uc) {
  115. + return uc->uc_mcontext.__gregs[REG_SP];
  116. +}
  117. +
  118. +uintptr_t UContextReader::GetInstructionPointer(const ucontext_t* uc) {
  119. + return uc->uc_mcontext.__gregs[REG_PC];
  120. +}
  121. +
  122. +void UContextReader::FillCPUContext(RawContextCPU* out, const ucontext_t* uc) {
  123. + out->context_flags = MD_CONTEXT_RISCV64_FULL;
  124. + for (int i = 0; i < MD_CONTEXT_RISCV64_GPR_COUNT; ++i)
  125. + out->iregs[i] = uc->uc_mcontext.__gregs[i];
  126. +
  127. + out->float_save.fcsr = uc->uc_mcontext.__fpregs.__d.__fcsr;
  128. + for (int i = 0; i < MD_FLOATINGSAVEAREA_RISCV64_FPR_COUNT; ++i)
  129. + out->float_save.regs[i] = uc->uc_mcontext.__fpregs.__d.__f[i];
  130. +}
  131. #endif
  132. } // namespace google_breakpad
  133. diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
  134. index 499be0a9..7e24a027 100644
  135. --- a/src/client/linux/handler/exception_handler.cc
  136. +++ b/src/client/linux/handler/exception_handler.cc
  137. @@ -461,7 +461,7 @@ bool ExceptionHandler::HandleSignal(int /*sig*/, siginfo_t* info, void* uc) {
  138. memcpy(&g_crash_context_.float_state, fp_ptr,
  139. sizeof(g_crash_context_.float_state));
  140. }
  141. -#elif !defined(__ARM_EABI__) && !defined(__mips__)
  142. +#elif !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  143. // FP state is not part of user ABI on ARM Linux.
  144. // In case of MIPS Linux FP state is already part of ucontext_t
  145. // and 'float_state' is not a member of CrashContext.
  146. @@ -701,7 +701,7 @@ bool ExceptionHandler::WriteMinidump() {
  147. }
  148. #endif
  149. -#if !defined(__ARM_EABI__) && !defined(__aarch64__) && !defined(__mips__)
  150. +#if !defined(__ARM_EABI__) && !defined(__aarch64__) && !defined(__mips__) && !defined(__riscv)
  151. // FPU state is not part of ARM EABI ucontext_t.
  152. memcpy(&context.float_state, context.context.uc_mcontext.fpregs,
  153. sizeof(context.float_state));
  154. @@ -726,6 +726,9 @@ bool ExceptionHandler::WriteMinidump() {
  155. #elif defined(__mips__)
  156. context.siginfo.si_addr =
  157. reinterpret_cast<void*>(context.context.uc_mcontext.pc);
  158. +#elif defined(__riscv)
  159. + context.siginfo.si_addr =
  160. + reinterpret_cast<void*>(context.context.uc_mcontext.__gregs[REG_PC]);
  161. #else
  162. #error "This code has not been ported to your platform yet."
  163. #endif
  164. diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h
  165. index f80843ea..6d2ab077 100644
  166. --- a/src/client/linux/handler/exception_handler.h
  167. +++ b/src/client/linux/handler/exception_handler.h
  168. @@ -192,7 +192,7 @@ class ExceptionHandler {
  169. siginfo_t siginfo;
  170. pid_t tid; // the crashing thread.
  171. ucontext_t context;
  172. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  173. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  174. // #ifdef this out because FP state is not part of user ABI for Linux ARM.
  175. // In case of MIPS Linux FP state is already part of ucontext_t so
  176. // 'float_state' is not required.
  177. diff --git a/src/client/linux/microdump_writer/microdump_writer.cc b/src/client/linux/microdump_writer/microdump_writer.cc
  178. index 22edb1b8..84fb37b9 100644
  179. --- a/src/client/linux/microdump_writer/microdump_writer.cc
  180. +++ b/src/client/linux/microdump_writer/microdump_writer.cc
  181. @@ -138,7 +138,7 @@ class MicrodumpWriter {
  182. const MicrodumpExtraInfo& microdump_extra_info,
  183. LinuxDumper* dumper)
  184. : ucontext_(context ? &context->context : NULL),
  185. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  186. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  187. float_state_(context ? &context->float_state : NULL),
  188. #endif
  189. dumper_(dumper),
  190. @@ -337,6 +337,12 @@ class MicrodumpWriter {
  191. # else
  192. # error "This mips ABI is currently not supported (n32)"
  193. #endif
  194. +#elif defined(__riscv)
  195. +# if __riscv_xlen == 64
  196. + const char kArch[] = "riscv64";
  197. +#else
  198. +# error "This RISC-V ABI is currently not supported"
  199. +#endif
  200. #else
  201. #error "This code has not been ported to your platform yet"
  202. #endif
  203. @@ -409,7 +415,7 @@ class MicrodumpWriter {
  204. void DumpCPUState() {
  205. RawContextCPU cpu;
  206. my_memset(&cpu, 0, sizeof(RawContextCPU));
  207. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  208. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  209. UContextReader::FillCPUContext(&cpu, ucontext_, float_state_);
  210. #else
  211. UContextReader::FillCPUContext(&cpu, ucontext_);
  212. @@ -605,7 +611,7 @@ class MicrodumpWriter {
  213. void* Alloc(unsigned bytes) { return dumper_->allocator()->Alloc(bytes); }
  214. const ucontext_t* const ucontext_;
  215. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  216. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  217. const google_breakpad::fpstate_t* const float_state_;
  218. #endif
  219. LinuxDumper* dumper_;
  220. diff --git a/src/client/linux/minidump_writer/linux_core_dumper.cc b/src/client/linux/minidump_writer/linux_core_dumper.cc
  221. index 92e3a844..1789c810 100644
  222. --- a/src/client/linux/minidump_writer/linux_core_dumper.cc
  223. +++ b/src/client/linux/minidump_writer/linux_core_dumper.cc
  224. @@ -112,6 +112,9 @@ bool LinuxCoreDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) {
  225. #elif defined(__mips__)
  226. stack_pointer =
  227. reinterpret_cast<uint8_t*>(info->mcontext.gregs[MD_CONTEXT_MIPS_REG_SP]);
  228. +#elif defined(__riscv)
  229. + stack_pointer =
  230. + reinterpret_cast<uint8_t*>(info->mcontext.__gregs[MD_CONTEXT_RISCV64_REG_SP]);
  231. #else
  232. #error "This code hasn't been ported to your platform yet."
  233. #endif
  234. @@ -218,6 +221,8 @@ bool LinuxCoreDumper::EnumerateThreads() {
  235. info.mcontext.mdlo = status->pr_reg[EF_LO];
  236. info.mcontext.mdhi = status->pr_reg[EF_HI];
  237. info.mcontext.pc = status->pr_reg[EF_CP0_EPC];
  238. +#elif defined(__riscv)
  239. + memcpy(info.mcontext.__gregs, status->pr_reg, sizeof(info.mcontext.__gregs));
  240. #else // __mips__
  241. memcpy(&info.regs, status->pr_reg, sizeof(info.regs));
  242. #endif // __mips__
  243. diff --git a/src/client/linux/minidump_writer/linux_dumper.h b/src/client/linux/minidump_writer/linux_dumper.h
  244. index 7bee160f..df04e2c0 100644
  245. --- a/src/client/linux/minidump_writer/linux_dumper.h
  246. +++ b/src/client/linux/minidump_writer/linux_dumper.h
  247. @@ -63,7 +63,8 @@ namespace google_breakpad {
  248. (defined(__mips__) && _MIPS_SIM == _ABIO32)
  249. typedef Elf32_auxv_t elf_aux_entry;
  250. #elif defined(__x86_64) || defined(__aarch64__) || \
  251. - (defined(__mips__) && _MIPS_SIM != _ABIO32)
  252. + (defined(__mips__) && _MIPS_SIM != _ABIO32) || \
  253. + (defined(__riscv) && __riscv_xlen == 64)
  254. typedef Elf64_auxv_t elf_aux_entry;
  255. #endif
  256. diff --git a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
  257. index e3ddb81a..0295fa3b 100644
  258. --- a/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
  259. +++ b/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
  260. @@ -298,6 +298,9 @@ bool LinuxPtraceDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) {
  261. #elif defined(__mips__)
  262. stack_pointer =
  263. reinterpret_cast<uint8_t*>(info->mcontext.gregs[MD_CONTEXT_MIPS_REG_SP]);
  264. +#elif defined(__riscv)
  265. + stack_pointer =
  266. + reinterpret_cast<uint8_t*>(info->mcontext.__gregs[MD_CONTEXT_RISCV64_REG_SP]);
  267. #else
  268. #error "This code hasn't been ported to your platform yet."
  269. #endif
  270. diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc
  271. index 7ce9ac57..202a95e0 100644
  272. --- a/src/client/linux/minidump_writer/minidump_writer.cc
  273. +++ b/src/client/linux/minidump_writer/minidump_writer.cc
  274. @@ -141,7 +141,7 @@ class MinidumpWriter {
  275. : fd_(minidump_fd),
  276. path_(minidump_path),
  277. ucontext_(context ? &context->context : NULL),
  278. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  279. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  280. float_state_(context ? &context->float_state : NULL),
  281. #endif
  282. dumper_(dumper),
  283. @@ -473,7 +473,7 @@ class MinidumpWriter {
  284. if (!cpu.Allocate())
  285. return false;
  286. my_memset(cpu.get(), 0, sizeof(RawContextCPU));
  287. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  288. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  289. UContextReader::FillCPUContext(cpu.get(), ucontext_, float_state_);
  290. #else
  291. UContextReader::FillCPUContext(cpu.get(), ucontext_);
  292. @@ -950,7 +950,7 @@ class MinidumpWriter {
  293. dirent->location.rva = 0;
  294. }
  295. -#if defined(__i386__) || defined(__x86_64__) || defined(__mips__)
  296. +#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || defined(__riscv)
  297. bool WriteCPUInformation(MDRawSystemInfo* sys_info) {
  298. char vendor_id[sizeof(sys_info->cpu.x86_cpu_info.vendor_id) + 1] = {0};
  299. static const char vendor_id_name[] = "vendor_id";
  300. @@ -978,6 +978,12 @@ class MinidumpWriter {
  301. # else
  302. # error "This mips ABI is currently not supported (n32)"
  303. #endif
  304. +#elif defined(__riscv)
  305. +# if __riscv_xlen == 64
  306. + MD_CPU_ARCHITECTURE_RISCV64;
  307. +# else
  308. +# error "This RISC-V ABI us currently not supported"
  309. +# endif
  310. #elif defined(__i386__)
  311. MD_CPU_ARCHITECTURE_X86;
  312. #else
  313. @@ -1386,7 +1392,7 @@ class MinidumpWriter {
  314. const char* path_; // Path to the file where the minidum should be written.
  315. const ucontext_t* const ucontext_; // also from the signal handler
  316. -#if !defined(__ARM_EABI__) && !defined(__mips__)
  317. +#if !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  318. const google_breakpad::fpstate_t* const float_state_; // ditto
  319. #endif
  320. LinuxDumper* dumper_;
  321. diff --git a/src/client/linux/minidump_writer/minidump_writer.h b/src/client/linux/minidump_writer/minidump_writer.h
  322. index e3b0b16d..0d18c328 100644
  323. --- a/src/client/linux/minidump_writer/minidump_writer.h
  324. +++ b/src/client/linux/minidump_writer/minidump_writer.h
  325. @@ -48,7 +48,7 @@ class ExceptionHandler;
  326. #if defined(__aarch64__)
  327. typedef struct fpsimd_context fpstate_t;
  328. -#elif !defined(__ARM_EABI__) && !defined(__mips__)
  329. +#elif !defined(__ARM_EABI__) && !defined(__mips__) && !defined(__riscv)
  330. typedef std::remove_pointer<fpregset_t>::type fpstate_t;
  331. #endif
  332. diff --git a/src/common/linux/breakpad_getcontext.S b/src/common/linux/breakpad_getcontext.S
  333. index 2ebcf319..b3c2873b 100644
  334. --- a/src/common/linux/breakpad_getcontext.S
  335. +++ b/src/common/linux/breakpad_getcontext.S
  336. @@ -526,6 +526,67 @@ breakpad_getcontext:
  337. ret
  338. .cfi_endproc
  339. .size breakpad_getcontext, . - breakpad_getcontext
  340. +#elif defined(__riscv) && __riscv_xlen == 64
  341. +
  342. +#define __NR_rt_sigprocmask 135
  343. +#define _NSIG8 64 / 8
  344. +#define SIG_BLOCK 0
  345. +
  346. + .text
  347. + .global breakpad_getcontext
  348. + .hidden breakpad_getcontext
  349. + .type breakpad_getcontext, @function
  350. + .align 2
  351. +breakpad_getcontext:
  352. + sd ra, MCONTEXT_GREGS_OFFSET + 0*8(a0)
  353. + sd ra, MCONTEXT_GREGS_OFFSET + 1*8(a0)
  354. + sd sp, MCONTEXT_GREGS_OFFSET + 2*8(a0)
  355. + sd s0, MCONTEXT_GREGS_OFFSET + 8*8(a0)
  356. + sd s1, MCONTEXT_GREGS_OFFSET + 9*8(a0)
  357. + sd x0, MCONTEXT_GREGS_OFFSET + 10*8(a0) /* return 0 by overwriting a0. */
  358. + sd s2, MCONTEXT_GREGS_OFFSET + 18*8(a0)
  359. + sd s3, MCONTEXT_GREGS_OFFSET + 19*8(a0)
  360. + sd s4, MCONTEXT_GREGS_OFFSET + 20*8(a0)
  361. + sd s5, MCONTEXT_GREGS_OFFSET + 21*8(a0)
  362. + sd s6, MCONTEXT_GREGS_OFFSET + 22*8(a0)
  363. + sd s7, MCONTEXT_GREGS_OFFSET + 23*8(a0)
  364. + sd s8, MCONTEXT_GREGS_OFFSET + 24*8(a0)
  365. + sd s9, MCONTEXT_GREGS_OFFSET + 25*8(a0)
  366. + sd s10, MCONTEXT_GREGS_OFFSET + 26*8(a0)
  367. + sd s11, MCONTEXT_GREGS_OFFSET + 27*8(a0)
  368. +
  369. +#ifndef __riscv_float_abi_soft
  370. + frsr a1
  371. +
  372. + fsd fs0, MCONTEXT_FPREGS_OFFSET + 8*8(a0)
  373. + fsd fs1, MCONTEXT_FPREGS_OFFSET + 9*8(a0)
  374. + fsd fs2, MCONTEXT_FPREGS_OFFSET + 18*8(a0)
  375. + fsd fs3, MCONTEXT_FPREGS_OFFSET + 19*8(a0)
  376. + fsd fs4, MCONTEXT_FPREGS_OFFSET + 20*8(a0)
  377. + fsd fs5, MCONTEXT_FPREGS_OFFSET + 21*8(a0)
  378. + fsd fs6, MCONTEXT_FPREGS_OFFSET + 22*8(a0)
  379. + fsd fs7, MCONTEXT_FPREGS_OFFSET + 23*8(a0)
  380. + fsd fs8, MCONTEXT_FPREGS_OFFSET + 24*8(a0)
  381. + fsd fs9, MCONTEXT_FPREGS_OFFSET + 25*8(a0)
  382. + fsd fs10, MCONTEXT_FPREGS_OFFSET + 26*8(a0)
  383. + fsd fs11, MCONTEXT_FPREGS_OFFSET + 27*8(a0)
  384. +
  385. + sw a1, MCONTEXT_FSR_OFFSET(a0)
  386. +#endif /* __riscv_float_abi_soft */
  387. +
  388. +/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG / 8) */
  389. + li a3, _NSIG8
  390. + add a2, a0, UCONTEXT_SIGMASK_OFFSET
  391. + mv a1, zero
  392. + li a0, SIG_BLOCK
  393. +
  394. + li a7, __NR_rt_sigprocmask
  395. + scall
  396. +
  397. + /* Always return 0 for success, even if sigprocmask failed. */
  398. + mv a0, zero
  399. + ret
  400. + .size breakpad_getcontext, . - breakpad_getcontext
  401. #else
  402. #error "This file has not been ported for your CPU!"
  403. diff --git a/src/common/linux/memory_mapped_file.cc b/src/common/linux/memory_mapped_file.cc
  404. index 99362945..f70549fd 100644
  405. --- a/src/common/linux/memory_mapped_file.cc
  406. +++ b/src/common/linux/memory_mapped_file.cc
  407. @@ -65,7 +65,8 @@ bool MemoryMappedFile::Map(const char* path, size_t offset) {
  408. }
  409. #if defined(__x86_64__) || defined(__aarch64__) || \
  410. - (defined(__mips__) && _MIPS_SIM == _ABI64)
  411. + (defined(__mips__) && _MIPS_SIM == _ABI64) || \
  412. + (defined(__riscv) && __riscv_xlen == 64)
  413. struct kernel_stat st;
  414. if (sys_fstat(fd, &st) == -1 || st.st_size < 0) {
  415. diff --git a/src/common/linux/ucontext_constants.h b/src/common/linux/ucontext_constants.h
  416. index c390508a..0a970e3b 100644
  417. --- a/src/common/linux/ucontext_constants.h
  418. +++ b/src/common/linux/ucontext_constants.h
  419. @@ -146,6 +146,14 @@
  420. #endif
  421. #define FPREGS_OFFSET_MXCSR 24
  422. +#elif defined(__riscv)
  423. +
  424. +#define UCONTEXT_SIGMASK_OFFSET 40
  425. +
  426. +#define MCONTEXT_GREGS_OFFSET 176
  427. +#define MCONTEXT_FPREGS_OFFSET 432
  428. +#define MCONTEXT_FSR_OFFSET (MCONTEXT_FPREGS_OFFSET + 32*8)
  429. +
  430. #else
  431. #error "This header has not been ported for your CPU"
  432. #endif
  433. diff --git a/src/google_breakpad/common/minidump_cpu_riscv64.h b/src/google_breakpad/common/minidump_cpu_riscv64.h
  434. new file mode 100644
  435. index 00000000..801aa821
  436. --- /dev/null
  437. +++ b/src/google_breakpad/common/minidump_cpu_riscv64.h
  438. @@ -0,0 +1,121 @@
  439. +/* Copyright 2013 Google Inc.
  440. + * All rights reserved.
  441. + *
  442. + * Redistribution and use in source and binary forms, with or without
  443. + * modification, are permitted provided that the following conditions are
  444. + * met:
  445. + *
  446. + * * Redistributions of source code must retain the above copyright
  447. + * notice, this list of conditions and the following disclaimer.
  448. + * * Redistributions in binary form must reproduce the above
  449. + * copyright notice, this list of conditions and the following disclaimer
  450. + * in the documentation and/or other materials provided with the
  451. + * distribution.
  452. + * * Neither the name of Google Inc. nor the names of its
  453. + * contributors may be used to endorse or promote products derived from
  454. + * this software without specific prior written permission.
  455. + *
  456. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  457. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  458. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  459. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  460. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  461. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  462. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  463. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  464. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  465. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  466. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
  467. +
  468. +/* minidump_format.h: A cross-platform reimplementation of minidump-related
  469. + * portions of DbgHelp.h from the Windows Platform SDK.
  470. + *
  471. + * (This is C99 source, please don't corrupt it with C.)
  472. + *
  473. + * This file contains the necessary definitions to read minidump files
  474. + * produced on ARM. These files may be read on any platform provided
  475. + * that the alignments of these structures on the processing system are
  476. + * identical to the alignments of these structures on the producing system.
  477. + * For this reason, precise-sized types are used. The structures defined
  478. + * by this file have been laid out to minimize alignment problems by
  479. + * ensuring that all members are aligned on their natural boundaries.
  480. + * In some cases, tail-padding may be significant when different ABIs specify
  481. + * different tail-padding behaviors. To avoid problems when reading or
  482. + * writing affected structures, MD_*_SIZE macros are provided where needed,
  483. + * containing the useful size of the structures without padding.
  484. + *
  485. + * Structures that are defined by Microsoft to contain a zero-length array
  486. + * are instead defined here to contain an array with one element, as
  487. + * zero-length arrays are forbidden by standard C and C. In these cases,
  488. + * *_minsize constants are provided to be used in place of sizeof. For a
  489. + * cleaner interface to these sizes when using C, see minidump_size.h.
  490. + *
  491. + * These structures are also sufficient to populate minidump files.
  492. + *
  493. + * Because precise data type sizes are crucial for this implementation to
  494. + * function properly and portably, a set of primitive types with known sizes
  495. + * are used as the basis of each structure defined by this file.
  496. + *
  497. + * Author: Colin Blundell
  498. + */
  499. +
  500. +/*
  501. + * RISCV64 support
  502. + */
  503. +
  504. +#ifndef GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_RISCV64_H__
  505. +#define GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_RISCV64_H__
  506. +
  507. +#include "google_breakpad/common/breakpad_types.h"
  508. +
  509. +#define MD_FLOATINGSAVEAREA_RISCV64_FPR_COUNT 32
  510. +#define MD_CONTEXT_RISCV64_GPR_COUNT 32
  511. +
  512. +typedef struct {
  513. + /* 32 64-bit floating point registers, f0 .. f31. */
  514. + uint64_t regs[MD_FLOATINGSAVEAREA_RISCV64_FPR_COUNT];
  515. +
  516. + uint32_t fcsr; /* FPU control and status register */
  517. +} MDFloatingSaveAreaRISCV64;
  518. +
  519. +/* For (MDRawContextRISCV64).context_flags. These values indicate the type of
  520. + * context stored in the structure. */
  521. +#define MD_CONTEXT_RISCV64 0x00400000
  522. +#define MD_CONTEXT_RISCV64_CONTROL (MD_CONTEXT_RISCV64 | 0x00000001)
  523. +#define MD_CONTEXT_RISCV64_INTEGER (MD_CONTEXT_RISCV64 | 0x00000002)
  524. +#define MD_CONTEXT_RISCV64_FLOATING_POINT (MD_CONTEXT_RISCV64 | 0x00000004)
  525. +#define MD_CONTEXT_RISCV64_DEBUG (MD_CONTEXT_RISCV64 | 0x00000008)
  526. +#define MD_CONTEXT_RISCV64_FULL (MD_CONTEXT_RISCV64_CONTROL | \
  527. + MD_CONTEXT_RISCV64_INTEGER | \
  528. + MD_CONTEXT_RISCV64_FLOATING_POINT)
  529. +#define MD_CONTEXT_RISCV64_ALL (MD_CONTEXT_RISCV64_FULL | MD_CONTEXT_RISCV64_DEBUG)
  530. +
  531. +typedef struct {
  532. + /* Determines which fields of this struct are populated */
  533. + uint32_t context_flags;
  534. +
  535. + /* 32 64-bit integer registers, x1 .. x31 the PC
  536. + * Note the following fixed uses:
  537. + * x8 is the frame pointer
  538. + * x1 is the link register
  539. + * x2 is the stack pointer
  540. + * The PC is effectively x0.
  541. + */
  542. + uint64_t iregs[MD_CONTEXT_RISCV64_GPR_COUNT];
  543. +
  544. + /* The next field is included with MD_CONTEXT64_ARM_FLOATING_POINT */
  545. + MDFloatingSaveAreaRISCV64 float_save;
  546. +
  547. +} MDRawContextRISCV64;
  548. +
  549. +/* Indices into iregs for registers with a dedicated or conventional
  550. + * purpose.
  551. + */
  552. +enum MDRISCV64RegisterNumbers {
  553. + MD_CONTEXT_RISCV64_REG_FP = 8,
  554. + MD_CONTEXT_RISCV64_REG_RA = 1,
  555. + MD_CONTEXT_RISCV64_REG_SP = 2,
  556. + MD_CONTEXT_RISCV64_REG_PC = 0
  557. +};
  558. +
  559. +#endif /* GOOGLE_BREAKPAD_COMMON_MINIDUMP_CPU_RISCV64_H__ */
  560. diff --git a/src/google_breakpad/common/minidump_format.h b/src/google_breakpad/common/minidump_format.h
  561. index e2366635..5ae68057 100644
  562. --- a/src/google_breakpad/common/minidump_format.h
  563. +++ b/src/google_breakpad/common/minidump_format.h
  564. @@ -118,6 +118,7 @@ typedef struct {
  565. #include "minidump_cpu_mips.h"
  566. #include "minidump_cpu_ppc.h"
  567. #include "minidump_cpu_ppc64.h"
  568. +#include "minidump_cpu_riscv64.h"
  569. #include "minidump_cpu_sparc.h"
  570. #include "minidump_cpu_x86.h"
  571. @@ -684,6 +685,7 @@ typedef enum {
  572. MD_CPU_ARCHITECTURE_PPC64 = 0x8002, /* Breakpad-defined value for PPC64 */
  573. MD_CPU_ARCHITECTURE_ARM64_OLD = 0x8003, /* Breakpad-defined value for ARM64 */
  574. MD_CPU_ARCHITECTURE_MIPS64 = 0x8004, /* Breakpad-defined value for MIPS64 */
  575. + MD_CPU_ARCHITECTURE_RISCV64 = 0x8005, /* Breakpad-defined value for RISCV64 */
  576. MD_CPU_ARCHITECTURE_UNKNOWN = 0xffff /* PROCESSOR_ARCHITECTURE_UNKNOWN */
  577. } MDCPUArchitecture;
  578. --
  579. 2.30.2