blob: 7ca579d4388ee06f216b96bd0424835c4a666688 [file] [log] [blame]
sewardjc97096c2004-06-30 09:28:04 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
4/*--- This file (test_main.c) is ---*/
5/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
6/*--- ---*/
7/*---------------------------------------------------------------*/
8
9#include <stdio.h>
10#include <stdlib.h>
sewardjced9fe52004-07-07 11:55:36 +000011#include <assert.h>
sewardj9b1004e2004-10-30 22:25:40 +000012#include <string.h>
sewardjc97096c2004-06-30 09:28:04 +000013
sewardjced9fe52004-07-07 11:55:36 +000014#include "libvex_basictypes.h"
15#include "libvex.h"
sewardjc97096c2004-06-30 09:28:04 +000016
sewardjabe017e2004-10-29 23:42:36 +000017#include "test_main.h"
18
19
sewardjc97096c2004-06-30 09:28:04 +000020/*---------------------------------------------------------------*/
21/*--- Test ---*/
22/*---------------------------------------------------------------*/
23
sewardjce605f92004-07-05 14:39:15 +000024
sewardj2b515872004-07-05 20:50:45 +000025__attribute__ ((noreturn))
sewardj41f43bc2004-07-08 14:23:22 +000026static
sewardjce605f92004-07-05 14:39:15 +000027void failure_exit ( void )
28{
29 fprintf(stdout, "VEX did failure_exit. Bye.\n");
30 exit(1);
31}
32
sewardj41f43bc2004-07-08 14:23:22 +000033static
sewardjce605f92004-07-05 14:39:15 +000034void log_bytes ( Char* bytes, Int nbytes )
35{
36 fwrite ( bytes, 1, nbytes, stdout );
37}
38
sewardjced9fe52004-07-07 11:55:36 +000039#define N_LINEBUF 10000
sewardj41f43bc2004-07-08 14:23:22 +000040static Char linebuf[N_LINEBUF];
sewardjced9fe52004-07-07 11:55:36 +000041
sewardjf05537e2004-10-14 01:08:12 +000042#define N_ORIGBUF 1000
sewardj4459baa2004-09-10 20:00:46 +000043#define N_TRANSBUF 5000
sewardjced9fe52004-07-07 11:55:36 +000044
sewardj4459baa2004-09-10 20:00:46 +000045static UChar origbuf[N_ORIGBUF];
46static UChar transbuf[N_TRANSBUF];
sewardjced9fe52004-07-07 11:55:36 +000047
sewardj1f40a0a2004-07-21 12:28:07 +000048static Bool verbose = True;
sewardjced9fe52004-07-07 11:55:36 +000049
sewardj9b1004e2004-10-30 22:25:40 +000050/* Forwards */
sewardjeeac8412004-11-02 00:26:55 +000051static IRBB* ac_instrument ( IRBB*, VexGuestLayout* );
sewardj9b1004e2004-10-30 22:25:40 +000052
53
sewardjced9fe52004-07-07 11:55:36 +000054int main ( int argc, char** argv )
sewardjce605f92004-07-05 14:39:15 +000055{
sewardjced9fe52004-07-07 11:55:36 +000056 FILE* f;
57 Int i;
sewardj4459baa2004-09-10 20:00:46 +000058 UInt u, sum;
sewardjced9fe52004-07-07 11:55:36 +000059 Addr32 orig_addr;
sewardjabe017e2004-10-29 23:42:36 +000060 Int bb_number, n_bbs_done = 0;
sewardjced9fe52004-07-07 11:55:36 +000061 Int orig_nbytes, trans_used, orig_used;
62 TranslateResult tres;
sewardjb5bf2e02004-10-25 13:06:17 +000063 VexControl vcon;
sewardjced9fe52004-07-07 11:55:36 +000064
65 if (argc != 2) {
66 fprintf(stderr, "usage: vex file.org\n");
67 exit(1);
68 }
69 f = fopen(argv[1], "r");
70 if (!f) {
71 fprintf(stderr, "can't open `%s'\n", argv[1]);
72 exit(1);
73 }
74
sewardjb5bf2e02004-10-25 13:06:17 +000075 /* Run with default params. However, we can't allow bb chasing
76 since that causes the front end to get segfaults when it tries
77 to read code outside the initial BB we hand it. */
78 LibVEX_default_VexControl ( &vcon );
79 vcon.guest_chase_thresh = 0;
sewardjb4952402004-10-26 13:24:50 +000080 vcon.iropt_level = 2;
sewardjb5bf2e02004-10-25 13:06:17 +000081
sewardjced9fe52004-07-07 11:55:36 +000082 LibVEX_Init ( &failure_exit, &log_bytes,
sewardj1f40a0a2004-07-21 12:28:07 +000083 1, /* debug_paranoia */
sewardjabe017e2004-10-29 23:42:36 +000084 TEST_VSUPPORT, /* valgrind support */
sewardjb5bf2e02004-10-25 13:06:17 +000085 &vcon );
sewardjced9fe52004-07-07 11:55:36 +000086
sewardjea64e142004-07-22 16:47:21 +000087
sewardjced9fe52004-07-07 11:55:36 +000088 while (!feof(f)) {
sewardjabe017e2004-10-29 23:42:36 +000089
sewardjced9fe52004-07-07 11:55:36 +000090 fgets(linebuf, N_LINEBUF,f);
sewardjabe017e2004-10-29 23:42:36 +000091 if (linebuf[0] == 0) continue;
sewardjced9fe52004-07-07 11:55:36 +000092 if (linebuf[0] != '.') continue;
sewardjabe017e2004-10-29 23:42:36 +000093
94 if (n_bbs_done == TEST_N_BBS) break;
95 n_bbs_done++;
96
sewardjced9fe52004-07-07 11:55:36 +000097 /* first line is: . bb-number bb-addr n-bytes */
98 assert(3 == sscanf(&linebuf[1], " %d %x %d\n",
99 & bb_number,
sewardjabe017e2004-10-29 23:42:36 +0000100 & orig_addr, & orig_nbytes ));
sewardjced9fe52004-07-07 11:55:36 +0000101 assert(orig_nbytes >= 1);
102 assert(!feof(f));
103 fgets(linebuf, N_LINEBUF,f);
104 assert(linebuf[0] == '.');
sewardjabe017e2004-10-29 23:42:36 +0000105
sewardjced9fe52004-07-07 11:55:36 +0000106 /* second line is: . byte byte byte etc */
sewardj1f40a0a2004-07-21 12:28:07 +0000107 if (verbose)
sewardj4459baa2004-09-10 20:00:46 +0000108 printf("============ Basic Block %d, "
109 "Start %x, nbytes %2d ============",
sewardjabe017e2004-10-29 23:42:36 +0000110 n_bbs_done-1, orig_addr, orig_nbytes);
111
sewardjced9fe52004-07-07 11:55:36 +0000112 assert(orig_nbytes >= 1 && orig_nbytes <= N_ORIGBUF);
113 for (i = 0; i < orig_nbytes; i++) {
sewardjabe017e2004-10-29 23:42:36 +0000114 assert(1 == sscanf(&linebuf[2 + 3*i], "%x", &u));
115 origbuf[i] = (UChar)u;
sewardjced9fe52004-07-07 11:55:36 +0000116 }
117
sewardjabe017e2004-10-29 23:42:36 +0000118 for (i = 0; i < TEST_N_ITERS; i++)
119 tres
120 = LibVEX_Translate (
121 InsnSetX86, InsnSetX86,
122 origbuf, (Addr64)orig_addr, &orig_used,
123 transbuf, N_TRANSBUF, &trans_used,
sewardj9b1004e2004-10-30 22:25:40 +0000124 ac_instrument, //NULL, /* instrument1 */
sewardjabe017e2004-10-29 23:42:36 +0000125 NULL, /* instrument2 */
sewardjabe017e2004-10-29 23:42:36 +0000126 NULL, /* access checker */
127 TEST_FLAGS
128 );
129
sewardj4459baa2004-09-10 20:00:46 +0000130 if (tres != TransOK)
131 printf("\ntres = %d\n", (Int)tres);
sewardjced9fe52004-07-07 11:55:36 +0000132 assert(tres == TransOK);
133 assert(orig_used == orig_nbytes);
sewardjabe017e2004-10-29 23:42:36 +0000134
sewardj4459baa2004-09-10 20:00:46 +0000135 sum = 0;
136 for (i = 0; i < trans_used; i++)
137 sum += (UInt)transbuf[i];
138 printf ( " %6.2f ... %d\n", (double)trans_used / (double)orig_used, sum );
sewardjced9fe52004-07-07 11:55:36 +0000139 }
140
141 fclose(f);
sewardjf05537e2004-10-14 01:08:12 +0000142 printf("\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000143 LibVEX_ClearTemporary(True);
sewardjced9fe52004-07-07 11:55:36 +0000144
sewardjce605f92004-07-05 14:39:15 +0000145 return 0;
146}
sewardj9b1004e2004-10-30 22:25:40 +0000147
148//////////////////////////////////////////////////////////////////////
149
150static
151void panic ( Char* s )
152{
153 printf("\npanic: %s\n", s);
154 failure_exit();
155}
156
157static
sewardjeeac8412004-11-02 00:26:55 +0000158IRBB* ac_instrument (IRBB* bb_in, VexGuestLayout* layout)
sewardj9b1004e2004-10-30 22:25:40 +0000159{
160/* Use this rather than eg. -1 because it's a UInt. */
161#define INVALID_DATA_SIZE 999999
162
163 Int i;
164 Int sz;
165 IRCallee* helper;
166 IRStmt* st;
167 IRExpr* data;
168 IRExpr* addr;
169 Bool needSz;
170
171 /* Set up BB */
172 IRBB* bb = emptyIRBB();
173 bb->tyenv = dopyIRTypeEnv(bb_in->tyenv);
174 bb->next = dopyIRExpr(bb_in->next);
175 bb->jumpkind = bb_in->jumpkind;
176
177 /* No loads to consider in ->next. */
178 assert(isAtom(bb_in->next));
179
180 for (i = 0; i < bb_in->stmts_used; i++) {
181 st = bb_in->stmts[i];
182 if (!st) continue;
183
184 switch (st->tag) {
185
186 case Ist_Tmp:
187 data = st->Ist.Tmp.data;
188 if (data->tag == Iex_LDle) {
189 addr = data->Iex.LDle.addr;
190 sz = sizeofIRType(data->Iex.LDle.ty);
191 needSz = False;
192 switch (sz) {
193 case 4: helper = mkIRCallee(1, "ac_helperc_LOAD4",
sewardjf5435862004-10-31 20:04:05 +0000194 (void*)0x12345601); break;
sewardj9b1004e2004-10-30 22:25:40 +0000195 case 2: helper = mkIRCallee(0, "ac_helperc_LOAD2",
sewardjf5435862004-10-31 20:04:05 +0000196 (void*)0x12345602); break;
sewardj9b1004e2004-10-30 22:25:40 +0000197 case 1: helper = mkIRCallee(1, "ac_helperc_LOAD1",
sewardjf5435862004-10-31 20:04:05 +0000198 (void*)0x12345603); break;
sewardj9b1004e2004-10-30 22:25:40 +0000199 default: helper = mkIRCallee(0, "ac_helperc_LOADN",
sewardjf5435862004-10-31 20:04:05 +0000200 (void*)0x12345604);
sewardj9b1004e2004-10-30 22:25:40 +0000201 needSz = True; break;
202 }
203 if (needSz) {
204 addStmtToIRBB(
205 bb,
206 IRStmt_Dirty(
sewardjf5435862004-10-31 20:04:05 +0000207 unsafeIRDirty_0_N( helper->regparms,
208 helper->name, helper->addr,
sewardj9b1004e2004-10-30 22:25:40 +0000209 mkIRExprVec_2(addr, mkIRExpr_HWord(sz)))
210 ));
211 } else {
212 addStmtToIRBB(
213 bb,
214 IRStmt_Dirty(
sewardjf5435862004-10-31 20:04:05 +0000215 unsafeIRDirty_0_N( helper->regparms,
216 helper->name, helper->addr,
sewardj9b1004e2004-10-30 22:25:40 +0000217 mkIRExprVec_1(addr) )
218 ));
219 }
220 }
221 break;
222
223 case Ist_STle:
224 data = st->Ist.STle.data;
225 addr = st->Ist.STle.addr;
226 assert(isAtom(data));
227 assert(isAtom(addr));
228 sz = sizeofIRType(typeOfIRExpr(bb_in->tyenv, data));
229 needSz = False;
230 switch (sz) {
231 case 4: helper = mkIRCallee(1, "ac_helperc_STORE4",
sewardjf5435862004-10-31 20:04:05 +0000232 (void*)0x12345605); break;
sewardj9b1004e2004-10-30 22:25:40 +0000233 case 2: helper = mkIRCallee(0, "ac_helperc_STORE2",
sewardjf5435862004-10-31 20:04:05 +0000234 (void*)0x12345606); break;
sewardj9b1004e2004-10-30 22:25:40 +0000235 case 1: helper = mkIRCallee(1, "ac_helperc_STORE1",
sewardjf5435862004-10-31 20:04:05 +0000236 (void*)0x12345607); break;
sewardj9b1004e2004-10-30 22:25:40 +0000237 default: helper = mkIRCallee(0, "ac_helperc_STOREN",
sewardjf5435862004-10-31 20:04:05 +0000238 (void*)0x12345608);
sewardj9b1004e2004-10-30 22:25:40 +0000239 needSz = True; break;
240 }
241 if (needSz) {
242 addStmtToIRBB(
243 bb,
244 IRStmt_Dirty(
sewardjf5435862004-10-31 20:04:05 +0000245 unsafeIRDirty_0_N( helper->regparms,
246 helper->name, helper->addr,
sewardj9b1004e2004-10-30 22:25:40 +0000247 mkIRExprVec_2(addr, mkIRExpr_HWord(sz)))
248 ));
249 } else {
250 addStmtToIRBB(
251 bb,
252 IRStmt_Dirty(
sewardjf5435862004-10-31 20:04:05 +0000253 unsafeIRDirty_0_N( helper->regparms,
254 helper->name, helper->addr,
sewardj9b1004e2004-10-30 22:25:40 +0000255 mkIRExprVec_1(addr) )
256 ));
257 }
258 break;
259
260 case Ist_Put:
261 assert(isAtom(st->Ist.Put.data));
262 break;
263
264 case Ist_PutI:
sewardjeeac8412004-11-02 00:26:55 +0000265 assert(isAtom(st->Ist.PutI.ix));
sewardj9b1004e2004-10-30 22:25:40 +0000266 assert(isAtom(st->Ist.PutI.data));
267 break;
268
269 case Ist_Exit:
270 assert(isAtom(st->Ist.Exit.cond));
271 break;
272
273 case Ist_Dirty:
274 /* If the call doesn't interact with memory, we ain't
275 interested. */
276 if (st->Ist.Dirty.details->mFx == Ifx_None)
277 break;
278 goto unhandled;
279
280 default:
281 unhandled:
282 printf("\n");
283 ppIRStmt(st);
284 printf("\n");
285 panic("addrcheck: unhandled IRStmt");
286 }
287
288 addStmtToIRBB( bb, dopyIRStmt(st));
289 }
290
291 return bb;
292}