From 1818ed0e51ac06a30ac3d4918256032671b7bb8f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 30 Apr 2002 13:44:01 +0000 Subject: [PATCH] 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 --- cachegrind/cg_main.c | 7 ++-- cachegrind/cg_sim_D1.c | 4 +-- cachegrind/cg_sim_I1.c | 4 +-- cachegrind/cg_sim_L2.c | 4 +-- coregrind/vg_symtab2.c | 76 +++++++++++++++++++++++------------------- vg_cachegen.in | 4 +-- vg_cachesim.c | 7 ++-- vg_cachesim_D1.c | 4 +-- vg_cachesim_I1.c | 4 +-- vg_cachesim_L2.c | 4 +-- vg_symtab2.c | 76 +++++++++++++++++++++++------------------- 11 files changed, 104 insertions(+), 90 deletions(-) diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c index 4db78ce7e6..43e100cb94 100644 --- a/cachegrind/cg_main.c +++ b/cachegrind/cg_main.c @@ -136,7 +136,7 @@ static void init_idCC(CC_type X_CC, idCC* cc, Addr instr_addr, 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 @@ static __inline__ void sprint_read_or_mod_CC(Char buf[BUF_LEN], UInt ln, { 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 @@ static Int compute_BBCC_array_size(UCodeBlock* cb) 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 c2b3d4cc3e..4a5b0bbee2 100644 --- a/cachegrind/cg_sim_D1.c +++ b/cachegrind/cg_sim_D1.c @@ -22,8 +22,8 @@ static void cachesim_D1_initcache(void) 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 32b89b51b0..96e9edd23e 100644 --- a/cachegrind/cg_sim_I1.c +++ b/cachegrind/cg_sim_I1.c @@ -22,8 +22,8 @@ static void cachesim_I1_initcache(void) 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 bb685326ab..89a614c86e 100644 --- a/cachegrind/cg_sim_L2.c +++ b/cachegrind/cg_sim_L2.c @@ -22,8 +22,8 @@ static void cachesim_L2_initcache(void) 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 d9da8fff45..0136ba3bf7 100644 --- a/coregrind/vg_symtab2.c +++ b/coregrind/vg_symtab2.c @@ -34,6 +34,7 @@ #include /* ELF defns */ #include /* 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 @@ void vg_read_lib_symbols ( SegInfo* si ) 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; + 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; + /* 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; - } 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"); + /* 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 e887f1bab3..e37dc3bfb5 100755 --- a/vg_cachegen.in +++ b/vg_cachegen.in @@ -229,8 +229,8 @@ static void cachesim_${L}_initcache(void) 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 4db78ce7e6..43e100cb94 100644 --- a/vg_cachesim.c +++ b/vg_cachesim.c @@ -136,7 +136,7 @@ static void init_idCC(CC_type X_CC, idCC* cc, Addr instr_addr, 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 @@ static __inline__ void sprint_read_or_mod_CC(Char buf[BUF_LEN], UInt ln, { 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 @@ static Int compute_BBCC_array_size(UCodeBlock* cb) 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 c2b3d4cc3e..4a5b0bbee2 100644 --- a/vg_cachesim_D1.c +++ b/vg_cachesim_D1.c @@ -22,8 +22,8 @@ static void cachesim_D1_initcache(void) 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 32b89b51b0..96e9edd23e 100644 --- a/vg_cachesim_I1.c +++ b/vg_cachesim_I1.c @@ -22,8 +22,8 @@ static void cachesim_I1_initcache(void) 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 bb685326ab..89a614c86e 100644 --- a/vg_cachesim_L2.c +++ b/vg_cachesim_L2.c @@ -22,8 +22,8 @@ static void cachesim_L2_initcache(void) 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 d9da8fff45..0136ba3bf7 100644 --- a/vg_symtab2.c +++ b/vg_symtab2.c @@ -34,6 +34,7 @@ #include /* ELF defns */ #include /* 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 @@ void vg_read_lib_symbols ( SegInfo* si ) 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; + 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; + /* 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; - } 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"); + /* 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 -- 2.47.3