4 * Copyright (c) 2010-2016 Institute for System Programming
5 * of the Russian Academy of Sciences.
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
12 #include "qemu/osdep.h"
13 #include "qemu/error-report.h"
14 #include "sysemu/replay.h"
15 #include "replay-internal.h"
16 #include "chardev/char.h"
18 /* Char drivers that generate qemu_chr_be_write events
19 that should be saved into the log. */
20 static Chardev
**char_drivers
;
21 static int drivers_count
;
23 /* Char event attributes. */
24 typedef struct CharEvent
{
30 static int find_char_driver(Chardev
*chr
)
33 for ( ; i
< drivers_count
; ++i
) {
34 if (char_drivers
[i
] == chr
) {
41 void replay_register_char_driver(Chardev
*chr
)
43 if (replay_mode
== REPLAY_MODE_NONE
) {
46 char_drivers
= g_realloc(char_drivers
,
47 sizeof(*char_drivers
) * (drivers_count
+ 1));
48 char_drivers
[drivers_count
++] = chr
;
51 void replay_chr_be_write(Chardev
*s
, const uint8_t *buf
, int len
)
53 CharEvent
*event
= g_new0(CharEvent
, 1);
55 event
->id
= find_char_driver(s
);
57 fprintf(stderr
, "Replay: cannot find char driver\n");
60 event
->buf
= g_malloc(len
);
61 memcpy(event
->buf
, buf
, len
);
64 replay_add_event(REPLAY_ASYNC_EVENT_CHAR_READ
, event
, NULL
, 0);
67 void replay_event_char_read_run(void *opaque
)
69 CharEvent
*event
= (CharEvent
*)opaque
;
71 qemu_chr_be_write_impl(char_drivers
[event
->id
], event
->buf
,
78 void replay_event_char_read_save(void *opaque
)
80 CharEvent
*event
= (CharEvent
*)opaque
;
82 replay_put_byte(event
->id
);
83 replay_put_array(event
->buf
, event
->len
);
86 void *replay_event_char_read_load(void)
88 CharEvent
*event
= g_new0(CharEvent
, 1);
90 event
->id
= replay_get_byte();
91 replay_get_array_alloc(&event
->buf
, &event
->len
);
96 void replay_char_write_event_save(int res
, int offset
)
98 g_assert(replay_mutex_locked());
100 replay_save_instructions();
101 replay_put_event(EVENT_CHAR_WRITE
);
102 replay_put_dword(res
);
103 replay_put_dword(offset
);
106 void replay_char_write_event_load(int *res
, int *offset
)
108 g_assert(replay_mutex_locked());
110 replay_account_executed_instructions();
111 if (replay_next_event_is(EVENT_CHAR_WRITE
)) {
112 *res
= replay_get_dword();
113 *offset
= replay_get_dword();
114 replay_finish_event();
116 replay_sync_error("Missing character write event in the replay log");
120 int replay_char_read_all_load(uint8_t *buf
)
122 g_assert(replay_mutex_locked());
124 if (replay_next_event_is(EVENT_CHAR_READ_ALL
)) {
127 replay_get_array(buf
, &size
);
128 replay_finish_event();
132 } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR
)) {
133 int res
= replay_get_dword();
134 replay_finish_event();
137 replay_sync_error("Missing character read all event in the replay log");
141 void replay_char_read_all_save_error(int res
)
143 g_assert(replay_mutex_locked());
145 replay_save_instructions();
146 replay_put_event(EVENT_CHAR_READ_ALL_ERROR
);
147 replay_put_dword(res
);
150 void replay_char_read_all_save_buf(uint8_t *buf
, int offset
)
152 g_assert(replay_mutex_locked());
153 replay_save_instructions();
154 replay_put_event(EVENT_CHAR_READ_ALL
);
155 replay_put_array(buf
, offset
);