- Mucho x86 to IR hacking.
- Build with Intel icc as it can warn about int-enum mismatches
git-svn-id: svn://svn.valgrind.org/vex/trunk@65 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/Makefile b/Makefile
index f841b13..0299a1e 100644
--- a/Makefile
+++ b/Makefile
@@ -27,8 +27,20 @@
APP_OBJS = test_main.o
-CC = gcc341
-CCFLAGS = -g -Wall -Wshadow
+#CC = gcc341
+#CCFLAGS = -g -Wall -Wshadow
+
+CC = icc
+CCFLAGS = -g -Wbrief -Wall -wd981 -wd279 -wd1287 -wd869 \
+ -wd810 -wd1419 -wd181 -wd111 -wd167
+# 981: operands are evaluated in unspecified order
+# 279: controlling expression is constant
+# 1287: invalid attribute for parameter
+# 869: parameter "..." was never referenced
+# 810: conversion from "int" to "Char={char}" may lose significant bits
+# 181: argument is incompatible with corresponding format string conversion
+# 111: statement is unreachable
+# 167: argument of type unsigned char incompatible with formal of type char
all: libvex.a $(APP_OBJS)
$(CC) $(CCFLAGS) -o vex $(APP_OBJS) libvex.a
diff --git a/priv/guest-x86/x86guest_defs.h b/priv/guest-x86/x86guest_defs.h
index 7e25045..0660860 100644
--- a/priv/guest-x86/x86guest_defs.h
+++ b/priv/guest-x86/x86guest_defs.h
@@ -20,7 +20,7 @@
/*---------------------------------------------------------*/
extern
-IRBB* bbToIR_X86Instr ( Char* x86code,
+IRBB* bbToIR_X86Instr ( UChar* x86code,
Addr64 eip,
Int* guest_bytes_read,
Bool (*byte_accessible)(Addr64),
diff --git a/priv/guest-x86/x86toIR.c b/priv/guest-x86/x86toIR.c
index e956eee..9ac4b84 100644
--- a/priv/guest-x86/x86toIR.c
+++ b/priv/guest-x86/x86toIR.c
@@ -177,29 +177,29 @@
}
/* Ditto, but write to a reg instead. */
-static IRStmt* putIReg ( Int sz, UInt archreg, IRExpr* e )
+static void putIReg ( Int sz, UInt archreg, IRExpr* e )
{
vassert(sz == 1 || sz == 2 || sz == 4);
vassert(archreg < 8);
vassert(!host_is_bigendian);
vassert(sz == 4);
- return IRStmt_Put(OFFB_EAX + 4*archreg, e);
+ stmt( IRStmt_Put(OFFB_EAX + 4*archreg, e) );
}
-static IRStmt* assign ( IRTemp dst, IRExpr* e )
+static void assign ( IRTemp dst, IRExpr* e )
{
- return IRStmt_Tmp(dst, e);
+ stmt( IRStmt_Tmp(dst, e) );
}
-static IRStmt* storeLE ( IRExpr* addr, IRExpr* data )
+static void storeLE ( IRExpr* addr, IRExpr* data )
{
- return IRStmt_STle(addr,data);
+ stmt( IRStmt_STle(addr,data) );
}
-static IRStmt* copyToFrom ( IRTemp dst, IRTemp src )
+static void copyToFrom ( IRTemp dst, IRTemp src )
{
- return IRStmt_Tmp(dst, IRExpr_Tmp(src));
+ stmt( IRStmt_Tmp(dst, IRExpr_Tmp(src)) );
}
static IRExpr* binop ( IROp op, IRExpr* a1, IRExpr* a2 )
@@ -217,6 +217,65 @@
return IRExpr_Const(IRConst_U32(i));
}
+static IRExpr* mkU ( IRType ty, UInt i )
+{
+ if (ty == Ity_I8) return IRExpr_Const(IRConst_U8(i));
+ if (ty == Ity_I16) return IRExpr_Const(IRConst_U16(i));
+ if (ty == Ity_I32) return IRExpr_Const(IRConst_U32(i));
+ vpanic("mkU(x86)");
+}
+
+static IRExpr* loadLE ( IRType ty, IRExpr* data )
+{
+ return IRExpr_LDle(ty,data);
+}
+
+static IROp mkSizedOp ( IRType ty, IROp op8 )
+{
+ vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);
+ vassert(op8 == Iop_Add8 || op8 == Iop_Sub8
+ || op8 == Iop_Adc8 || op8 == Iop_Sbb8
+ || op8 == Iop_Mul8
+ || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8
+ || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
+ || op8 == Iop_Not8 || op8 == Iop_Neg8 );
+ return (IROp)(
+ ((Int)op8) + (ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2))
+ );
+}
+
+static IRType szToTy ( Int n )
+{
+ switch (n) {
+ case 1: return Ity_I8;
+ case 2: return Ity_I16;
+ case 4: return Ity_I32;
+ default: vpanic("szToTy(x86)");
+ }
+}
+
+
+/*------------------------------------------------------------*/
+/*--- Helpers for %eflags. ---*/
+/*------------------------------------------------------------*/
+
+static void setFlagsARITH ( IRTemp dstAfter,
+ IRTemp src,
+ IRTemp dstBefore,
+ IRType ty,
+ IROp op8 )
+{
+ vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);
+ switch (op8) {
+ case Iop_Sub8:
+ /* CC_SRC = %s, CC_DST = %d afterwards */
+
+ default:
+ ppIROp(op8);
+ vpanic("setFlagsARITH(x86)");
+ }
+}
+
//-- /*------------------------------------------------------------*/
//-- /*--- CPU feature set stuff ---*/
@@ -480,15 +539,15 @@
//-- }
-//--
-//-- static Char* nameGrp1 ( Int opc_aux )
-//-- {
-//-- static Char* grp1_names[8]
-//-- = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" };
-//-- if (opc_aux < 0 || opc_aux > 7) VG_(core_panic)("nameGrp1");
-//-- return grp1_names[opc_aux];
-//-- }
-//--
+
+static Char* nameGrp1 ( Int opc_aux )
+{
+ static Char* grp1_names[8]
+ = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" };
+ if (opc_aux < 0 || opc_aux > 7) vpanic("nameGrp1(x86)");
+ return grp1_names[opc_aux];
+}
+
//-- static Char* nameGrp2 ( Int opc_aux )
//-- {
//-- static Char* grp2_names[8]
@@ -583,8 +642,7 @@
//-- }
//-- }
-static
-const Char nameISize ( Int size )
+static Char nameISize ( Int size )
{
switch (size) {
case 4: return 'l';
@@ -792,6 +850,7 @@
{ UChar rm = mod_reg_rm;
DIS(buf, "%s(%s)", sorbTxt(sorb), nameIReg(4,rm));
*len = 1;
+ vpanic("amode 1");
return handleSegOverride(sorb, getIReg(4,rm));
}
@@ -804,6 +863,7 @@
UInt d = getSDisp8(delta);
DIS(buf, "%s%d(%s)", sorbTxt(sorb), d, nameIReg(4,rm));
*len = 2;
+ vpanic("amode 2");
return handleSegOverride(sorb,
binop(Iop_Add32,getIReg(4,rm),mkU32(d)));
}
@@ -817,6 +877,7 @@
UInt d = getUDisp32(delta);
DIS(buf, "%s0x%x(%s)", sorbTxt(sorb), d, nameIReg(4,rm));
*len = 5;
+ vpanic("amode 3");
return handleSegOverride(sorb,
binop(Iop_Add32,getIReg(4,rm),mkU32(d)));
}
@@ -833,6 +894,7 @@
{ UInt d = getUDisp32(delta);
*len = 5;
DIS(buf, "%s(0x%x)", sorbTxt(sorb), d);
+ vpanic("amode 4");
return handleSegOverride(sorb, mkU32(d));
}
@@ -866,6 +928,7 @@
DIS(buf, "%s(%s,%s,%d)", sorbTxt(sorb),
nameIReg(4,base_r), nameIReg(4,index_r), 1<<scale);
*len = 2;
+ vpanic("amode 5");
return
handleSegOverride(sorb,
binop(Iop_Add32,
@@ -879,6 +942,7 @@
DIS(buf, "%s0x%x(,%s,%d)", sorbTxt(sorb), d,
nameIReg(4,index_r), 1<<scale);
*len = 6;
+ vpanic("amode 6");
return
handleSegOverride(sorb,
binop(Iop_Add32,
@@ -889,6 +953,7 @@
if (index_r == R_ESP && base_r != R_EBP) {
DIS(buf, "%s(%s,,)", sorbTxt(sorb), nameIReg(4,base_r));
*len = 2;
+ vpanic("amode 7");
return handleSegOverride(sorb, getIReg(4,base_r));
}
@@ -896,6 +961,7 @@
UInt d = getUDisp32(delta);
DIS(buf, "%s0x%x()", sorbTxt(sorb), d);
*len = 6;
+ vpanic("amode 8");
return handleSegOverride(sorb, mkU32(d));
}
@@ -921,12 +987,14 @@
if (index_r == R_ESP) {
DIS(buf, "%s%d(%s,,)", sorbTxt(sorb), d, nameIReg(4,base_r));
*len = 3;
+ vpanic("amode 9");
return handleSegOverride(sorb,
binop(Iop_Add32, getIReg(4,base_r), mkU32(d)) );
} else {
DIS(buf, "%s%d(%s,%s,%d)", sorbTxt(sorb), d,
nameIReg(4,base_r), nameIReg(4,index_r), 1<<scale);
*len = 3;
+ vpanic("amode 10");
return handleSegOverride(sorb,
binop(Iop_Add32,
binop(Iop_Add32,
@@ -956,12 +1024,14 @@
if (index_r == R_ESP) {
DIS(buf, "%s%d(%s,,)", sorbTxt(sorb), d, nameIReg(4,base_r));
*len = 6;
+ vpanic("amode 11");
return handleSegOverride(sorb,
binop(Iop_Add32, getIReg(4,base_r), mkU32(d)) );
} else {
DIS(buf, "%s%d(%s,%s,%d)", sorbTxt(sorb), d,
nameIReg(4,base_r), nameIReg(4,index_r), 1<<scale);
*len = 6;
+ vpanic("amode 12");
return handleSegOverride(sorb,
binop(Iop_Add32,
binop(Iop_Add32,
@@ -1326,7 +1396,7 @@
// UChar dis_buf[50];
if (epartIsReg(rm)) {
- stmt( putIReg(size, eregOfRM(rm), getIReg(size, gregOfRM(rm))) );
+ putIReg(size, eregOfRM(rm), getIReg(size, gregOfRM(rm)));
DIP("mov%c %s,%s\n", nameISize(size),
nameIReg(size,gregOfRM(rm)),
nameIReg(size,eregOfRM(rm)));
@@ -1470,79 +1540,71 @@
//-- }
//-- uInstr0(cb, CALLM_E, 0);
//-- }
-//--
-//--
-//-- static
-//-- Addr dis_Grp1 ( UCodeBlock* cb,
-//-- UChar sorb,
-//-- Addr eip, UChar modrm,
-//-- Int am_sz, Int d_sz, Int sz, UInt d32 )
-//-- {
-//-- Int t1, t2, uopc;
-//-- UInt pair;
-//-- UChar dis_buf[50];
-//-- if (epartIsReg(modrm)) {
-//-- vg_assert(am_sz == 1);
-//-- t1 = newTemp(cb);
-//-- uInstr2(cb, GET, sz, ArchReg, eregOfRM(modrm), TempReg, t1);
-//-- switch (gregOfRM(modrm)) {
-//-- case 0: uopc = ADD; break; case 1: uopc = OR; break;
-//-- case 2: uopc = ADC; break; case 3: uopc = SBB; break;
-//-- case 4: uopc = AND; break; case 5: uopc = SUB; break;
-//-- case 6: uopc = XOR; break; case 7: uopc = SUB; break;
-//-- default: VG_(core_panic)("dis_Grp1(Reg): unhandled case");
-//-- }
-//-- if (uopc == AND || uopc == OR) {
-//-- Int tao = newTemp(cb);
-//-- uInstr2(cb, MOV, sz, Literal, 0, TempReg, tao);
-//-- uLiteral(cb, d32);
-//-- uInstr2(cb, uopc, sz, TempReg, tao, TempReg, t1);
-//-- setFlagsFromUOpcode(cb, uopc);
-//-- } else {
-//-- uInstr2(cb, uopc, sz, Literal, 0, TempReg, t1);
-//-- uLiteral(cb, d32);
-//-- setFlagsFromUOpcode(cb, uopc);
-//-- }
-//-- if (gregOfRM(modrm) < 7)
-//-- uInstr2(cb, PUT, sz, TempReg, t1, ArchReg, eregOfRM(modrm));
-//-- eip += (am_sz + d_sz);
-//-- DIP("%s%c $0x%x, %s\n", nameGrp1(gregOfRM(modrm)), nameISize(sz), d32,
-//-- nameIReg(sz,eregOfRM(modrm)));
-//-- } else {
-//-- pair = disAMode ( cb, sorb, eip, dis_buf);
-//-- t1 = LOW24(pair);
-//-- t2 = newTemp(cb);
-//-- eip += HI8(pair);
-//-- eip += d_sz;
-//-- uInstr2(cb, LOAD, sz, TempReg, t1, TempReg, t2);
-//-- switch (gregOfRM(modrm)) {
-//-- case 0: uopc = ADD; break; case 1: uopc = OR; break;
-//-- case 2: uopc = ADC; break; case 3: uopc = SBB; break;
-//-- case 4: uopc = AND; break; case 5: uopc = SUB; break;
-//-- case 6: uopc = XOR; break; case 7: uopc = SUB; break;
-//-- default: VG_(core_panic)("dis_Grp1(Mem): unhandled case");
-//-- }
-//-- if (uopc == AND || uopc == OR) {
-//-- Int tao = newTemp(cb);
-//-- uInstr2(cb, MOV, sz, Literal, 0, TempReg, tao);
-//-- uLiteral(cb, d32);
-//-- uInstr2(cb, uopc, sz, TempReg, tao, TempReg, t2);
-//-- setFlagsFromUOpcode(cb, uopc);
-//-- } else {
-//-- uInstr2(cb, uopc, sz, Literal, 0, TempReg, t2);
-//-- uLiteral(cb, d32);
-//-- setFlagsFromUOpcode(cb, uopc);
-//-- }
-//-- if (gregOfRM(modrm) < 7) {
-//-- uInstr2(cb, STORE, sz, TempReg, t2, TempReg, t1);
-//-- }
-//-- DIP("%s%c $0x%x, %s\n", nameGrp1(gregOfRM(modrm)), nameISize(sz),
-//-- d32, dis_buf);
-//-- }
-//-- return eip;
-//-- }
-//--
-//--
+
+
+static
+UInt dis_Grp1 ( UChar sorb,
+ UInt delta, UChar modrm,
+ Int am_sz, Int d_sz, Int sz, UInt d32 )
+{
+ IRExpr* addr;
+ IRTemp dst1, src, dst0;
+ IRType ty;
+ IROp uopc;
+ Int len;
+ UChar dis_buf[50];
+
+ ty = szToTy(sz);
+
+ switch (gregOfRM(modrm)) {
+ case 0: uopc = Iop_Add8; break; case 1: uopc = Iop_Or8; break;
+ case 2: uopc = Iop_Adc8; break; case 3: uopc = Iop_Sbb8; break;
+ case 4: uopc = Iop_And8; break; case 5: uopc = Iop_Sub8; break;
+ case 6: uopc = Iop_Xor8; break; case 7: uopc = Iop_Sub8; break;
+ default: vpanic("dis_Grp1: unhandled case");
+ }
+ vassert(uopc != Iop_Adc8 && uopc != Iop_Sbb8);
+
+ dst0 = newTemp(ty);
+ dst1 = newTemp(ty);
+ src = newTemp(ty);
+
+ if (epartIsReg(modrm)) {
+ vassert(am_sz == 1);
+
+ assign(dst0, getIReg(sz,eregOfRM(modrm)));
+ assign(src, mkU(ty,d32));
+ assign(dst1, binop(mkSizedOp(ty,uopc), mkexpr(dst0), mkexpr(src)));
+
+ setFlagsARITH(dst1, dst0, src, ty, uopc);
+
+ if (gregOfRM(modrm) < 7)
+ putIReg(ty, eregOfRM(modrm), mkexpr(dst1));
+
+ delta += (am_sz + d_sz);
+ DIP("%s%c $0x%x, %s\n", nameGrp1(gregOfRM(modrm)), nameISize(sz), d32,
+ nameIReg(sz,eregOfRM(modrm)));
+ } else {
+ vassert(0==334);
+ addr = disAMode ( &len, sorb, delta, dis_buf);
+
+ assign(dst0, loadLE(ty,addr));
+ assign(src, mkU(ty,d32));
+ assign(dst1, binop(mkSizedOp(ty,uopc), mkexpr(dst0), mkexpr(src)));
+
+ setFlagsARITH(dst1, dst0, src, ty, uopc);
+
+ if (gregOfRM(modrm) < 7)
+ storeLE(addr, mkexpr(dst1));
+
+ delta += (len+d_sz);
+ DIP("%s%c $0x%x, %s\n", nameGrp1(gregOfRM(modrm)), nameISize(sz),
+ d32, dis_buf);
+ }
+ return delta;
+}
+
+
//-- /* Group 2 extended opcodes. */
//-- static
//-- Addr dis_Grp2 ( UCodeBlock* cb,
@@ -3924,7 +3986,7 @@
UInt d32 /*, pair*/;
// UChar dis_buf[50];
Int am_sz, d_sz;
- IRTemp t1, t2, t3, t4;
+ IRTemp t1, t2; //, t3, t4;
IRType ty;
//Char loc_buf[M_VG_ERRTXT];
@@ -3945,7 +4007,8 @@
IRStmt* first_stmt = last_stmt;
*isEnd = False;
- t1 = t2 = t3 = t4 = INVALID_IRTEMP;
+ t1 = t2 = INVALID_IRTEMP;
+ //t3 = t4 = INVALID_IRTEMP;
DIP("\t0x%x: ", guest_eip+delta);
@@ -5358,9 +5421,9 @@
{
/* The normal sequence for a call. */
t1 = newTemp(Ity_I32);
- stmt( assign(t1, binop(Iop_Sub32, getIReg(4,R_ESP), mkU32(4))) );
- stmt( putIReg(4, R_ESP, mkexpr(t1)) );
- stmt( storeLE( mkexpr(t1), mkU32(guest_eip+delta)) );
+ assign(t1, binop(Iop_Sub32, getIReg(4,R_ESP), mkU32(4)));
+ putIReg(4, R_ESP, mkexpr(t1));
+ storeLE( mkexpr(t1), mkU32(guest_eip+delta));
jmp_lit(d32);
// LAST_UINSTR(cb).jmpkind = JmpCall;
*isEnd = True;
@@ -6118,10 +6181,10 @@
vassert(sz == 2 || sz == 4);
ty = sz==2 ? Ity_I16 : Ity_I32;
t1 = newTemp(ty); t2 = newTemp(ty);
- stmt( assign(t1, getIReg(sz, opc-0x50)) );
- stmt( assign(t2, binop(Iop_Sub32, getIReg(4, R_ESP), mkU32(sz))) );
- stmt( putIReg(4, R_ESP, mkexpr(t2) ) );
- stmt( storeLE(mkexpr(t2),mkexpr(t1)) );
+ assign(t1, getIReg(sz, opc-0x50));
+ assign(t2, binop(Iop_Sub32, getIReg(4, R_ESP), mkU32(sz)));
+ putIReg(4, R_ESP, mkexpr(t2) );
+ storeLE(mkexpr(t2),mkexpr(t1));
DIP("push%c %s\n", nameISize(sz), nameIReg(sz,opc-0x50));
break;
@@ -7417,7 +7480,7 @@
/* Disassemble a complete basic block, starting at eip, and dumping
the ucode into cb. Returns the size, in bytes, of the basic
block. */
-IRBB* bbToIR_X86Instr ( Char* x86code,
+IRBB* bbToIR_X86Instr ( UChar* x86code,
Addr64 eip,
Int* guest_bytes_read,
Bool (*byte_accessible)(Addr64),
diff --git a/priv/ir/ir_defs.c b/priv/ir/ir_defs.c
index 35d9409..caa6a0d 100644
--- a/priv/ir/ir_defs.c
+++ b/priv/ir/ir_defs.c
@@ -44,26 +44,48 @@
if (tmp == INVALID_IRTEMP)
vex_printf("INVALID_IRTEMP");
else
- vex_printf( "t%d", tmp);
+ vex_printf( "t%d", (Int)tmp);
}
-
void ppIROp ( IROp op )
{
- switch (op) {
- case Iop_Add32: vex_printf( "Add32"); break;
- case Iop_Sub32: vex_printf( "Sub32"); break;
- case Iop_Mul32: vex_printf( "Mul32"); break;
- case Iop_Or32: vex_printf( "Or32"); break;
- case Iop_And32: vex_printf( "And32"); break;
- case Iop_Xor32: vex_printf( "Xor32"); break;
- case Iop_Shl32: vex_printf( "Shl32"); break;
- case Iop_Shr32: vex_printf( "Shr32"); break;
- case Iop_Sar32: vex_printf( "Sar32"); break;
- case Iop_Not32: vex_printf( "Not32"); break;
- case Iop_Neg32: vex_printf( "Neg32"); break;
- default: vpanic("ppIROp");
- }
+ Char* str;
+ IROp base;
+ switch (op) {
+ case Iop_Add8 ... Iop_Add64:
+ str = "Add"; base = Iop_Add8; break;
+ case Iop_Sub8 ... Iop_Sub64:
+ str = "Sub"; base = Iop_Sub8; break;
+ case Iop_Mul8 ... Iop_Mul64:
+ str = "Mul"; base = Iop_Mul8; break;
+ case Iop_Or8 ... Iop_Or64:
+ str = "Or"; base = Iop_Or8; break;
+ case Iop_And8 ... Iop_And64:
+ str = "And"; base = Iop_And8; break;
+ case Iop_Xor8 ... Iop_Xor64:
+ str = "Xor"; base = Iop_Xor8; break;
+ case Iop_Shl8 ... Iop_Shl64:
+ str = "Shl"; base = Iop_Shl8; break;
+ case Iop_Shr8 ... Iop_Shr64:
+ str = "Shr"; base = Iop_Shr8; break;
+ case Iop_Sar8 ... Iop_Sar64:
+ str = "Sar"; base = Iop_Sar8; break;
+ case Iop_Neg8 ... Iop_Neg64:
+ str = "Neg"; base = Iop_Neg8; break;
+ case Iop_Not8 ... Iop_Not64:
+ str = "Not"; base = Iop_Not8; break;
+ /* other cases must explicitly "return;" */
+ default:
+ vpanic("ppIROp(1)");
+ }
+
+ switch (op - base) {
+ case 0: vex_printf(str); vex_printf("8"); break;
+ case 1: vex_printf(str); vex_printf("16"); break;
+ case 2: vex_printf(str); vex_printf("32"); break;
+ case 3: vex_printf(str); vex_printf("64"); break;
+ default: vpanic("ppIROp(2)");
+ }
}
void ppIRExpr ( IRExpr* e )
diff --git a/priv/main/vex_globals.c b/priv/main/vex_globals.c
index 0eac1eb..8407177 100644
--- a/priv/main/vex_globals.c
+++ b/priv/main/vex_globals.c
@@ -9,6 +9,7 @@
#include "libvex_basictypes.h"
#include "vex_util.h"
+#include "vex_globals.h"
/* Global settings for the VEX library. These are the
diff --git a/priv/main/vex_main.c b/priv/main/vex_main.c
index 52b4537..f889684 100644
--- a/priv/main/vex_main.c
+++ b/priv/main/vex_main.c
@@ -88,7 +88,7 @@
void (*ppInstr) ( HInstr* );
void (*ppReg) ( HReg );
HInstrArray* (*iselBB) ( IRBB* );
- IRBB* (*bbToIR) ( Char*, Addr64, Int*, Bool(*)(Addr64), Bool );
+ IRBB* (*bbToIR) ( UChar*, Addr64, Int*, Bool(*)(Addr64), Bool );
Bool host_is_bigendian = False;
IRBB* irbb;
diff --git a/priv/main/vex_util.c b/priv/main/vex_util.c
index 1c91ab8..73d70a6 100644
--- a/priv/main/vex_util.c
+++ b/priv/main/vex_util.c
@@ -7,6 +7,8 @@
/*---------------------------------------------------------------*/
#include "libvex_basictypes.h"
+#include "libvex.h"
+
#include "vex_globals.h"
#include "vex_util.h"
@@ -67,7 +69,8 @@
storage_count_allocs_TOT += (ULong)storage_count_allocs;
if (verb) {
vex_printf("vex storage: total %lld (%lld), curr %d (%d)\n",
- storage_bytes_allocd_TOT, storage_count_allocs_TOT,
+ (Long)storage_bytes_allocd_TOT,
+ (Long)storage_count_allocs_TOT,
storage_bytes_allocd, storage_count_allocs );
}
storage_used = 0;
@@ -420,6 +423,36 @@
}
+/* A general replacement for sprintf(). */
+
+static Char *vg_sprintf_ptr;
+
+static void add_to_vg_sprintf_buf ( Char c )
+{
+ *vg_sprintf_ptr++ = c;
+}
+
+UInt vex_sprintf ( Char* buf, const Char *format, ... )
+{
+ Int ret;
+ va_list vargs;
+
+ vg_sprintf_ptr = buf;
+
+ va_start(vargs,format);
+
+ ret = vprintf_wrk ( add_to_vg_sprintf_buf, format, vargs );
+ add_to_vg_sprintf_buf(0);
+
+ va_end(vargs);
+
+ vassert(vex_strlen(buf) == ret);
+ return ret;
+}
+
+
+
+
/*---------------------------------------------------------------*/
/*--- end vex_util.c ---*/
/*---------------------------------------------------------------*/
diff --git a/priv/main/vex_util.h b/priv/main/vex_util.h
index bb36f5a..97ffe9c 100644
--- a/priv/main/vex_util.h
+++ b/priv/main/vex_util.h
@@ -37,8 +37,10 @@
/* Printing */
__attribute__ ((format (printf, 1, 2)))
-extern UInt vex_printf ( const char *format, ... );
+extern UInt vex_printf ( const Char *format, ... );
+__attribute__ ((format (printf, 2, 3)))
+extern UInt vex_sprintf ( Char* buf, const Char *format, ... );
#endif /* ndef __VEX_UTIL_H */
diff --git a/pub/libvex_ir.h b/pub/libvex_ir.h
index 3a6e604..9193675 100644
--- a/pub/libvex_ir.h
+++ b/pub/libvex_ir.h
@@ -63,18 +63,24 @@
/* ------------------ Binary and unary ops ------------------ */
typedef
- enum { Iop_Add32,
- Iop_Sub32,
- Iop_Mul32,
- Iop_Or32,
- Iop_And32,
- Iop_Xor32,
- Iop_Shl32,
- Iop_Shr32,
- Iop_Sar32,
- /* Tags for unary ops */
- Iop_Not32,
- Iop_Neg32
+ enum {
+ /* Do not change this ordering. The IR generators
+ rely on (eg) Iop_Add64 == IopAdd8 + 3. */
+ Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64,
+ Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64,
+ Iop_Adc8, Iop_Adc16, Iop_Adc32, Iop_Adc64,
+ Iop_Sbb8, Iop_Sbb16, Iop_Sbb32, Iop_Sbb64,
+ /* Signless mul. MullS/MullU is elsewhere. */
+ Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64,
+ Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64,
+ Iop_And8, Iop_And16, Iop_And32, Iop_And64,
+ Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64,
+ Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64,
+ Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64,
+ Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64,
+ /* Tags for unary ops */
+ Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64,
+ Iop_Neg8, Iop_Neg16, Iop_Neg32, Iop_Neg64
}
IROp;
diff --git a/test_main.c b/test_main.c
index 568333d..c3d0daa 100644
--- a/test_main.c
+++ b/test_main.c
@@ -19,25 +19,27 @@
__attribute__ ((noreturn))
+static
void failure_exit ( void )
{
fprintf(stdout, "VEX did failure_exit. Bye.\n");
exit(1);
}
+static
void log_bytes ( Char* bytes, Int nbytes )
{
fwrite ( bytes, 1, nbytes, stdout );
}
#define N_LINEBUF 10000
-Char linebuf[N_LINEBUF];
+static Char linebuf[N_LINEBUF];
#define N_ORIGBUF 200
#define N_TRANSBUF 1000
-UChar origbuf[N_ORIGBUF];
-UChar transbuf[N_TRANSBUF];
+static Char origbuf[N_ORIGBUF];
+static Char transbuf[N_TRANSBUF];
int main ( int argc, char** argv )