1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <inttypes.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 
9 #include <zircon/syscalls.h>
10 
11 #include "inspector/inspector.h"
12 #include "utils-impl.h"
13 
inspector_read_general_regs(zx_handle_t thread,zx_thread_state_general_regs_t * regs)14 zx_status_t inspector_read_general_regs(zx_handle_t thread, zx_thread_state_general_regs_t* regs) {
15     auto status = zx_thread_read_state(thread, ZX_THREAD_STATE_GENERAL_REGS, regs, sizeof(*regs));
16     if (status < 0) {
17         print_zx_error("unable to access general regs", status);
18         return status;
19     }
20     return ZX_OK;
21 }
22 
23 #if defined(__x86_64__)
24 
inspector_print_general_regs(FILE * f,const zx_thread_state_general_regs_t * regs,const inspector_excp_data_t * excp_data)25 void inspector_print_general_regs(FILE* f, const zx_thread_state_general_regs_t* regs,
26                                   const inspector_excp_data_t* excp_data) {
27     fprintf(f, " CS:  %#18llx RIP: %#18" PRIx64 " EFL: %#18" PRIx64,
28             0ull, regs->rip, regs->rflags);
29     if (excp_data) {
30         fprintf(f, " CR2: %#18" PRIx64, excp_data->cr2);
31     }
32     fprintf(f, "\n");
33     fprintf(f, " RAX: %#18" PRIx64 " RBX: %#18" PRIx64 " RCX: %#18" PRIx64 " RDX: %#18" PRIx64 "\n",
34             regs->rax, regs->rbx, regs->rcx, regs->rdx);
35     fprintf(f, " RSI: %#18" PRIx64 " RDI: %#18" PRIx64 " RBP: %#18" PRIx64 " RSP: %#18" PRIx64 "\n",
36             regs->rsi, regs->rdi, regs->rbp, regs->rsp);
37     fprintf(f, "  R8: %#18" PRIx64 "  R9: %#18" PRIx64 " R10: %#18" PRIx64 " R11: %#18" PRIx64 "\n",
38             regs->r8, regs->r9, regs->r10, regs->r11);
39     fprintf(f, " R12: %#18" PRIx64 " R13: %#18" PRIx64 " R14: %#18" PRIx64 " R15: %#18" PRIx64 "\n",
40             regs->r12, regs->r13, regs->r14, regs->r15);
41     if (excp_data) {
42         // errc value is 17 on purpose, errc is 4 characters
43         fprintf(f, " errc: %#17" PRIx64 "\n", excp_data->err_code);
44     }
45 }
46 
47 #elif defined(__aarch64__)
48 
inspector_print_general_regs(FILE * f,const zx_thread_state_general_regs_t * regs,const inspector_excp_data_t * excp_data)49 void inspector_print_general_regs(FILE* f, const zx_thread_state_general_regs_t* regs,
50                                   const inspector_excp_data_t* excp_data) {
51     fprintf(f, " x0  %#18" PRIx64 " x1  %#18" PRIx64 " x2  %#18" PRIx64 " x3  %#18" PRIx64 "\n",
52             regs->r[0], regs->r[1], regs->r[2], regs->r[3]);
53     fprintf(f, " x4  %#18" PRIx64 " x5  %#18" PRIx64 " x6  %#18" PRIx64 " x7  %#18" PRIx64 "\n",
54             regs->r[4], regs->r[5], regs->r[6], regs->r[7]);
55     fprintf(f, " x8  %#18" PRIx64 " x9  %#18" PRIx64 " x10 %#18" PRIx64 " x11 %#18" PRIx64 "\n",
56             regs->r[8], regs->r[9], regs->r[10], regs->r[11]);
57     fprintf(f, " x12 %#18" PRIx64 " x13 %#18" PRIx64 " x14 %#18" PRIx64 " x15 %#18" PRIx64 "\n",
58             regs->r[12], regs->r[13], regs->r[14], regs->r[15]);
59     fprintf(f, " x16 %#18" PRIx64 " x17 %#18" PRIx64 " x18 %#18" PRIx64 " x19 %#18" PRIx64 "\n",
60             regs->r[16], regs->r[17], regs->r[18], regs->r[19]);
61     fprintf(f, " x20 %#18" PRIx64 " x21 %#18" PRIx64 " x22 %#18" PRIx64 " x23 %#18" PRIx64 "\n",
62             regs->r[20], regs->r[21], regs->r[22], regs->r[23]);
63     fprintf(f, " x24 %#18" PRIx64 " x25 %#18" PRIx64 " x26 %#18" PRIx64 " x27 %#18" PRIx64 "\n",
64             regs->r[24], regs->r[25], regs->r[26], regs->r[27]);
65     fprintf(f, " x28 %#18" PRIx64 " x29 %#18" PRIx64 " lr  %#18" PRIx64 " sp  %#18" PRIx64 "\n",
66             regs->r[28], regs->r[29], regs->lr, regs->sp);
67     fprintf(f, " pc  %#18" PRIx64 " psr %#18" PRIx64 "\n",
68             regs->pc, regs->cpsr);
69 }
70 
71 #else   // unsupported arch
72 
inspector_print_general_regs(const zx_thread_state_general_regs_t * regs,const inspector_excp_data_t * excp_data)73 void inspector_print_general_regs(const zx_thread_state_general_regs_t* regs,
74                                   const inspector_excp_data_t* excp_data) {
75     printf("unsupported architecture\n");
76 }
77 
78 #endif
79