mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-04 02:18:37 +00:00
Incorporate horrible hack to workaround problem of emitting bogus
uninit-value errors on code with inlined strlen() et al from gcc-3.1 and above. MERGE TO STABLE git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1213
This commit is contained in:
parent
e5494a7f05
commit
9ea62d1526
@ -583,6 +583,20 @@ follows:
|
||||
in g++-3.0.4.
|
||||
</li><br><p>
|
||||
|
||||
<li><code>--avoid-strlen-errors=yes</code> [default]<br>
|
||||
<code>--avoid-strlen-errors=no</code> <p>When enabled, valgrind
|
||||
inspects each basic block it instruments for some tell-tale
|
||||
literals (0xFEFEFEFF, 0x80808080, 0x00008080) which suggest
|
||||
that this block is part of an inlined strlen() function. In
|
||||
many cases such functions cause spurious uninitialised-value
|
||||
errors to be reported -- their code is too clever for the
|
||||
instrumentation scheme. This horrible hack works around the
|
||||
problem, at the expense of hiding any genuine
|
||||
uninitialised-value errors which might appear ine such blocks.
|
||||
It is enabled by default because it is needed to get sensible
|
||||
behaviour on code compiled by gcc-3.1 and above.
|
||||
</li><br><p>
|
||||
|
||||
<li><code>--error-limit=yes</code> [default]<br>
|
||||
<code>--error-limit=no</code> <p>When enabled, valgrind stops
|
||||
reporting errors after 30000 in total, or 300 different ones,
|
||||
|
||||
@ -145,6 +145,10 @@ extern Bool SK_(clo_check_addrVs);
|
||||
/* DEBUG: clean up instrumented code? default: YES */
|
||||
extern Bool SK_(clo_cleanup);
|
||||
|
||||
/* When instrumenting, omit some checks if tell-tale literals for
|
||||
inlined strlen() are visible in the basic block. default: YES */
|
||||
extern Bool SK_(clo_avoid_strlen_errors);
|
||||
|
||||
|
||||
/*------------------------------------------------------------*/
|
||||
/*--- Functions ---*/
|
||||
|
||||
@ -57,6 +57,8 @@ Bool SK_(clo_show_reachable) = False;
|
||||
Bool SK_(clo_workaround_gcc296_bugs) = False;
|
||||
Bool SK_(clo_check_addrVs) = True;
|
||||
Bool SK_(clo_cleanup) = True;
|
||||
Bool SK_(clo_avoid_strlen_errors) = True;
|
||||
|
||||
|
||||
/*------------------------------------------------------------*/
|
||||
/*--- Profiling events ---*/
|
||||
@ -2318,6 +2320,11 @@ Bool SK_(process_cmd_line_option)(Char* arg)
|
||||
else if (STREQ(arg, "--cleanup=no"))
|
||||
SK_(clo_cleanup) = False;
|
||||
|
||||
else if (STREQ(arg, "--avoid-strlen-errors=yes"))
|
||||
SK_(clo_avoid_strlen_errors) = True;
|
||||
else if (STREQ(arg, "--avoid-strlen-errors=no"))
|
||||
SK_(clo_avoid_strlen_errors) = False;
|
||||
|
||||
else
|
||||
return False;
|
||||
|
||||
@ -2340,7 +2347,8 @@ Char* SK_(usage)(void)
|
||||
" --check-addrVs=no|yes experimental lighterweight checking? [yes]\n"
|
||||
" yes == Valgrind's original behaviour\n"
|
||||
"\n"
|
||||
" --cleanup=no|yes improve after instrumentation? [yes]\n";
|
||||
" --cleanup=no|yes improve after instrumentation? [yes]\n"
|
||||
" --avoid-strlen-errors=no|yes suppress errs from inlined strlen [yes]\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -498,9 +498,43 @@ static UCodeBlock* memcheck_instrument ( UCodeBlock* cb_in )
|
||||
Int i, j;
|
||||
UInstr* u_in;
|
||||
Int qs, qd, qt, qtt;
|
||||
Bool bogusLiterals;
|
||||
cb = VG_(alloc_UCodeBlock)();
|
||||
cb->nextTemp = cb_in->nextTemp;
|
||||
|
||||
/* Scan the block to look for bogus literals. These are magic
|
||||
numbers which particularly appear in hand-optimised / inlined
|
||||
implementations of strlen() et al which cause so much trouble
|
||||
(spurious reports of uninit-var uses). Purpose of this horrible
|
||||
hack is to disable some checks any such literals are present in
|
||||
this basic block. */
|
||||
bogusLiterals = False;
|
||||
|
||||
if (SK_(clo_avoid_strlen_errors)) {
|
||||
for (i = 0; i < cb_in->used; i++) {
|
||||
u_in = &cb_in->instrs[i];
|
||||
switch (u_in->opcode) {
|
||||
case ADD: case SUB: case MOV:
|
||||
if (u_in->size == 4 && u_in->tag1 == Literal)
|
||||
goto literal;
|
||||
break;
|
||||
case LEA1:
|
||||
sk_assert(u_in->size == 4);
|
||||
goto literal;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
literal:
|
||||
if (u_in->lit32 == 0xFEFEFEFF ||
|
||||
u_in->lit32 == 0x80808080 ||
|
||||
u_in->lit32 == 0x00008080) {
|
||||
bogusLiterals = True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < cb_in->used; i++) {
|
||||
qs = qd = qt = qtt = INVALID_TEMPREG;
|
||||
u_in = &cb_in->instrs[i];
|
||||
@ -1003,7 +1037,12 @@ static UCodeBlock* memcheck_instrument ( UCodeBlock* cb_in )
|
||||
if (u_in->cond != CondAlways) {
|
||||
sk_assert(u_in->flags_r != FlagsEmpty);
|
||||
qt = create_GETVF(cb, 0);
|
||||
uInstr1(cb, TESTV, 0, TempReg, qt);
|
||||
if (/* HACK */ bogusLiterals) {
|
||||
if (0)
|
||||
VG_(printf)("ignore TESTV due to bogus literal\n");
|
||||
} else {
|
||||
uInstr1(cb, TESTV, 0, TempReg, qt);
|
||||
}
|
||||
/* qt should never be referred to again. Nevertheless
|
||||
... */
|
||||
uInstr1(cb, SETV, 0, TempReg, qt);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user