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_arch_block { 14 uint32_t vector; 15 uint32_t code; 16 17 struct { 18 uint32_t eax; 19 uint32_t ecx; 20 uint32_t edx; 21 uint32_t ebx; 22 uint32_t esp; 23 uint32_t ebp; 24 uint32_t esi; 25 uint32_t edi; 26 uint32_t eip; 27 uint32_t eflags; 28 uint32_t cs; 29 } r; 30 } __packed; 31 32 /* 33 * This might be too large for stack space if defined 34 * inside function. So do it here. 35 */ 36 static struct x86_arch_block arch_blk; 37 arch_coredump_info_dump(const struct arch_esf * esf)38void arch_coredump_info_dump(const struct arch_esf *esf) 39 { 40 struct coredump_arch_hdr_t hdr = { 41 .id = COREDUMP_ARCH_HDR_ID, 42 .hdr_version = ARCH_HDR_VER, 43 .num_bytes = sizeof(arch_blk), 44 }; 45 46 /* Nothing to process */ 47 if (esf == NULL) { 48 return; 49 } 50 51 (void)memset(&arch_blk, 0, sizeof(arch_blk)); 52 53 arch_blk.vector = z_x86_exception_vector; 54 arch_blk.code = esf->errorCode; 55 56 /* 57 * 16 registers expected by GDB. 58 * Not all are in ESF but the GDB stub 59 * will need to send all 16 as one packet. 60 * The stub will need to send undefined 61 * for registers not presented in coredump. 62 */ 63 arch_blk.r.eax = esf->eax; 64 arch_blk.r.ebx = esf->ebx; 65 arch_blk.r.ecx = esf->ecx; 66 arch_blk.r.edx = esf->edx; 67 arch_blk.r.esp = esf->esp; 68 arch_blk.r.ebp = esf->ebp; 69 arch_blk.r.esi = esf->esi; 70 arch_blk.r.edi = esf->edi; 71 arch_blk.r.eip = esf->eip; 72 arch_blk.r.eflags = esf->eflags; 73 arch_blk.r.cs = esf->cs & 0xFFFFU; 74 75 /* Send for output */ 76 coredump_buffer_output((uint8_t *)&hdr, sizeof(hdr)); 77 coredump_buffer_output((uint8_t *)&arch_blk, sizeof(arch_blk)); 78 } 79 arch_coredump_tgt_code_get(void)80uint16_t arch_coredump_tgt_code_get(void) 81 { 82 return COREDUMP_TGT_X86; 83 } 84 85 #if defined(CONFIG_DEBUG_COREDUMP_DUMP_THREAD_PRIV_STACK) arch_coredump_priv_stack_dump(struct k_thread * thread)86void arch_coredump_priv_stack_dump(struct k_thread *thread) 87 { 88 struct z_x86_thread_stack_header *hdr_stack_obj; 89 uintptr_t start_addr, end_addr; 90 91 #if defined(CONFIG_THREAD_STACK_MEM_MAPPED) 92 hdr_stack_obj = (struct z_x86_thread_stack_header *)thread->stack_info.mapped.addr; 93 #else 94 hdr_stack_obj = (struct z_x86_thread_stack_header *)thread->stack_obj; 95 #endif /* CONFIG_THREAD_STACK_MEM_MAPPED) */ 96 97 start_addr = (uintptr_t)&hdr_stack_obj->privilege_stack[0]; 98 end_addr = start_addr + sizeof(hdr_stack_obj->privilege_stack); 99 100 coredump_memory_dump(start_addr, end_addr); 101 } 102 #endif /* CONFIG_DEBUG_COREDUMP_DUMP_THREAD_PRIV_STACK */ 103