vg_symtab2.c:
Discovered sometimes a SLINE stabs entry is the last one (which broke an
assertion). In such a case, we must guess the line's instruction address
range -- I've guessed 4, arbitrarily.
vg_cachegen.in, vg_cachesim_{I1,D1,L2}.c:
Discovered a bad bug in the cache simulation: when determining if a
references straddles two memory blocks, to find the end of the range I was
adding 'size' to the base address, rather than 'size - 1'. This was
causing way too many straddled references, which would inflate the miss
counts.
vg_cachesim.c:
Minor stuff
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@176 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c
index 4db78ce..43e100c 100644
--- a/cachegrind/cg_main.c
+++ b/cachegrind/cg_main.c
@@ -136,7 +136,7 @@
static __inline__ void sprint_iCC(Char buf[BUF_LEN], UInt ln, iCC* cc)
{
VG_(sprintf)(buf, "%u %llu %llu %llu\n",
- ln, cc->I.a, cc->I.m1, cc->I.m2/*, cc->instr_addr*/);
+ ln, cc->I.a, cc->I.m1, cc->I.m2);
}
static __inline__ void sprint_read_or_mod_CC(Char buf[BUF_LEN], UInt ln,
@@ -144,14 +144,14 @@
{
VG_(sprintf)(buf, "%u %llu %llu %llu %llu %llu %llu\n",
ln, cc->I.a, cc->I.m1, cc->I.m2,
- cc->D.a, cc->D.m1, cc->D.m2/*, cc->instr_addr*/);
+ cc->D.a, cc->D.m1, cc->D.m2);
}
static __inline__ void sprint_write_CC(Char buf[BUF_LEN], UInt ln, idCC* cc)
{
VG_(sprintf)(buf, "%u %llu %llu %llu . . . %llu %llu %llu\n",
ln, cc->I.a, cc->I.m1, cc->I.m2,
- cc->D.a, cc->D.m1, cc->D.m2/*, cc->instr_addr*/);
+ cc->D.a, cc->D.m1, cc->D.m2);
}
/*------------------------------------------------------------*/
@@ -399,6 +399,7 @@
case LOAD:
/* Two LDBs are possible for a single instruction */
+ /* Also, a STORE can come after a LOAD for bts/btr/btc */
vg_assert(/*!is_LOAD &&*/ /* !is_STORE && */
!is_FPU_R && !is_FPU_W);
is_LOAD = True;
diff --git a/cachegrind/cg_sim_D1.c b/cachegrind/cg_sim_D1.c
index c2b3d4c..4a5b0bb 100644
--- a/cachegrind/cg_sim_D1.c
+++ b/cachegrind/cg_sim_D1.c
@@ -22,8 +22,8 @@
static __inline__
void cachesim_D1_doref(Addr a, UChar size, ULong* m1, ULong *m2)
{
- register UInt set1 = ( a >> 6) & (512-1);
- register UInt set2 = ((a + size) >> 6) & (512-1);
+ register UInt set1 = ( a >> 6) & (512-1);
+ register UInt set2 = ((a + size - 1) >> 6) & (512-1);
register UInt tag = a >> (6 + 9);
if (set1 == set2) {
diff --git a/cachegrind/cg_sim_I1.c b/cachegrind/cg_sim_I1.c
index 32b89b5..96e9edd 100644
--- a/cachegrind/cg_sim_I1.c
+++ b/cachegrind/cg_sim_I1.c
@@ -22,8 +22,8 @@
static __inline__
void cachesim_I1_doref(Addr a, UChar size, ULong* m1, ULong *m2)
{
- register UInt set1 = ( a >> 6) & (512-1);
- register UInt set2 = ((a + size) >> 6) & (512-1);
+ register UInt set1 = ( a >> 6) & (512-1);
+ register UInt set2 = ((a + size - 1) >> 6) & (512-1);
register UInt tag = a >> (6 + 9);
if (set1 == set2) {
diff --git a/cachegrind/cg_sim_L2.c b/cachegrind/cg_sim_L2.c
index bb68532..89a614c 100644
--- a/cachegrind/cg_sim_L2.c
+++ b/cachegrind/cg_sim_L2.c
@@ -22,8 +22,8 @@
static __inline__
void cachesim_L2_doref(Addr a, UChar size, ULong *m2)
{
- register UInt set1 = ( a >> 6) & (512-1);
- register UInt set2 = ((a + size) >> 6) & (512-1);
+ register UInt set1 = ( a >> 6) & (512-1);
+ register UInt set2 = ((a + size - 1) >> 6) & (512-1);
register UInt tag = a >> (6 + 9);
if (set1 == set2) {
diff --git a/coregrind/vg_symtab2.c b/coregrind/vg_symtab2.c
index d9da8ff..0136ba3 100644
--- a/coregrind/vg_symtab2.c
+++ b/coregrind/vg_symtab2.c
@@ -34,6 +34,7 @@
#include <elf.h> /* ELF defns */
#include <a.out.h> /* stabs defns */
+
/* Majorly rewritten Sun 3 Feb 02 to enable loading symbols from
dlopen()ed libraries, which is something that KDE3 does a lot.
Still kludgey, though less than before:
@@ -929,45 +930,50 @@
Int this_addr = (UInt)stab[i].n_value;
LOOP:
- vg_assert(i+1 < n_stab_entries); /* Haven't reached end */
- switch (stab[i+1].n_type) {
- /* Easy, common case: use address of next entry */
- case N_SLINE: case N_SO:
- next_addr = (UInt)stab[i+1].n_value;
- break;
-
- /* Boring one: skip, look for something more useful. */
- case N_RSYM: case N_LSYM: case N_LBRAC: case N_RBRAC:
- case N_STSYM: case N_LCSYM:
- i++;
- goto LOOP;
-
- /* Should be an end of fun entry, use its address */
- case N_FUN:
- if ('\0' == * (stabstr + stab[i+1].n_un.n_strx) ) {
+ if (i+1 >= n_stab_entries) {
+ /* If it's the last entry, just guess the range is four; can't
+ * do any better */
+ next_addr = 4;
+ } else {
+ switch (stab[i+1].n_type) {
+ /* Easy, common case: use address of next entry */
+ case N_SLINE: case N_SO:
next_addr = (UInt)stab[i+1].n_value;
- } else {
- VG_(printf)("unhandled stabs case: N_FUN start %d %s\n",
- i, (stabstr + stab[i+1].n_un.n_strx) );
- VG_(panic)("argh");
- }
- break;
-
- /* N_SOL should be followed by an N_SLINE which can be used */
- case N_SOL:
- if (i+2 < n_stab_entries && N_SLINE == stab[i+2].n_type) {
- next_addr = (UInt)stab[i+2].n_value;
break;
- } else {
- VG_(printf)("unhandled N_SOL stabs case: %d %d %d",
- stab[i+1].n_type, i, n_stab_entries);
- VG_(panic)("argh");
- }
- default:
- VG_(printf)("unhandled stabs case: %d %d",
- stab[i+1].n_type,i);
- VG_(panic)("argh");
+ /* Boring one: skip, look for something more useful. */
+ case N_RSYM: case N_LSYM: case N_LBRAC: case N_RBRAC:
+ case N_STSYM: case N_LCSYM:
+ i++;
+ goto LOOP;
+
+ /* Should be an end of fun entry, use its address */
+ case N_FUN:
+ if ('\0' == * (stabstr + stab[i+1].n_un.n_strx) ) {
+ next_addr = (UInt)stab[i+1].n_value;
+ } else {
+ VG_(printf)("unhandled stabs case: N_FUN start %d %s\n",
+ i, (stabstr + stab[i+1].n_un.n_strx) );
+ VG_(panic)("argh");
+ }
+ break;
+
+ /* N_SOL should be followed by an N_SLINE which can be used */
+ case N_SOL:
+ if (i+2 < n_stab_entries && N_SLINE == stab[i+2].n_type) {
+ next_addr = (UInt)stab[i+2].n_value;
+ break;
+ } else {
+ VG_(printf)("unhandled N_SOL stabs case: %d %d %d",
+ stab[i+1].n_type, i, n_stab_entries);
+ VG_(panic)("argh");
+ }
+
+ default:
+ VG_(printf)("unhandled stabs case: %d %d",
+ stab[i+1].n_type,i);
+ VG_(panic)("argh");
+ }
}
//Int offset2 = (i+1 < n_stab_entries && 68 == stab[i+1].n_type
diff --git a/vg_cachegen.in b/vg_cachegen.in
index e887f1b..e37dc3b 100755
--- a/vg_cachegen.in
+++ b/vg_cachegen.in
@@ -229,8 +229,8 @@
static __inline__
void cachesim_${L}_doref($L_args)
{
- register UInt set1 = ( a >> $n_line_bits) & ($n_sets-1);
- register UInt set2 = ((a + size) >> $n_line_bits) & ($n_sets-1);
+ register UInt set1 = ( a >> $n_line_bits) & ($n_sets-1);
+ register UInt set2 = ((a + size - 1) >> $n_line_bits) & ($n_sets-1);
register UInt tag = a >> ($n_line_bits + $n_set_bits);
if (set1 == set2) {
diff --git a/vg_cachesim.c b/vg_cachesim.c
index 4db78ce..43e100c 100644
--- a/vg_cachesim.c
+++ b/vg_cachesim.c
@@ -136,7 +136,7 @@
static __inline__ void sprint_iCC(Char buf[BUF_LEN], UInt ln, iCC* cc)
{
VG_(sprintf)(buf, "%u %llu %llu %llu\n",
- ln, cc->I.a, cc->I.m1, cc->I.m2/*, cc->instr_addr*/);
+ ln, cc->I.a, cc->I.m1, cc->I.m2);
}
static __inline__ void sprint_read_or_mod_CC(Char buf[BUF_LEN], UInt ln,
@@ -144,14 +144,14 @@
{
VG_(sprintf)(buf, "%u %llu %llu %llu %llu %llu %llu\n",
ln, cc->I.a, cc->I.m1, cc->I.m2,
- cc->D.a, cc->D.m1, cc->D.m2/*, cc->instr_addr*/);
+ cc->D.a, cc->D.m1, cc->D.m2);
}
static __inline__ void sprint_write_CC(Char buf[BUF_LEN], UInt ln, idCC* cc)
{
VG_(sprintf)(buf, "%u %llu %llu %llu . . . %llu %llu %llu\n",
ln, cc->I.a, cc->I.m1, cc->I.m2,
- cc->D.a, cc->D.m1, cc->D.m2/*, cc->instr_addr*/);
+ cc->D.a, cc->D.m1, cc->D.m2);
}
/*------------------------------------------------------------*/
@@ -399,6 +399,7 @@
case LOAD:
/* Two LDBs are possible for a single instruction */
+ /* Also, a STORE can come after a LOAD for bts/btr/btc */
vg_assert(/*!is_LOAD &&*/ /* !is_STORE && */
!is_FPU_R && !is_FPU_W);
is_LOAD = True;
diff --git a/vg_cachesim_D1.c b/vg_cachesim_D1.c
index c2b3d4c..4a5b0bb 100644
--- a/vg_cachesim_D1.c
+++ b/vg_cachesim_D1.c
@@ -22,8 +22,8 @@
static __inline__
void cachesim_D1_doref(Addr a, UChar size, ULong* m1, ULong *m2)
{
- register UInt set1 = ( a >> 6) & (512-1);
- register UInt set2 = ((a + size) >> 6) & (512-1);
+ register UInt set1 = ( a >> 6) & (512-1);
+ register UInt set2 = ((a + size - 1) >> 6) & (512-1);
register UInt tag = a >> (6 + 9);
if (set1 == set2) {
diff --git a/vg_cachesim_I1.c b/vg_cachesim_I1.c
index 32b89b5..96e9edd 100644
--- a/vg_cachesim_I1.c
+++ b/vg_cachesim_I1.c
@@ -22,8 +22,8 @@
static __inline__
void cachesim_I1_doref(Addr a, UChar size, ULong* m1, ULong *m2)
{
- register UInt set1 = ( a >> 6) & (512-1);
- register UInt set2 = ((a + size) >> 6) & (512-1);
+ register UInt set1 = ( a >> 6) & (512-1);
+ register UInt set2 = ((a + size - 1) >> 6) & (512-1);
register UInt tag = a >> (6 + 9);
if (set1 == set2) {
diff --git a/vg_cachesim_L2.c b/vg_cachesim_L2.c
index bb68532..89a614c 100644
--- a/vg_cachesim_L2.c
+++ b/vg_cachesim_L2.c
@@ -22,8 +22,8 @@
static __inline__
void cachesim_L2_doref(Addr a, UChar size, ULong *m2)
{
- register UInt set1 = ( a >> 6) & (512-1);
- register UInt set2 = ((a + size) >> 6) & (512-1);
+ register UInt set1 = ( a >> 6) & (512-1);
+ register UInt set2 = ((a + size - 1) >> 6) & (512-1);
register UInt tag = a >> (6 + 9);
if (set1 == set2) {
diff --git a/vg_symtab2.c b/vg_symtab2.c
index d9da8ff..0136ba3 100644
--- a/vg_symtab2.c
+++ b/vg_symtab2.c
@@ -34,6 +34,7 @@
#include <elf.h> /* ELF defns */
#include <a.out.h> /* stabs defns */
+
/* Majorly rewritten Sun 3 Feb 02 to enable loading symbols from
dlopen()ed libraries, which is something that KDE3 does a lot.
Still kludgey, though less than before:
@@ -929,45 +930,50 @@
Int this_addr = (UInt)stab[i].n_value;
LOOP:
- vg_assert(i+1 < n_stab_entries); /* Haven't reached end */
- switch (stab[i+1].n_type) {
- /* Easy, common case: use address of next entry */
- case N_SLINE: case N_SO:
- next_addr = (UInt)stab[i+1].n_value;
- break;
-
- /* Boring one: skip, look for something more useful. */
- case N_RSYM: case N_LSYM: case N_LBRAC: case N_RBRAC:
- case N_STSYM: case N_LCSYM:
- i++;
- goto LOOP;
-
- /* Should be an end of fun entry, use its address */
- case N_FUN:
- if ('\0' == * (stabstr + stab[i+1].n_un.n_strx) ) {
+ if (i+1 >= n_stab_entries) {
+ /* If it's the last entry, just guess the range is four; can't
+ * do any better */
+ next_addr = 4;
+ } else {
+ switch (stab[i+1].n_type) {
+ /* Easy, common case: use address of next entry */
+ case N_SLINE: case N_SO:
next_addr = (UInt)stab[i+1].n_value;
- } else {
- VG_(printf)("unhandled stabs case: N_FUN start %d %s\n",
- i, (stabstr + stab[i+1].n_un.n_strx) );
- VG_(panic)("argh");
- }
- break;
-
- /* N_SOL should be followed by an N_SLINE which can be used */
- case N_SOL:
- if (i+2 < n_stab_entries && N_SLINE == stab[i+2].n_type) {
- next_addr = (UInt)stab[i+2].n_value;
break;
- } else {
- VG_(printf)("unhandled N_SOL stabs case: %d %d %d",
- stab[i+1].n_type, i, n_stab_entries);
- VG_(panic)("argh");
- }
- default:
- VG_(printf)("unhandled stabs case: %d %d",
- stab[i+1].n_type,i);
- VG_(panic)("argh");
+ /* Boring one: skip, look for something more useful. */
+ case N_RSYM: case N_LSYM: case N_LBRAC: case N_RBRAC:
+ case N_STSYM: case N_LCSYM:
+ i++;
+ goto LOOP;
+
+ /* Should be an end of fun entry, use its address */
+ case N_FUN:
+ if ('\0' == * (stabstr + stab[i+1].n_un.n_strx) ) {
+ next_addr = (UInt)stab[i+1].n_value;
+ } else {
+ VG_(printf)("unhandled stabs case: N_FUN start %d %s\n",
+ i, (stabstr + stab[i+1].n_un.n_strx) );
+ VG_(panic)("argh");
+ }
+ break;
+
+ /* N_SOL should be followed by an N_SLINE which can be used */
+ case N_SOL:
+ if (i+2 < n_stab_entries && N_SLINE == stab[i+2].n_type) {
+ next_addr = (UInt)stab[i+2].n_value;
+ break;
+ } else {
+ VG_(printf)("unhandled N_SOL stabs case: %d %d %d",
+ stab[i+1].n_type, i, n_stab_entries);
+ VG_(panic)("argh");
+ }
+
+ default:
+ VG_(printf)("unhandled stabs case: %d %d",
+ stab[i+1].n_type,i);
+ VG_(panic)("argh");
+ }
}
//Int offset2 = (i+1 < n_stab_entries && 68 == stab[i+1].n_type