Raef Coles | b3d343b | 2020-12-08 09:31:43 +0000 | [diff] [blame] | 1 | # Copyright (c) 2021, Arm Limited. All rights reserved. |
| 2 | # |
| 3 | # SPDX-License-Identifier: BSD-3-Clause |
| 4 | |
| 5 | import subprocess |
| 6 | import os |
| 7 | import gdb |
| 8 | |
| 9 | backend_has_saveload = True |
| 10 | |
| 11 | qemu_mon_in_file = None |
| 12 | qemu_mon_out_file = None |
| 13 | |
| 14 | qemu_pid = None |
| 15 | |
| 16 | def backend_start_and_reset_and_connect(): |
| 17 | global qemu_mon_in_file |
| 18 | global qemu_mon_out_file |
| 19 | global qemu_pid |
| 20 | |
| 21 | print("(Re)Starting QEMU") |
| 22 | p = subprocess.run(os.path.dirname(os.path.realpath(__file__)) + "/../../fih_test_exec_qemu.sh") |
| 23 | p = subprocess.run(["pgrep", "qemu-system-arm"], capture_output=True) |
| 24 | qemu_pid = p.stdout.decode('utf-8').rstrip() |
| 25 | |
| 26 | try: |
| 27 | gdb.execute('detach') |
| 28 | except gdb.error: |
| 29 | # We were probably not attached in the first place - this was post-crash |
| 30 | # or first run. |
| 31 | pass |
| 32 | gdb.execute('target extended-remote localhost:1234') |
| 33 | |
| 34 | if qemu_mon_in_file is not None: |
| 35 | qemu_mon_in_file.close() |
| 36 | if qemu_mon_out_file is not None: |
| 37 | qemu_mon_out_file.close() |
| 38 | |
| 39 | qemu_mon_in_file = open("qemu_mon.in", 'w') |
| 40 | qemu_mon_out_file = open("qemu_mon.out", 'r') |
| 41 | |
| 42 | def backend_reset(): |
| 43 | gdb.execute('detach') |
| 44 | _kill_qemu() |
| 45 | backend_start_and_reset_and_connect() |
| 46 | print("Reset QEMU") |
| 47 | |
| 48 | ####################### Save / Loading ######################################### |
| 49 | |
| 50 | def backend_save_state(id): |
| 51 | print("Saving state: {} at PC {}".format(str(id), |
| 52 | hex(gdb.selected_frame().pc()))) |
| 53 | _write_fifo(qemu_mon_in_file, 'savevm {}'.format(str(id))) |
| 54 | |
| 55 | def backend_load_state(id): |
| 56 | _write_fifo(qemu_mon_in_file, 'loadvm {}'.format(str(id))) |
| 57 | # Disconnect and reconnect to reset gdb's internal state |
| 58 | gdb.execute('detach') |
| 59 | gdb.execute('target extended-remote localhost:1234') |
| 60 | print("Loaded state: " + str(id)) |
| 61 | |
| 62 | ######################## Internal ############################################## |
| 63 | |
| 64 | def _write_fifo(fifo, msg): |
| 65 | fifo.write(msg + '\n') |
| 66 | fifo.flush() |
| 67 | |
| 68 | def _kill_qemu(): |
| 69 | global qemu_pid |
| 70 | if qemu_pid is None: |
| 71 | return |
| 72 | p = subprocess.run(["kill", qemu_pid, "-9"]) |
| 73 | qemu_pid = None |