]> git.proxmox.com Git - mirror_qemu.git/blob - replay/replay-internal.c
replay: internal functions for replay log
[mirror_qemu.git] / replay / replay-internal.c
1 /*
2 * replay-internal.c
3 *
4 * Copyright (c) 2010-2015 Institute for System Programming
5 * of the Russian Academy of Sciences.
6 *
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.
9 *
10 */
11
12 #include "qemu-common.h"
13 #include "replay-internal.h"
14 #include "qemu/error-report.h"
15 #include "sysemu/sysemu.h"
16
17 unsigned int replay_data_kind = -1;
18 static unsigned int replay_has_unread_data;
19
20 /* File for replay writing */
21 FILE *replay_file;
22
23 void replay_put_byte(uint8_t byte)
24 {
25 if (replay_file) {
26 putc(byte, replay_file);
27 }
28 }
29
30 void replay_put_event(uint8_t event)
31 {
32 replay_put_byte(event);
33 }
34
35
36 void replay_put_word(uint16_t word)
37 {
38 replay_put_byte(word >> 8);
39 replay_put_byte(word);
40 }
41
42 void replay_put_dword(uint32_t dword)
43 {
44 replay_put_word(dword >> 16);
45 replay_put_word(dword);
46 }
47
48 void replay_put_qword(int64_t qword)
49 {
50 replay_put_dword(qword >> 32);
51 replay_put_dword(qword);
52 }
53
54 void replay_put_array(const uint8_t *buf, size_t size)
55 {
56 if (replay_file) {
57 replay_put_dword(size);
58 fwrite(buf, 1, size, replay_file);
59 }
60 }
61
62 uint8_t replay_get_byte(void)
63 {
64 uint8_t byte = 0;
65 if (replay_file) {
66 byte = getc(replay_file);
67 }
68 return byte;
69 }
70
71 uint16_t replay_get_word(void)
72 {
73 uint16_t word = 0;
74 if (replay_file) {
75 word = replay_get_byte();
76 word = (word << 8) + replay_get_byte();
77 }
78
79 return word;
80 }
81
82 uint32_t replay_get_dword(void)
83 {
84 uint32_t dword = 0;
85 if (replay_file) {
86 dword = replay_get_word();
87 dword = (dword << 16) + replay_get_word();
88 }
89
90 return dword;
91 }
92
93 int64_t replay_get_qword(void)
94 {
95 int64_t qword = 0;
96 if (replay_file) {
97 qword = replay_get_dword();
98 qword = (qword << 32) + replay_get_dword();
99 }
100
101 return qword;
102 }
103
104 void replay_get_array(uint8_t *buf, size_t *size)
105 {
106 if (replay_file) {
107 *size = replay_get_dword();
108 if (fread(buf, 1, *size, replay_file) != *size) {
109 error_report("replay read error");
110 }
111 }
112 }
113
114 void replay_get_array_alloc(uint8_t **buf, size_t *size)
115 {
116 if (replay_file) {
117 *size = replay_get_dword();
118 *buf = g_malloc(*size);
119 if (fread(*buf, 1, *size, replay_file) != *size) {
120 error_report("replay read error");
121 }
122 }
123 }
124
125 void replay_check_error(void)
126 {
127 if (replay_file) {
128 if (feof(replay_file)) {
129 error_report("replay file is over");
130 qemu_system_vmstop_request_prepare();
131 qemu_system_vmstop_request(RUN_STATE_PAUSED);
132 } else if (ferror(replay_file)) {
133 error_report("replay file is over or something goes wrong");
134 qemu_system_vmstop_request_prepare();
135 qemu_system_vmstop_request(RUN_STATE_INTERNAL_ERROR);
136 }
137 }
138 }
139
140 void replay_fetch_data_kind(void)
141 {
142 if (replay_file) {
143 if (!replay_has_unread_data) {
144 replay_data_kind = replay_get_byte();
145 replay_check_error();
146 replay_has_unread_data = 1;
147 }
148 }
149 }
150
151 void replay_finish_event(void)
152 {
153 replay_has_unread_data = 0;
154 replay_fetch_data_kind();
155 }