extern Bool VG_(what_fn_is_this) ( Bool no_demangle, Addr a,
Char* fn_name, Int n_fn_name);
-extern Bool VG_(symtab_notify_munmap) ( Addr start, UInt length );
+extern Bool VG_(is_munmap_exe) ( Addr start, UInt length );
+
+extern void VG_(symtab_notify_munmap) ( Addr start, UInt length );
/* ---------------------------------------------------------------------
Stabs reader greatly improved by Nick Nethercode, Apr 02.
- 16 May 02: when notified about munmap, return a Bool indicating
- whether or not the area being munmapped had executable permissions.
- This is then used to determine whether or not
- VG_(invalid_translations) should be called for that area. In order
- that this work even if --instrument=no, in this case we still keep
- track of the mapped executable segments, but do not load any debug
+ NJN 30 Aug 2002: when notified about munmap, use VG_(is_munmap_exe) to
+ return a Bool indicating whether or not the area being munmapped had
+ executable permissions. This is then used to determine whether or not
+ VG_(invalidate_translations) and VG_(symtab_notify_munmap) should be
+ called for that area.
+
+ Note that for Cachegrind to work, VG_(invalidate_translations) *must* be
+ called before VG_(symtab_notify_munmap), because Cachegrind uses the
+ symbols during the invalidation step.
+
+ In order that this work even if --instrument=no, in this case we still
+ keep track of the mapped executable segments, but do not load any debug
info or symbols.
*/
}
+/* Determine if the munmapped segment is executable, so we know if we have
+ to unload symbols and invalidate translations. */
+Bool VG_(is_munmap_exe) ( Addr start, UInt length )
+{
+ SegInfo *prev, *curr;
+
+ prev = NULL;
+ curr = segInfo;
+ while (True) {
+ if (curr == NULL) return False;
+ if (start == curr->start) break;
+ prev = curr;
+ curr = curr->next;
+ }
+
+ vg_assert(prev == NULL || prev->next == curr);
+ return True;
+}
+
+
/* When an munmap() call happens, check to see whether it corresponds
to a segment for a .so, and if so discard the relevant SegInfo.
This might not be a very clever idea from the point of view of
accuracy of error messages, but we need to do it in order to
maintain the no-overlapping invariant.
-
- 16 May 02: Returns a Bool indicating whether or not the discarded
- range falls inside a known executable segment. See comment at top
- of file for why.
*/
-Bool VG_(symtab_notify_munmap) ( Addr start, UInt length )
+void VG_(symtab_notify_munmap) ( Addr start, UInt length )
{
SegInfo *prev, *curr;
prev = NULL;
curr = segInfo;
while (True) {
- if (curr == NULL) break;
+ /* VG_(is_munmap_exe) does exactly the same search, and this function
+ * is only called if it succeeds, so this search should not fail */
+ vg_assert(curr != NULL);
+
if (start == curr->start) break;
prev = curr;
curr = curr->next;
}
- if (curr == NULL)
- return False;
VG_(message)(Vg_UserMsg,
"discard syms in %s due to munmap()",
} else {
prev->next = curr->next;
}
-
freeSegInfo(curr);
- return True;
}
while ((start % VKI_BYTES_PER_PAGE) > 0) { start--; length++; }
while (((start+length) % VKI_BYTES_PER_PAGE) > 0) { length++; }
make_noaccess( start, length );
- munmap_exe = VG_(symtab_notify_munmap) ( start, length );
- if (munmap_exe)
+ munmap_exe = VG_(is_munmap_exe) ( start, length );
+ if (munmap_exe) {
+ VG_(symtab_notify_munmap) ( start, length );
VG_(invalidate_translations) ( start, length );
+ }
approximate_mmap_permissions( (Addr)res, arg3, arg4 );
}
break;
/* Tell our symbol table machinery about this, so that if
this happens to be a .so being unloaded, the relevant
symbols are removed too. */
- munmap_exe = VG_(symtab_notify_munmap) ( start, length );
- if (munmap_exe)
+ munmap_exe = VG_(is_munmap_exe) ( start, length );
+ if (munmap_exe) {
VG_(invalidate_translations) ( start, length );
+ VG_(symtab_notify_munmap) ( start, length );
+ }
}
break;