1 /* 2 * Copyright (c) 2020 Intel Corporation. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include <string.h> 8 #include <zephyr/kernel.h> 9 #include <zephyr/debug/coredump.h> 10 11 #define ARCH_HDR_VER 1 12 13 struct x86_64_arch_block { 14 uint64_t vector; 15 uint64_t code; 16 17 struct { 18 uint64_t rax; 19 uint64_t rcx; 20 uint64_t rdx; 21 uint64_t rsi; 22 uint64_t rdi; 23 uint64_t rsp; 24 uint64_t r8; 25 uint64_t r9; 26 uint64_t r10; 27 uint64_t r11; 28 uint64_t rip; 29 uint64_t eflags; 30 uint64_t cs; 31 uint64_t ss; 32 uint64_t rbp; 33 34 #ifdef CONFIG_EXCEPTION_DEBUG 35 uint64_t rbx; 36 uint64_t r12; 37 uint64_t r13; 38 uint64_t r14; 39 uint64_t r15; 40 #endif 41 } r; 42 } __packed; 43 44 /* 45 * Register block takes up too much stack space 46 * if defined within function. So define it here. 47 */ 48 static struct x86_64_arch_block arch_blk; 49 arch_coredump_info_dump(const struct arch_esf * esf)50void arch_coredump_info_dump(const struct arch_esf *esf) 51 { 52 struct coredump_arch_hdr_t hdr = { 53 .id = COREDUMP_ARCH_HDR_ID, 54 .hdr_version = ARCH_HDR_VER, 55 .num_bytes = sizeof(arch_blk), 56 }; 57 58 /* Nothing to process */ 59 if (esf == NULL) { 60 return; 61 } 62 63 (void)memset(&arch_blk, 0, sizeof(arch_blk)); 64 65 arch_blk.vector = esf->vector; 66 arch_blk.code = esf->code; 67 68 /* 69 * 34 registers expected by GDB. 70 * Not all are in ESF but the GDB stub 71 * will need to send all 34 as one packet. 72 * The stub will need to send undefined 73 * for registers not presented in coredump. 74 */ 75 arch_blk.r.rax = esf->rax; 76 arch_blk.r.rcx = esf->rcx; 77 arch_blk.r.rdx = esf->rdx; 78 arch_blk.r.rsi = esf->rsi; 79 arch_blk.r.rdi = esf->rdi; 80 arch_blk.r.rsp = esf->rsp; 81 arch_blk.r.rip = esf->rip; 82 arch_blk.r.r8 = esf->r8; 83 arch_blk.r.r9 = esf->r9; 84 arch_blk.r.r10 = esf->r10; 85 arch_blk.r.r11 = esf->r11; 86 87 arch_blk.r.eflags = esf->rflags; 88 arch_blk.r.cs = esf->cs & 0xFFFFU; 89 arch_blk.r.ss = esf->ss; 90 91 arch_blk.r.rbp = esf->rbp; 92 93 #ifdef CONFIG_EXCEPTION_DEBUG 94 arch_blk.r.rbx = esf->rbx; 95 arch_blk.r.r12 = esf->r12; 96 arch_blk.r.r13 = esf->r13; 97 arch_blk.r.r14 = esf->r14; 98 arch_blk.r.r15 = esf->r15; 99 #endif 100 101 /* Send for output */ 102 coredump_buffer_output((uint8_t *)&hdr, sizeof(hdr)); 103 coredump_buffer_output((uint8_t *)&arch_blk, sizeof(arch_blk)); 104 } 105 arch_coredump_tgt_code_get(void)106uint16_t arch_coredump_tgt_code_get(void) 107 { 108 return COREDUMP_TGT_X86_64; 109 } 110 111 #if defined(CONFIG_DEBUG_COREDUMP_DUMP_THREAD_PRIV_STACK) arch_coredump_priv_stack_dump(struct k_thread * thread)112void arch_coredump_priv_stack_dump(struct k_thread *thread) 113 { 114 struct z_x86_thread_stack_header *hdr_stack_obj; 115 uintptr_t start_addr, end_addr; 116 117 #if defined(CONFIG_THREAD_STACK_MEM_MAPPED) 118 hdr_stack_obj = (struct z_x86_thread_stack_header *)thread->stack_info.mapped.addr; 119 #else 120 hdr_stack_obj = (struct z_x86_thread_stack_header *)thread->stack_obj; 121 #endif /* CONFIG_THREAD_STACK_MEM_MAPPED) */ 122 123 start_addr = (uintptr_t)&hdr_stack_obj->privilege_stack[0]; 124 end_addr = start_addr + sizeof(hdr_stack_obj->privilege_stack); 125 126 coredump_memory_dump(start_addr, end_addr); 127 } 128 #endif /* CONFIG_DEBUG_COREDUMP_DUMP_THREAD_PRIV_STACK */ 129