diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-03-18 20:25:23 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-03-18 20:25:23 +0000 |
commit | 9214813489eb29de71d37f57e1bcabf5facecc8f (patch) | |
tree | 4a7317768744cda3fa35cd08a6615bfdce13ee79 /include | |
parent | cf4b64406c0e7542b4e1852f5e5a743ad63cf36e (diff) | |
parent | 3bc2609d478779be600fd66744eb4e3730ec5e33 (diff) |
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-and-gdbstub-170320-1' into staging
Testing and gdbstub updates:
- docker updates for VirGL
- re-factor gdbstub for static GDBState
- re-factor gdbstub for dynamic arrays
- add SVE support to arm gdbstub
- add some guest debug tests to check-tcg
- add aarch64 userspace register tests
- remove packet size limit to gdbstub
- simplify gdbstub monitor code
- report vContSupported in gdbstub to use proper single-step
# gpg: Signature made Tue 17 Mar 2020 17:47:46 GMT
# gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full]
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44
* remotes/stsquad/tags/pull-testing-and-gdbstub-170320-1: (28 commits)
gdbstub: Fix single-step issue by confirming 'vContSupported+' feature to gdb
gdbstub: do not split gdb_monitor_write payload
gdbstub: change GDBState.last_packet to GByteArray
tests/tcg/aarch64: add test-sve-ioctl guest-debug test
tests/tcg/aarch64: add SVE iotcl test
tests/tcg/aarch64: add a gdbstub testcase for SVE registers
tests/guest-debug: add a simple test runner
configure: allow user to specify what gdb to use
tests/tcg/aarch64: userspace system register test
target/arm: don't bother with id_aa64pfr0_read for USER_ONLY
target/arm: generate xml description of our SVE registers
target/arm: default SVE length to 64 bytes for linux-user
target/arm: explicitly encode regnum in our XML
target/arm: prepare for multiple dynamic XMLs
gdbstub: extend GByteArray to read register helpers
target/i386: use gdb_get_reg helpers
target/m68k: use gdb_get_reg helpers
target/arm: use gdb_get_reg helpers
gdbstub: add helper for 128 bit registers
gdbstub: move mem_buf to GDBState and use GByteArray
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/exec/gdbstub.h | 62 | ||||
-rw-r--r-- | include/hw/core/cpu.h | 2 |
2 files changed, 50 insertions, 14 deletions
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index 08363969c1..30b909ebd2 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -68,40 +68,76 @@ void gdb_signalled(CPUArchState *, int); void gdbserver_fork(CPUState *); #endif /* Get or set a register. Returns the size of the register. */ -typedef int (*gdb_reg_cb)(CPUArchState *env, uint8_t *buf, int reg); +typedef int (*gdb_get_reg_cb)(CPUArchState *env, GByteArray *buf, int reg); +typedef int (*gdb_set_reg_cb)(CPUArchState *env, uint8_t *buf, int reg); void gdb_register_coprocessor(CPUState *cpu, - gdb_reg_cb get_reg, gdb_reg_cb set_reg, + gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg, int num_regs, const char *xml, int g_pos); -/* The GDB remote protocol transfers values in target byte order. This means - * we can use the raw memory access routines to access the value buffer. - * Conveniently, these also handle the case where the buffer is mis-aligned. +/* + * The GDB remote protocol transfers values in target byte order. As + * the gdbstub may be batching up several register values we always + * append to the array. */ -static inline int gdb_get_reg8(uint8_t *mem_buf, uint8_t val) +static inline int gdb_get_reg8(GByteArray *buf, uint8_t val) { - stb_p(mem_buf, val); + g_byte_array_append(buf, &val, 1); return 1; } -static inline int gdb_get_reg16(uint8_t *mem_buf, uint16_t val) +static inline int gdb_get_reg16(GByteArray *buf, uint16_t val) { - stw_p(mem_buf, val); + uint16_t to_word = tswap16(val); + g_byte_array_append(buf, (uint8_t *) &to_word, 2); return 2; } -static inline int gdb_get_reg32(uint8_t *mem_buf, uint32_t val) +static inline int gdb_get_reg32(GByteArray *buf, uint32_t val) { - stl_p(mem_buf, val); + uint32_t to_long = tswap32(val); + g_byte_array_append(buf, (uint8_t *) &to_long, 4); return 4; } -static inline int gdb_get_reg64(uint8_t *mem_buf, uint64_t val) +static inline int gdb_get_reg64(GByteArray *buf, uint64_t val) { - stq_p(mem_buf, val); + uint64_t to_quad = tswap64(val); + g_byte_array_append(buf, (uint8_t *) &to_quad, 8); return 8; } +static inline int gdb_get_reg128(GByteArray *buf, uint64_t val_hi, + uint64_t val_lo) +{ + uint64_t to_quad; +#ifdef TARGET_WORDS_BIGENDIAN + to_quad = tswap64(val_hi); + g_byte_array_append(buf, (uint8_t *) &to_quad, 8); + to_quad = tswap64(val_lo); + g_byte_array_append(buf, (uint8_t *) &to_quad, 8); +#else + to_quad = tswap64(val_lo); + g_byte_array_append(buf, (uint8_t *) &to_quad, 8); + to_quad = tswap64(val_hi); + g_byte_array_append(buf, (uint8_t *) &to_quad, 8); +#endif + return 16; +} + +/** + * gdb_get_reg_ptr: get pointer to start of last element + * @len: length of element + * + * This is a helper function to extract the pointer to the last + * element for additional processing. Some front-ends do additional + * dynamic swapping of the elements based on CPU state. + */ +static inline uint8_t * gdb_get_reg_ptr(GByteArray *buf, int len) +{ + return buf->data + buf->len - len; +} + #if TARGET_LONG_BITS == 64 #define gdb_get_regl(buf, val) gdb_get_reg64(buf, val) #define ldtul_p(addr) ldq_p(addr) diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 73e9a869a4..e1d6ee00b4 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -195,7 +195,7 @@ typedef struct CPUClass { hwaddr (*get_phys_page_attrs_debug)(CPUState *cpu, vaddr addr, MemTxAttrs *attrs); int (*asidx_from_attrs)(CPUState *cpu, MemTxAttrs attrs); - int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg); + int (*gdb_read_register)(CPUState *cpu, GByteArray *buf, int reg); int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg); bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp); void (*debug_excp_handler)(CPUState *cpu); |