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 "exec/tswap.h" 20 #include "cpu-param.h" 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 uint16_t to_word = tswap16(val); 37 g_byte_array_append(buf, (uint8_t *) &to_word, 2); 38 return 2; 39 } 40 41 static inline int gdb_get_reg32(GByteArray *buf, uint32_t val) 42 { 43 uint32_t to_long = tswap32(val); 44 g_byte_array_append(buf, (uint8_t *) &to_long, 4); 45 return 4; 46 } 47 48 static inline int gdb_get_reg64(GByteArray *buf, uint64_t val) 49 { 50 uint64_t to_quad = tswap64(val); 51 g_byte_array_append(buf, (uint8_t *) &to_quad, 8); 52 return 8; 53 } 54 55 static inline int gdb_get_reg128(GByteArray *buf, uint64_t val_hi, 56 uint64_t val_lo) 57 { 58 uint64_t to_quad; 59 #if TARGET_BIG_ENDIAN 60 to_quad = tswap64(val_hi); 61 g_byte_array_append(buf, (uint8_t *) &to_quad, 8); 62 to_quad = tswap64(val_lo); 63 g_byte_array_append(buf, (uint8_t *) &to_quad, 8); 64 #else 65 to_quad = tswap64(val_lo); 66 g_byte_array_append(buf, (uint8_t *) &to_quad, 8); 67 to_quad = tswap64(val_hi); 68 g_byte_array_append(buf, (uint8_t *) &to_quad, 8); 69 #endif 70 return 16; 71 } 72 73 static inline int gdb_get_zeroes(GByteArray *array, size_t len) 74 { 75 guint oldlen = array->len; 76 g_byte_array_set_size(array, oldlen + len); 77 memset(array->data + oldlen, 0, len); 78 79 return len; 80 } 81 82 /** 83 * gdb_get_reg_ptr: get pointer to start of last element 84 * @len: length of element 85 * 86 * This is a helper function to extract the pointer to the last 87 * element for additional processing. Some front-ends do additional 88 * dynamic swapping of the elements based on CPU state. 89 */ 90 static inline uint8_t *gdb_get_reg_ptr(GByteArray *buf, int len) 91 { 92 return buf->data + buf->len - len; 93 } 94 95 #if TARGET_LONG_BITS == 64 96 #define gdb_get_regl(buf, val) gdb_get_reg64(buf, val) 97 #define ldtul_p(addr) ldq_p(addr) 98 #define ldtul_le_p(addr) ldq_le_p(addr) 99 #define ldtul_be_p(addr) ldq_be_p(addr) 100 #else 101 #define gdb_get_regl(buf, val) gdb_get_reg32(buf, val) 102 #define ldtul_p(addr) ldl_p(addr) 103 #define ldtul_le_p(addr) ldl_le_p(addr) 104 #define ldtul_be_p(addr) ldl_be_p(addr) 105 #endif 106 107 #endif /* _GDBSTUB_HELPERS_H_ */ 108