qemu

Форк
0
/
replay-char.c 
156 строк · 3.7 Кб
1
/*
2
 * replay-char.c
3
 *
4
 * Copyright (c) 2010-2016 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/osdep.h"
13
#include "qemu/error-report.h"
14
#include "sysemu/replay.h"
15
#include "replay-internal.h"
16
#include "chardev/char.h"
17

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;
22

23
/* Char event attributes. */
24
typedef struct CharEvent {
25
    int id;
26
    uint8_t *buf;
27
    size_t len;
28
} CharEvent;
29

30
static int find_char_driver(Chardev *chr)
31
{
32
    int i = 0;
33
    for ( ; i < drivers_count ; ++i) {
34
        if (char_drivers[i] == chr) {
35
            return i;
36
        }
37
    }
38
    return -1;
39
}
40

41
void replay_register_char_driver(Chardev *chr)
42
{
43
    if (replay_mode == REPLAY_MODE_NONE) {
44
        return;
45
    }
46
    char_drivers = g_realloc(char_drivers,
47
                             sizeof(*char_drivers) * (drivers_count + 1));
48
    char_drivers[drivers_count++] = chr;
49
}
50

51
void replay_chr_be_write(Chardev *s, const uint8_t *buf, int len)
52
{
53
    CharEvent *event = g_new0(CharEvent, 1);
54

55
    event->id = find_char_driver(s);
56
    if (event->id < 0) {
57
        fprintf(stderr, "Replay: cannot find char driver\n");
58
        exit(1);
59
    }
60
    event->buf = g_malloc(len);
61
    memcpy(event->buf, buf, len);
62
    event->len = len;
63

64
    replay_add_event(REPLAY_ASYNC_EVENT_CHAR_READ, event, NULL, 0);
65
}
66

67
void replay_event_char_read_run(void *opaque)
68
{
69
    CharEvent *event = (CharEvent *)opaque;
70

71
    qemu_chr_be_write_impl(char_drivers[event->id], event->buf,
72
                           (int)event->len);
73

74
    g_free(event->buf);
75
    g_free(event);
76
}
77

78
void replay_event_char_read_save(void *opaque)
79
{
80
    CharEvent *event = (CharEvent *)opaque;
81

82
    replay_put_byte(event->id);
83
    replay_put_array(event->buf, event->len);
84
}
85

86
void *replay_event_char_read_load(void)
87
{
88
    CharEvent *event = g_new0(CharEvent, 1);
89

90
    event->id = replay_get_byte();
91
    replay_get_array_alloc(&event->buf, &event->len);
92

93
    return event;
94
}
95

96
void replay_char_write_event_save(int res, int offset)
97
{
98
    g_assert(replay_mutex_locked());
99

100
    replay_save_instructions();
101
    replay_put_event(EVENT_CHAR_WRITE);
102
    replay_put_dword(res);
103
    replay_put_dword(offset);
104
}
105

106
void replay_char_write_event_load(int *res, int *offset)
107
{
108
    g_assert(replay_mutex_locked());
109

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();
115
    } else {
116
        replay_sync_error("Missing character write event in the replay log");
117
    }
118
}
119

120
int replay_char_read_all_load(uint8_t *buf)
121
{
122
    g_assert(replay_mutex_locked());
123

124
    if (replay_next_event_is(EVENT_CHAR_READ_ALL)) {
125
        size_t size;
126
        int res;
127
        replay_get_array(buf, &size);
128
        replay_finish_event();
129
        res = (int)size;
130
        assert(res >= 0);
131
        return res;
132
    } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR)) {
133
        int res = replay_get_dword();
134
        replay_finish_event();
135
        return res;
136
    } else {
137
        replay_sync_error("Missing character read all event in the replay log");
138
    }
139
}
140

141
void replay_char_read_all_save_error(int res)
142
{
143
    g_assert(replay_mutex_locked());
144
    assert(res < 0);
145
    replay_save_instructions();
146
    replay_put_event(EVENT_CHAR_READ_ALL_ERROR);
147
    replay_put_dword(res);
148
}
149

150
void replay_char_read_all_save_buf(uint8_t *buf, int offset)
151
{
152
    g_assert(replay_mutex_locked());
153
    replay_save_instructions();
154
    replay_put_event(EVENT_CHAR_READ_ALL);
155
    replay_put_array(buf, offset);
156
}
157

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.