xref: /openbmc/qemu/include/gdbstub/helpers.h (revision 94326e4f217991102770667f684156bdbef599e6)
1 /*
2  * gdbstub helpers
3  *
4  * These are all used by the various frontends and have to be host
5  * aware to ensure things are store in target order.
6  *
7  * Copyright (c) 2022 Linaro Ltd
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 #ifndef _GDBSTUB_HELPERS_H_
13 #define _GDBSTUB_HELPERS_H_
14 
15 #ifndef COMPILING_PER_TARGET
16 #error "gdbstub helpers should only be included by target specific code"
17 #endif
18 
19 #include "cpu.h"
20 
21 /*
22  * The GDB remote protocol transfers values in target byte order. As
23  * the gdbstub may be batching up several register values we always
24  * append to the array.
25  */
26 
27 static inline int gdb_get_reg8(GByteArray *buf, uint8_t val)
28 {
29     g_byte_array_append(buf, &val, 1);
30     return 1;
31 }
32 
33 static inline int gdb_get_reg16(GByteArray *buf, uint16_t val)
34 {
35     uint16_t to_word = tswap16(val);
36     g_byte_array_append(buf, (uint8_t *) &to_word, 2);
37     return 2;
38 }
39 
40 static inline int gdb_get_reg32(GByteArray *buf, uint32_t val)
41 {
42     uint32_t to_long = tswap32(val);
43     g_byte_array_append(buf, (uint8_t *) &to_long, 4);
44     return 4;
45 }
46 
47 static inline int gdb_get_reg64(GByteArray *buf, uint64_t val)
48 {
49     uint64_t to_quad = tswap64(val);
50     g_byte_array_append(buf, (uint8_t *) &to_quad, 8);
51     return 8;
52 }
53 
54 static inline int gdb_get_reg128(GByteArray *buf, uint64_t val_hi,
55                                  uint64_t val_lo)
56 {
57     uint64_t to_quad;
58 #if TARGET_BIG_ENDIAN
59     to_quad = tswap64(val_hi);
60     g_byte_array_append(buf, (uint8_t *) &to_quad, 8);
61     to_quad = tswap64(val_lo);
62     g_byte_array_append(buf, (uint8_t *) &to_quad, 8);
63 #else
64     to_quad = tswap64(val_lo);
65     g_byte_array_append(buf, (uint8_t *) &to_quad, 8);
66     to_quad = tswap64(val_hi);
67     g_byte_array_append(buf, (uint8_t *) &to_quad, 8);
68 #endif
69     return 16;
70 }
71 
72 static inline int gdb_get_zeroes(GByteArray *array, size_t len)
73 {
74     guint oldlen = array->len;
75     g_byte_array_set_size(array, oldlen + len);
76     memset(array->data + oldlen, 0, len);
77 
78     return len;
79 }
80 
81 /**
82  * gdb_get_reg_ptr: get pointer to start of last element
83  * @len: length of element
84  *
85  * This is a helper function to extract the pointer to the last
86  * element for additional processing. Some front-ends do additional
87  * dynamic swapping of the elements based on CPU state.
88  */
89 static inline uint8_t *gdb_get_reg_ptr(GByteArray *buf, int len)
90 {
91     return buf->data + buf->len - len;
92 }
93 
94 #if TARGET_LONG_BITS == 64
95 #define gdb_get_regl(buf, val) gdb_get_reg64(buf, val)
96 #define ldtul_p(addr) ldq_p(addr)
97 #else
98 #define gdb_get_regl(buf, val) gdb_get_reg32(buf, val)
99 #define ldtul_p(addr) ldl_p(addr)
100 #endif
101 
102 #endif /* _GDBSTUB_HELPERS_H_ */
103