1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
/*******************************************************************************
* Copyright (c) 2010 Linaro Limited
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Peter Maydell (Linaro) - initial implementation
******************************************************************************/
#include <stdio.h>
#include <ucontext.h>
#include <string.h>
#include "risu.h"
#include "risu_reginfo_i386.h"
struct reginfo master_ri, apprentice_ri;
static int insn_is_ud2(uint32_t insn)
{
return ((insn & 0xffff) == 0x0b0f);
}
void advance_pc(void *vuc)
{
/* We assume that this is either UD1 or UD2.
* This would need tweaking if we want to test
* expected undefs on x86.
*/
ucontext_t *uc = vuc;
uc->uc_mcontext.gregs[REG_EIP] += 2;
}
int send_register_info(int sock, void *uc)
{
struct reginfo ri;
fill_reginfo(&ri, uc);
return send_data_pkt(sock, &ri, sizeof(ri));
}
/* Read register info from the socket and compare it with that from the
* ucontext. Return 0 for match, 1 for end-of-test, 2 for mismatch.
* NB: called from a signal handler.
*/
int recv_and_compare_register_info(int sock, void *uc)
{
int resp;
fill_reginfo(&master_ri, uc);
recv_data_pkt(sock, &apprentice_ri, sizeof(apprentice_ri));
if (memcmp(&master_ri, &apprentice_ri, sizeof(master_ri)) != 0) {
/* mismatch */
resp = 2;
} else if (insn_is_ud2(master_ri.faulting_insn)) {
/* end of test */
resp = 1;
} else {
/* either successful match or expected undef */
resp = 0;
}
send_response_byte(sock, resp);
return resp;
}
/* Print a useful report on the status of the last comparison
* done in recv_and_compare_register_info(). This is called on
* exit, so need not restrict itself to signal-safe functions.
* Should return 0 if it was a good match (ie end of test)
* and 1 for a mismatch.
*/
int report_match_status(void)
{
fprintf(stderr, "match status...\n");
fprintf(stderr, "master reginfo:\n");
dump_reginfo(&master_ri);
fprintf(stderr, "apprentice reginfo:\n");
dump_reginfo(&apprentice_ri);
if (memcmp(&master_ri, &apprentice_ri, sizeof(master_ri)) == 0) {
fprintf(stderr, "match!\n");
return 0;
}
fprintf(stderr, "mismatch!\n");
return 1;
}
|