blob: 5c2d3005905576c741fd06574967629b6d1941ea [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 */
sewardj9578a8b2004-11-04 19:44:48 +000051static IRBB* ac_instrument ( IRBB*, VexGuestLayout*, IRType );
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 */
sewardj9578a8b2004-11-04 19:44:48 +0000126 False, /* cleanup after instrument */
sewardjabe017e2004-10-29 23:42:36 +0000127 NULL, /* access checker */
128 TEST_FLAGS
129 );
130
sewardj4459baa2004-09-10 20:00:46 +0000131 if (tres != TransOK)
132 printf("\ntres = %d\n", (Int)tres);
sewardjced9fe52004-07-07 11:55:36 +0000133 assert(tres == TransOK);
134 assert(orig_used == orig_nbytes);
sewardjabe017e2004-10-29 23:42:36 +0000135
sewardj4459baa2004-09-10 20:00:46 +0000136 sum = 0;
137 for (i = 0; i < trans_used; i++)
138 sum += (UInt)transbuf[i];
139 printf ( " %6.2f ... %d\n", (double)trans_used / (double)orig_used, sum );
sewardjced9fe52004-07-07 11:55:36 +0000140 }
141
142 fclose(f);
sewardjf05537e2004-10-14 01:08:12 +0000143 printf("\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000144 LibVEX_ClearTemporary(True);
sewardjced9fe52004-07-07 11:55:36 +0000145
sewardjce605f92004-07-05 14:39:15 +0000146 return 0;
147}
sewardj9b1004e2004-10-30 22:25:40 +0000148
149//////////////////////////////////////////////////////////////////////
150
151static
152void panic ( Char* s )
153{
154 printf("\npanic: %s\n", s);
155 failure_exit();
156}
157
158static
sewardj9578a8b2004-11-04 19:44:48 +0000159IRBB* ac_instrument (IRBB* bb_in, VexGuestLayout* layout, IRType hWordTy )
sewardj9b1004e2004-10-30 22:25:40 +0000160{
161/* Use this rather than eg. -1 because it's a UInt. */
162#define INVALID_DATA_SIZE 999999
163
164 Int i;
165 Int sz;
166 IRCallee* helper;
167 IRStmt* st;
168 IRExpr* data;
169 IRExpr* addr;
170 Bool needSz;
171
172 /* Set up BB */
173 IRBB* bb = emptyIRBB();
174 bb->tyenv = dopyIRTypeEnv(bb_in->tyenv);
175 bb->next = dopyIRExpr(bb_in->next);
176 bb->jumpkind = bb_in->jumpkind;
177
178 /* No loads to consider in ->next. */
179 assert(isAtom(bb_in->next));
180
181 for (i = 0; i < bb_in->stmts_used; i++) {
182 st = bb_in->stmts[i];
183 if (!st) continue;
184
185 switch (st->tag) {
186
187 case Ist_Tmp:
188 data = st->Ist.Tmp.data;
189 if (data->tag == Iex_LDle) {
190 addr = data->Iex.LDle.addr;
191 sz = sizeofIRType(data->Iex.LDle.ty);
192 needSz = False;
193 switch (sz) {
194 case 4: helper = mkIRCallee(1, "ac_helperc_LOAD4",
sewardjf5435862004-10-31 20:04:05 +0000195 (void*)0x12345601); break;
sewardj9b1004e2004-10-30 22:25:40 +0000196 case 2: helper = mkIRCallee(0, "ac_helperc_LOAD2",
sewardjf5435862004-10-31 20:04:05 +0000197 (void*)0x12345602); break;
sewardj9b1004e2004-10-30 22:25:40 +0000198 case 1: helper = mkIRCallee(1, "ac_helperc_LOAD1",
sewardjf5435862004-10-31 20:04:05 +0000199 (void*)0x12345603); break;
sewardj9b1004e2004-10-30 22:25:40 +0000200 default: helper = mkIRCallee(0, "ac_helperc_LOADN",
sewardjf5435862004-10-31 20:04:05 +0000201 (void*)0x12345604);
sewardj9b1004e2004-10-30 22:25:40 +0000202 needSz = True; break;
203 }
204 if (needSz) {
205 addStmtToIRBB(
206 bb,
207 IRStmt_Dirty(
sewardjf5435862004-10-31 20:04:05 +0000208 unsafeIRDirty_0_N( helper->regparms,
209 helper->name, helper->addr,
sewardj9b1004e2004-10-30 22:25:40 +0000210 mkIRExprVec_2(addr, mkIRExpr_HWord(sz)))
211 ));
212 } else {
213 addStmtToIRBB(
214 bb,
215 IRStmt_Dirty(
sewardjf5435862004-10-31 20:04:05 +0000216 unsafeIRDirty_0_N( helper->regparms,
217 helper->name, helper->addr,
sewardj9b1004e2004-10-30 22:25:40 +0000218 mkIRExprVec_1(addr) )
219 ));
220 }
221 }
222 break;
223
224 case Ist_STle:
225 data = st->Ist.STle.data;
226 addr = st->Ist.STle.addr;
227 assert(isAtom(data));
228 assert(isAtom(addr));
229 sz = sizeofIRType(typeOfIRExpr(bb_in->tyenv, data));
230 needSz = False;
231 switch (sz) {
232 case 4: helper = mkIRCallee(1, "ac_helperc_STORE4",
sewardjf5435862004-10-31 20:04:05 +0000233 (void*)0x12345605); break;
sewardj9b1004e2004-10-30 22:25:40 +0000234 case 2: helper = mkIRCallee(0, "ac_helperc_STORE2",
sewardjf5435862004-10-31 20:04:05 +0000235 (void*)0x12345606); break;
sewardj9b1004e2004-10-30 22:25:40 +0000236 case 1: helper = mkIRCallee(1, "ac_helperc_STORE1",
sewardjf5435862004-10-31 20:04:05 +0000237 (void*)0x12345607); break;
sewardj9b1004e2004-10-30 22:25:40 +0000238 default: helper = mkIRCallee(0, "ac_helperc_STOREN",
sewardjf5435862004-10-31 20:04:05 +0000239 (void*)0x12345608);
sewardj9b1004e2004-10-30 22:25:40 +0000240 needSz = True; break;
241 }
242 if (needSz) {
243 addStmtToIRBB(
244 bb,
245 IRStmt_Dirty(
sewardjf5435862004-10-31 20:04:05 +0000246 unsafeIRDirty_0_N( helper->regparms,
247 helper->name, helper->addr,
sewardj9b1004e2004-10-30 22:25:40 +0000248 mkIRExprVec_2(addr, mkIRExpr_HWord(sz)))
249 ));
250 } else {
251 addStmtToIRBB(
252 bb,
253 IRStmt_Dirty(
sewardjf5435862004-10-31 20:04:05 +0000254 unsafeIRDirty_0_N( helper->regparms,
255 helper->name, helper->addr,
sewardj9b1004e2004-10-30 22:25:40 +0000256 mkIRExprVec_1(addr) )
257 ));
258 }
259 break;
260
261 case Ist_Put:
262 assert(isAtom(st->Ist.Put.data));
263 break;
264
265 case Ist_PutI:
sewardjeeac8412004-11-02 00:26:55 +0000266 assert(isAtom(st->Ist.PutI.ix));
sewardj9b1004e2004-10-30 22:25:40 +0000267 assert(isAtom(st->Ist.PutI.data));
268 break;
269
270 case Ist_Exit:
271 assert(isAtom(st->Ist.Exit.cond));
272 break;
273
274 case Ist_Dirty:
275 /* If the call doesn't interact with memory, we ain't
276 interested. */
277 if (st->Ist.Dirty.details->mFx == Ifx_None)
278 break;
279 goto unhandled;
280
281 default:
282 unhandled:
283 printf("\n");
284 ppIRStmt(st);
285 printf("\n");
286 panic("addrcheck: unhandled IRStmt");
287 }
288
289 addStmtToIRBB( bb, dopyIRStmt(st));
290 }
291
292 return bb;
293}