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