#ifdef VG_PROFILE_MEMORY
-#define N_PROF_EVENTS 120
+#define N_PROF_EVENTS 150
static UInt event_ctr[N_PROF_EVENTS];
101 handle_esp_assignment
102 handle_esp_assignment(-4)
103 handle_esp_assignment(+4)
- 104 handle_esp_assignment(+16)
- 105 handle_esp_assignment(-12)
- 106 handle_esp_assignment(+8)
- 107 handle_esp_assignment(-8)
-
- 110 vg_handle_esp_assignment_SLOWLY
- 111 vg_handle_esp_assignment_SLOWLY(normal; move down)
- 112 vg_handle_esp_assignment_SLOWLY(normal; move up)
- 113 vg_handle_esp_assignment_SLOWLY(normal)
- 114 vg_handle_esp_assignment_SLOWLY(>= HUGE_DELTA)
+ 104 handle_esp_assignment(-12)
+ 105 handle_esp_assignment(-8)
+ 106 handle_esp_assignment(+16)
+ 107 handle_esp_assignment(+12)
+ 108 handle_esp_assignment(0)
+ 109 handle_esp_assignment(+8)
+ 110 handle_esp_assignment(-16)
+ 111 handle_esp_assignment(+20)
+ 112 handle_esp_assignment(-20)
+ 113 handle_esp_assignment(+24)
+ 114 handle_esp_assignment(-24)
+
+ 120 vg_handle_esp_assignment_SLOWLY
+ 121 vg_handle_esp_assignment_SLOWLY(normal; move down)
+ 122 vg_handle_esp_assignment_SLOWLY(normal; move up)
+ 123 vg_handle_esp_assignment_SLOWLY(normal)
+ 124 vg_handle_esp_assignment_SLOWLY(>= HUGE_DELTA)
*/
/*------------------------------------------------------------*/
Under all other circumstances, it defers to the relevant _SLOWLY
function, which can handle all situations.
*/
-
UInt VG_(helperc_LOADV4) ( Addr a )
{
# ifdef VG_DEBUG_MEMORY
return;
}
- if (delta == 16) {
- /* Also surprisingly common. */
+ if (delta == -12) {
PROF_EVENT(104);
+ make_aligned_word_WRITABLE(new_esp);
+ make_aligned_word_WRITABLE(new_esp+4);
+ make_aligned_word_WRITABLE(new_esp+8);
+ return;
+ }
+
+ if (delta == -8) {
+ PROF_EVENT(105);
+ make_aligned_word_WRITABLE(new_esp);
+ make_aligned_word_WRITABLE(new_esp+4);
+ return;
+ }
+
+ if (delta == 16) {
+ PROF_EVENT(106);
make_aligned_word_NOACCESS(old_esp);
make_aligned_word_NOACCESS(old_esp+4);
make_aligned_word_NOACCESS(old_esp+8);
return;
}
- if (delta == -12) {
- PROF_EVENT(105);
+ if (delta == 12) {
+ PROF_EVENT(107);
+ make_aligned_word_NOACCESS(old_esp);
+ make_aligned_word_NOACCESS(old_esp+4);
+ make_aligned_word_NOACCESS(old_esp+8);
+ return;
+ }
+
+ if (delta == 0) {
+ PROF_EVENT(108);
+ return;
+ }
+
+ if (delta == 8) {
+ PROF_EVENT(109);
+ make_aligned_word_NOACCESS(old_esp);
+ make_aligned_word_NOACCESS(old_esp+4);
+ return;
+ }
+
+ if (delta == -16) {
+ PROF_EVENT(110);
make_aligned_word_WRITABLE(new_esp);
make_aligned_word_WRITABLE(new_esp+4);
make_aligned_word_WRITABLE(new_esp+8);
+ make_aligned_word_WRITABLE(new_esp+12);
return;
}
- if (delta == 8) {
- PROF_EVENT(106);
+ if (delta == 20) {
+ PROF_EVENT(111);
make_aligned_word_NOACCESS(old_esp);
make_aligned_word_NOACCESS(old_esp+4);
+ make_aligned_word_NOACCESS(old_esp+8);
+ make_aligned_word_NOACCESS(old_esp+12);
+ make_aligned_word_NOACCESS(old_esp+16);
return;
}
- if (delta == -8) {
- PROF_EVENT(107);
+ if (delta == -20) {
+ PROF_EVENT(112);
make_aligned_word_WRITABLE(new_esp);
make_aligned_word_WRITABLE(new_esp+4);
+ make_aligned_word_WRITABLE(new_esp+8);
+ make_aligned_word_WRITABLE(new_esp+12);
+ make_aligned_word_WRITABLE(new_esp+16);
return;
}
+
+ if (delta == 24) {
+ PROF_EVENT(113);
+ make_aligned_word_NOACCESS(old_esp);
+ make_aligned_word_NOACCESS(old_esp+4);
+ make_aligned_word_NOACCESS(old_esp+8);
+ make_aligned_word_NOACCESS(old_esp+12);
+ make_aligned_word_NOACCESS(old_esp+16);
+ make_aligned_word_NOACCESS(old_esp+20);
+ return;
+ }
+
+ if (delta == -24) {
+ PROF_EVENT(114);
+ make_aligned_word_WRITABLE(new_esp);
+ make_aligned_word_WRITABLE(new_esp+4);
+ make_aligned_word_WRITABLE(new_esp+8);
+ make_aligned_word_WRITABLE(new_esp+12);
+ make_aligned_word_WRITABLE(new_esp+16);
+ make_aligned_word_WRITABLE(new_esp+20);
+ return;
+ }
+
}
# endif
UInt old_esp = VG_(baseBlock)[VGOFF_(m_esp)];
UInt new_esp = (UInt)new_espA;
Int delta = ((Int)new_esp) - ((Int)old_esp);
-
- PROF_EVENT(110);
+ // VG_(printf)("%d ", delta);
+ PROF_EVENT(120);
if (-(VG_HUGE_DELTA) < delta && delta < VG_HUGE_DELTA) {
/* "Ordinary" stack change. */
if (new_esp < old_esp) {
/* Moving down; the stack is growing. */
- PROF_EVENT(111);
+ PROF_EVENT(121);
VGM_(make_writable) ( new_esp, old_esp - new_esp );
return;
}
if (new_esp > old_esp) {
/* Moving up; the stack is shrinking. */
- PROF_EVENT(112);
+ PROF_EVENT(122);
VGM_(make_noaccess) ( old_esp, new_esp - old_esp );
return;
}
- PROF_EVENT(113);
+ PROF_EVENT(123);
return; /* when old_esp == new_esp */
}
Addr valid_up_to = get_page_base(new_esp) + VKI_BYTES_PER_PAGE
+ 0 * VKI_BYTES_PER_PAGE;
ThreadState* tst = VG_(get_current_thread_state)();
- PROF_EVENT(114);
+ PROF_EVENT(124);
if (VG_(clo_verbosity) > 1)
VG_(message)(Vg_UserMsg, "Warning: client switching stacks? "
"%%esp: %p --> %p",
case 0x59: /* POP eCX */
case 0x5A: /* POP eDX */
case 0x5B: /* POP eBX */
- case 0x5C: /* POP eSP */
case 0x5D: /* POP eBP */
case 0x5E: /* POP eSI */
case 0x5F: /* POP eDI */
+ { Int n_pops;
+ Addr eipS, eipE;
+ UChar ch;
+ if (sz != 4) goto normal_pop_case;
+ /* eip points at first pop insn + 1. Make eipS and eipE
+ bracket the sequence. */
+ eipE = eipS = eip - 1;
+ while (True) {
+ ch = getUChar(eipE+1);
+ if (ch < 0x58 || ch > 0x5F || ch == 0x5C) break;
+ eipE++;
+ }
+ n_pops = eipE - eipS + 1;
+ if (0 && n_pops > 1) VG_(printf)("%d pops\n", n_pops);
+ t1 = newTemp(cb); t3 = newTemp(cb);
+ uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t1);
+ for (; eipS <= eipE; eipS++) {
+ ch = getUChar(eipS);
+ uInstr2(cb, LOAD, 4, TempReg, t1, TempReg, t3);
+ uInstr2(cb, PUT, 4, TempReg, t3, ArchReg, ch-0x58);
+ uInstr2(cb, ADD, 4, Literal, 0, TempReg, t1);
+ uLiteral(cb, 4);
+ SMC_IF_ALL(cb);
+ if (dis)
+ VG_(printf)("popl %s\n", nameIReg(4,ch-0x58));
+ }
+ uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_ESP);
+ eip = eipE + 1;
+ break;
+ }
+
+ case 0x5C: /* POP eSP */
+ normal_pop_case:
t1 = newTemp(cb); t2 = newTemp(cb);
uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t2);
uInstr2(cb, LOAD, sz, TempReg, t2, TempReg, t1);
case 0x50: /* PUSH eAX */
case 0x51: /* PUSH eCX */
case 0x52: /* PUSH eDX */
- case 0x54: /* PUSH eSP */
case 0x53: /* PUSH eBX */
case 0x55: /* PUSH eBP */
case 0x56: /* PUSH eSI */
case 0x57: /* PUSH eDI */
+ { Int n_pushes;
+ Addr eipS, eipE;
+ UChar ch;
+ if (sz != 4) goto normal_push_case;
+ /* eip points at first push insn + 1. Make eipS and eipE
+ bracket the sequence. */
+ eipE = eipS = eip - 1;
+ while (True) {
+ ch = getUChar(eipE+1);
+ if (ch < 0x50 || ch > 0x57 || ch == 0x54) break;
+ eipE++;
+ }
+ n_pushes = eipE - eipS + 1;
+ if (0 && n_pushes > 1) VG_(printf)("%d pushes\n", n_pushes);
+ t1 = newTemp(cb); t2 = newTemp(cb); t3 = newTemp(cb);
+ uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t1);
+ uInstr2(cb, MOV, 4, TempReg, t1, TempReg, t2);
+ uInstr2(cb, SUB, 4, Literal, 0, TempReg, t2);
+ uLiteral(cb, 4 * n_pushes);
+ uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP);
+ for (; eipS <= eipE; eipS++) {
+ ch = getUChar(eipS);
+ uInstr2(cb, SUB, 4, Literal, 0, TempReg, t1);
+ uLiteral(cb, 4);
+ uInstr2(cb, GET, 4, ArchReg, ch-0x50, TempReg, t3);
+ uInstr2(cb, STORE, 4, TempReg, t3, TempReg, t1);
+ SMC_IF_ALL(cb);
+ if (dis)
+ VG_(printf)("pushl %s\n", nameIReg(4,ch-0x50));
+ }
+ eip = eipE + 1;
+ break;
+ }
+
+ case 0x54: /* PUSH eSP */
+ normal_push_case:
/* This is the Right Way, in that the value to be pushed is
established before %esp is changed, so that pushl %esp
correctly pushes the old value. */
#ifdef VG_PROFILE_MEMORY
-#define N_PROF_EVENTS 120
+#define N_PROF_EVENTS 150
static UInt event_ctr[N_PROF_EVENTS];
101 handle_esp_assignment
102 handle_esp_assignment(-4)
103 handle_esp_assignment(+4)
- 104 handle_esp_assignment(+16)
- 105 handle_esp_assignment(-12)
- 106 handle_esp_assignment(+8)
- 107 handle_esp_assignment(-8)
-
- 110 vg_handle_esp_assignment_SLOWLY
- 111 vg_handle_esp_assignment_SLOWLY(normal; move down)
- 112 vg_handle_esp_assignment_SLOWLY(normal; move up)
- 113 vg_handle_esp_assignment_SLOWLY(normal)
- 114 vg_handle_esp_assignment_SLOWLY(>= HUGE_DELTA)
+ 104 handle_esp_assignment(-12)
+ 105 handle_esp_assignment(-8)
+ 106 handle_esp_assignment(+16)
+ 107 handle_esp_assignment(+12)
+ 108 handle_esp_assignment(0)
+ 109 handle_esp_assignment(+8)
+ 110 handle_esp_assignment(-16)
+ 111 handle_esp_assignment(+20)
+ 112 handle_esp_assignment(-20)
+ 113 handle_esp_assignment(+24)
+ 114 handle_esp_assignment(-24)
+
+ 120 vg_handle_esp_assignment_SLOWLY
+ 121 vg_handle_esp_assignment_SLOWLY(normal; move down)
+ 122 vg_handle_esp_assignment_SLOWLY(normal; move up)
+ 123 vg_handle_esp_assignment_SLOWLY(normal)
+ 124 vg_handle_esp_assignment_SLOWLY(>= HUGE_DELTA)
*/
/*------------------------------------------------------------*/
Under all other circumstances, it defers to the relevant _SLOWLY
function, which can handle all situations.
*/
-
UInt VG_(helperc_LOADV4) ( Addr a )
{
# ifdef VG_DEBUG_MEMORY
return;
}
- if (delta == 16) {
- /* Also surprisingly common. */
+ if (delta == -12) {
PROF_EVENT(104);
+ make_aligned_word_WRITABLE(new_esp);
+ make_aligned_word_WRITABLE(new_esp+4);
+ make_aligned_word_WRITABLE(new_esp+8);
+ return;
+ }
+
+ if (delta == -8) {
+ PROF_EVENT(105);
+ make_aligned_word_WRITABLE(new_esp);
+ make_aligned_word_WRITABLE(new_esp+4);
+ return;
+ }
+
+ if (delta == 16) {
+ PROF_EVENT(106);
make_aligned_word_NOACCESS(old_esp);
make_aligned_word_NOACCESS(old_esp+4);
make_aligned_word_NOACCESS(old_esp+8);
return;
}
- if (delta == -12) {
- PROF_EVENT(105);
+ if (delta == 12) {
+ PROF_EVENT(107);
+ make_aligned_word_NOACCESS(old_esp);
+ make_aligned_word_NOACCESS(old_esp+4);
+ make_aligned_word_NOACCESS(old_esp+8);
+ return;
+ }
+
+ if (delta == 0) {
+ PROF_EVENT(108);
+ return;
+ }
+
+ if (delta == 8) {
+ PROF_EVENT(109);
+ make_aligned_word_NOACCESS(old_esp);
+ make_aligned_word_NOACCESS(old_esp+4);
+ return;
+ }
+
+ if (delta == -16) {
+ PROF_EVENT(110);
make_aligned_word_WRITABLE(new_esp);
make_aligned_word_WRITABLE(new_esp+4);
make_aligned_word_WRITABLE(new_esp+8);
+ make_aligned_word_WRITABLE(new_esp+12);
return;
}
- if (delta == 8) {
- PROF_EVENT(106);
+ if (delta == 20) {
+ PROF_EVENT(111);
make_aligned_word_NOACCESS(old_esp);
make_aligned_word_NOACCESS(old_esp+4);
+ make_aligned_word_NOACCESS(old_esp+8);
+ make_aligned_word_NOACCESS(old_esp+12);
+ make_aligned_word_NOACCESS(old_esp+16);
return;
}
- if (delta == -8) {
- PROF_EVENT(107);
+ if (delta == -20) {
+ PROF_EVENT(112);
make_aligned_word_WRITABLE(new_esp);
make_aligned_word_WRITABLE(new_esp+4);
+ make_aligned_word_WRITABLE(new_esp+8);
+ make_aligned_word_WRITABLE(new_esp+12);
+ make_aligned_word_WRITABLE(new_esp+16);
return;
}
+
+ if (delta == 24) {
+ PROF_EVENT(113);
+ make_aligned_word_NOACCESS(old_esp);
+ make_aligned_word_NOACCESS(old_esp+4);
+ make_aligned_word_NOACCESS(old_esp+8);
+ make_aligned_word_NOACCESS(old_esp+12);
+ make_aligned_word_NOACCESS(old_esp+16);
+ make_aligned_word_NOACCESS(old_esp+20);
+ return;
+ }
+
+ if (delta == -24) {
+ PROF_EVENT(114);
+ make_aligned_word_WRITABLE(new_esp);
+ make_aligned_word_WRITABLE(new_esp+4);
+ make_aligned_word_WRITABLE(new_esp+8);
+ make_aligned_word_WRITABLE(new_esp+12);
+ make_aligned_word_WRITABLE(new_esp+16);
+ make_aligned_word_WRITABLE(new_esp+20);
+ return;
+ }
+
}
# endif
UInt old_esp = VG_(baseBlock)[VGOFF_(m_esp)];
UInt new_esp = (UInt)new_espA;
Int delta = ((Int)new_esp) - ((Int)old_esp);
-
- PROF_EVENT(110);
+ // VG_(printf)("%d ", delta);
+ PROF_EVENT(120);
if (-(VG_HUGE_DELTA) < delta && delta < VG_HUGE_DELTA) {
/* "Ordinary" stack change. */
if (new_esp < old_esp) {
/* Moving down; the stack is growing. */
- PROF_EVENT(111);
+ PROF_EVENT(121);
VGM_(make_writable) ( new_esp, old_esp - new_esp );
return;
}
if (new_esp > old_esp) {
/* Moving up; the stack is shrinking. */
- PROF_EVENT(112);
+ PROF_EVENT(122);
VGM_(make_noaccess) ( old_esp, new_esp - old_esp );
return;
}
- PROF_EVENT(113);
+ PROF_EVENT(123);
return; /* when old_esp == new_esp */
}
Addr valid_up_to = get_page_base(new_esp) + VKI_BYTES_PER_PAGE
+ 0 * VKI_BYTES_PER_PAGE;
ThreadState* tst = VG_(get_current_thread_state)();
- PROF_EVENT(114);
+ PROF_EVENT(124);
if (VG_(clo_verbosity) > 1)
VG_(message)(Vg_UserMsg, "Warning: client switching stacks? "
"%%esp: %p --> %p",
case 0x59: /* POP eCX */
case 0x5A: /* POP eDX */
case 0x5B: /* POP eBX */
- case 0x5C: /* POP eSP */
case 0x5D: /* POP eBP */
case 0x5E: /* POP eSI */
case 0x5F: /* POP eDI */
+ { Int n_pops;
+ Addr eipS, eipE;
+ UChar ch;
+ if (sz != 4) goto normal_pop_case;
+ /* eip points at first pop insn + 1. Make eipS and eipE
+ bracket the sequence. */
+ eipE = eipS = eip - 1;
+ while (True) {
+ ch = getUChar(eipE+1);
+ if (ch < 0x58 || ch > 0x5F || ch == 0x5C) break;
+ eipE++;
+ }
+ n_pops = eipE - eipS + 1;
+ if (0 && n_pops > 1) VG_(printf)("%d pops\n", n_pops);
+ t1 = newTemp(cb); t3 = newTemp(cb);
+ uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t1);
+ for (; eipS <= eipE; eipS++) {
+ ch = getUChar(eipS);
+ uInstr2(cb, LOAD, 4, TempReg, t1, TempReg, t3);
+ uInstr2(cb, PUT, 4, TempReg, t3, ArchReg, ch-0x58);
+ uInstr2(cb, ADD, 4, Literal, 0, TempReg, t1);
+ uLiteral(cb, 4);
+ SMC_IF_ALL(cb);
+ if (dis)
+ VG_(printf)("popl %s\n", nameIReg(4,ch-0x58));
+ }
+ uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_ESP);
+ eip = eipE + 1;
+ break;
+ }
+
+ case 0x5C: /* POP eSP */
+ normal_pop_case:
t1 = newTemp(cb); t2 = newTemp(cb);
uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t2);
uInstr2(cb, LOAD, sz, TempReg, t2, TempReg, t1);
case 0x50: /* PUSH eAX */
case 0x51: /* PUSH eCX */
case 0x52: /* PUSH eDX */
- case 0x54: /* PUSH eSP */
case 0x53: /* PUSH eBX */
case 0x55: /* PUSH eBP */
case 0x56: /* PUSH eSI */
case 0x57: /* PUSH eDI */
+ { Int n_pushes;
+ Addr eipS, eipE;
+ UChar ch;
+ if (sz != 4) goto normal_push_case;
+ /* eip points at first push insn + 1. Make eipS and eipE
+ bracket the sequence. */
+ eipE = eipS = eip - 1;
+ while (True) {
+ ch = getUChar(eipE+1);
+ if (ch < 0x50 || ch > 0x57 || ch == 0x54) break;
+ eipE++;
+ }
+ n_pushes = eipE - eipS + 1;
+ if (0 && n_pushes > 1) VG_(printf)("%d pushes\n", n_pushes);
+ t1 = newTemp(cb); t2 = newTemp(cb); t3 = newTemp(cb);
+ uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t1);
+ uInstr2(cb, MOV, 4, TempReg, t1, TempReg, t2);
+ uInstr2(cb, SUB, 4, Literal, 0, TempReg, t2);
+ uLiteral(cb, 4 * n_pushes);
+ uInstr2(cb, PUT, 4, TempReg, t2, ArchReg, R_ESP);
+ for (; eipS <= eipE; eipS++) {
+ ch = getUChar(eipS);
+ uInstr2(cb, SUB, 4, Literal, 0, TempReg, t1);
+ uLiteral(cb, 4);
+ uInstr2(cb, GET, 4, ArchReg, ch-0x50, TempReg, t3);
+ uInstr2(cb, STORE, 4, TempReg, t3, TempReg, t1);
+ SMC_IF_ALL(cb);
+ if (dis)
+ VG_(printf)("pushl %s\n", nameIReg(4,ch-0x50));
+ }
+ eip = eipE + 1;
+ break;
+ }
+
+ case 0x54: /* PUSH eSP */
+ normal_push_case:
/* This is the Right Way, in that the value to be pushed is
established before %esp is changed, so that pushl %esp
correctly pushes the old value. */