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