1 : /*
2 : * Copyright 2010 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can
4 : * be found in the LICENSE file.
5 : */
6 :
7 : #include <stdio.h>
8 : #include <stdlib.h>
9 : #include <string.h>
10 :
11 : #include "native_client/src/trusted/gdb_rsp/abi.h"
12 :
13 : using gdb_rsp::Abi;
14 :
15 3 : int VerifyAbi(const char *name, uint32_t regs) {
16 3 : int errs = 0;
17 :
18 3 : const Abi *abi = Abi::Find(name);
19 3 : if (NULL != abi) {
20 3 : uint32_t regCnt = abi->GetRegisterCount();
21 3 : uint32_t byteCnt= abi->GetContextSize();
22 3 : uint32_t bytes = 0;
23 3 : uint32_t loop = 0;
24 :
25 3 : if (strcmp(abi->GetName(), name)) {
26 0 : printf("Incorrect name for ABI %s.\n", name);
27 0 : errs++;
28 : }
29 :
30 3 : if (regCnt != regs) {
31 0 : printf("Incorrect number of registers for ABI %s.\n", name);
32 0 : errs++;
33 : }
34 :
35 3 : if (abi->GetRegisterDef(regs) != NULL) {
36 0 : printf("Unexpected register for ABI %s.\n", name);
37 0 : errs++;
38 : }
39 :
40 59 : for (loop = 0; loop < regs; loop++) {
41 56 : const Abi::RegDef *def = abi->GetRegisterDef(loop);
42 56 : if (NULL == def) {
43 0 : printf("Missing register for ABI %s, reg %d.\n", name, loop);
44 0 : errs++;
45 0 : break;
46 : }
47 :
48 56 : if (NULL == def->name_) {
49 0 : printf("Missing register name for ABI %s, reg %d.\n", name, loop);
50 0 : errs++;
51 0 : break;
52 : }
53 :
54 56 : if (loop != def->index_) {
55 0 : printf("Index mismatch for ABI %s, reg %d.\n", name, loop);
56 0 : errs++;
57 0 : break;
58 : }
59 :
60 56 : if ((1 > def->bytes_) || (def->bytes_ > byteCnt)) {
61 0 : printf("Index mismatch for ABI %s, reg %d.\n", name, loop);
62 0 : errs++;
63 0 : break;
64 : }
65 :
66 56 : if ((def->type_ < Abi::GENERAL) || (def->type_ >= Abi::REG_TYPE_CNT)) {
67 0 : printf("Illegal register type ABI %s, reg %d.\n", name, loop);
68 0 : errs++;
69 0 : break;
70 : }
71 :
72 56 : if (def->offset_ != bytes) {
73 0 : printf("Offset mismatch in ABI %s, reg %d.\n", name, loop);
74 0 : errs++;
75 0 : break;
76 : }
77 :
78 56 : bytes += def->bytes_;
79 : }
80 :
81 3 : if (bytes != byteCnt) {
82 0 : printf("Context size mismatch for ABI %s.\n", name);
83 0 : errs++;
84 : }
85 :
86 3 : if (abi->GetRegisterType(Abi::GENERAL) == NULL) {
87 0 : printf("Missing general registers for ABI %s.\n", name);
88 0 : errs++;
89 : }
90 :
91 3 : if (abi->GetRegisterType(Abi::INST_PTR) == NULL) {
92 0 : printf("Missing instruction pointer for ABI %s.\n", name);
93 0 : errs++;
94 : }
95 : } else {
96 0 : printf("Could not find ABI %s.\n", name);
97 0 : errs++;
98 : }
99 3 : return errs;
100 : }
101 :
102 1 : int TestAbi() {
103 1 : int errs = 0;
104 :
105 : // TODO(cbiffle) Figure out how to REALLY detect ARM
106 1 : errs += VerifyAbi("iwmmxt", 16);
107 1 : errs += VerifyAbi("i386", 16);
108 1 : errs += VerifyAbi("i386:x86-64", 24);
109 :
110 : // Get the default ABI
111 1 : const Abi* abi = Abi::Get();
112 1 : if (NULL == abi) {
113 0 : printf("Failed to get default ABI.\n");
114 0 : errs++;
115 : }
116 :
117 : // Get a generic register
118 1 : const Abi::RegDef *def = abi->GetRegisterType(Abi::GENERAL);
119 1 : if (NULL == def) {
120 : printf("Failed to get a generic register on the default ABI %s.\n",
121 0 : abi->GetName());
122 0 : errs++;
123 : } else {
124 1 : if (def->bytes_ != sizeof(intptr_t)) {
125 : printf("Generic register %d != %d pointer size for %s\n",
126 : static_cast<int>(def->bytes_),
127 : static_cast<int>(sizeof(intptr_t)),
128 0 : abi->GetName());
129 0 : errs++;
130 : }
131 : }
132 :
133 1 : if (NULL != Abi::Find("non-existant")) {
134 0 : printf("Found 'non-existant' ABI.\n");
135 0 : errs++;
136 : }
137 :
138 1 : return errs;
139 : }
140 :
|