master
h 118 lines 2.76 KB
Raw
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 #include "qemu/bswap.h"
16 #include "qemu/target-info.h"
17
18 #ifdef COMPILING_PER_TARGET
19 #include "cpu-param.h"
20 #endif
21
22 /*
23 * The GDB remote protocol transfers values in target byte order. As
24 * the gdbstub may be batching up several register values we always
25 * append to the array.
26 */
27
28 static inline int gdb_get_reg8(GByteArray *buf, uint8_t val)
29 {
30 g_byte_array_append(buf, &val, 1);
31 return 1;
32 }
33
34 static inline int gdb_get_reg16(GByteArray *buf, uint16_t val)
35 {
36 if (target_big_endian()) {
37 cpu_to_be16s(&val);
38 } else {
39 cpu_to_le16s(&val);
40 }
41 g_byte_array_append(buf, (uint8_t *) &val, 2);
42 return 2;
43 }
44
45 static inline int gdb_get_reg32(GByteArray *buf, uint32_t val)
46 {
47 if (target_big_endian()) {
48 cpu_to_be32s(&val);
49 } else {
50 cpu_to_le32s(&val);
51 }
52 g_byte_array_append(buf, (uint8_t *) &val, 4);
53 return 4;
54 }
55
56 static inline int gdb_get_reg64(GByteArray *buf, uint64_t val)
57 {
58 if (target_big_endian()) {
59 cpu_to_be64s(&val);
60 } else {
61 cpu_to_le64s(&val);
62 }
63 g_byte_array_append(buf, (uint8_t *) &val, 8);
64 return 8;
65 }
66
67 static inline int gdb_get_reg128(GByteArray *buf, uint64_t val_hi,
68 uint64_t val_lo)
69 {
70 uint64_t tmp[2];
71 if (target_big_endian()) {
72 tmp[0] = cpu_to_be64(val_hi);
73 tmp[1] = cpu_to_be64(val_lo);
74 } else {
75 tmp[0] = cpu_to_le64(val_lo);
76 tmp[1] = cpu_to_le64(val_hi);
77 }
78 g_byte_array_append(buf, (uint8_t *)&tmp, 16);
79 return 16;
80 }
81
82 static inline int gdb_get_zeroes(GByteArray *array, size_t len)
83 {
84 guint oldlen = array->len;
85 g_byte_array_set_size(array, oldlen + len);
86 memset(array->data + oldlen, 0, len);
87
88 return len;
89 }
90
91 /**
92 * gdb_get_regl: append @val in @buf using 32 or 64-bit, depending on target
93 *
94 * This function is legacy and deprecated, thus should not be used in new code.
95 */
96 static inline int gdb_get_regl(GByteArray *buf, uint64_t val)
97 {
98 if (target_long_bits() == 64) {
99 return gdb_get_reg64(buf, val);
100 } else {
101 return gdb_get_reg32(buf, val);
102 }
103 }
104
105 /**
106 * gdb_get_reg_ptr: get pointer to start of last element
107 * @len: length of element
108 *
109 * This is a helper function to extract the pointer to the last
110 * element for additional processing. Some front-ends do additional
111 * dynamic swapping of the elements based on CPU state.
112 */
113 static inline uint8_t *gdb_get_reg_ptr(GByteArray *buf, int len)
114 {
115 return buf->data + buf->len - len;
116 }
117
118 #endif /* _GDBSTUB_HELPERS_H_ */